diff --git a/CHANGELOG.md b/CHANGELOG.md index 6054a3330..a06c84031 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Fixed + +- Incorrect case-sensitive treatment of file names in coverage reports. + ## [1.12.1] - 2024-12-06 ### Fixed diff --git a/delphi-frontend/src/main/java/au/com/integradev/delphi/coverage/DelphiCodeCoverageParser.java b/delphi-frontend/src/main/java/au/com/integradev/delphi/coverage/DelphiCodeCoverageParser.java index 2c0731961..811fb875d 100644 --- a/delphi-frontend/src/main/java/au/com/integradev/delphi/coverage/DelphiCodeCoverageParser.java +++ b/delphi-frontend/src/main/java/au/com/integradev/delphi/coverage/DelphiCodeCoverageParser.java @@ -24,7 +24,11 @@ import au.com.integradev.delphi.msbuild.DelphiProjectHelper; import com.google.common.base.Splitter; +import com.google.common.base.Suppliers; +import com.google.common.collect.ImmutableSortedMap; import java.io.File; +import java.util.Map; +import java.util.function.Supplier; import javax.xml.XMLConstants; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; @@ -42,9 +46,19 @@ public class DelphiCodeCoverageParser implements DelphiCoverageParser { private static final Logger LOG = LoggerFactory.getLogger(DelphiCodeCoverageParser.class); private final DelphiProjectHelper delphiProjectHelper; + private final Supplier> fileNameToInputFile; public DelphiCodeCoverageParser(DelphiProjectHelper delphiProjectHelper) { this.delphiProjectHelper = delphiProjectHelper; + this.fileNameToInputFile = Suppliers.memoize(this::indexInputFiles); + } + + private Map indexInputFiles() { + var builder = ImmutableSortedMap.orderedBy(String.CASE_INSENSITIVE_ORDER); + for (InputFile inputFile : delphiProjectHelper.inputFiles()) { + builder.put(inputFile.filename(), inputFile); + } + return builder.build(); } @Override @@ -89,12 +103,12 @@ private void parseReportFile(SensorContext sensorContext, File reportFile) { private void parseFileNode(SensorContext sensorContext, Node srcFile) { String fileName = srcFile.getAttributes().getNamedItem("name").getTextContent(); - InputFile sourceFile = delphiProjectHelper.getFileFromBasename(fileName); - + InputFile sourceFile = fileNameToInputFile.get().get(fileName); if (sourceFile == null) { LOG.debug("File not found in project: {}", fileName); return; } + LOG.debug("Parsing line hit information for file: {}", fileName); NewCoverage newCoverage = sensorContext.newCoverage(); diff --git a/delphi-frontend/src/main/java/au/com/integradev/delphi/msbuild/DelphiProjectHelper.java b/delphi-frontend/src/main/java/au/com/integradev/delphi/msbuild/DelphiProjectHelper.java index 0f52bc623..df7d24d80 100644 --- a/delphi-frontend/src/main/java/au/com/integradev/delphi/msbuild/DelphiProjectHelper.java +++ b/delphi-frontend/src/main/java/au/com/integradev/delphi/msbuild/DelphiProjectHelper.java @@ -365,10 +365,6 @@ public InputFile getFile(String path) { return fs.inputFile(fs.predicates().hasURI(Paths.get(path).toUri())); } - public InputFile getFileFromBasename(String basename) { - return fs.inputFile(fs.predicates().hasFilename(basename)); - } - public String encoding() { return fs != null ? fs.encoding().name() : Charset.defaultCharset().name(); } diff --git a/delphi-frontend/src/test/java/au/com/integradev/delphi/coverage/delphicodecoveragetool/DelphiCoverageToolParserTest.java b/delphi-frontend/src/test/java/au/com/integradev/delphi/coverage/delphicodecoveragetool/DelphiCoverageToolParserTest.java index 5b5d91f86..70df0b36c 100644 --- a/delphi-frontend/src/test/java/au/com/integradev/delphi/coverage/delphicodecoveragetool/DelphiCoverageToolParserTest.java +++ b/delphi-frontend/src/test/java/au/com/integradev/delphi/coverage/delphicodecoveragetool/DelphiCoverageToolParserTest.java @@ -56,6 +56,8 @@ class DelphiCoverageToolParserTest { private static final String INVALID_STRUCTURE = BASE_REPORT_PATH + "InvalidStructure.xml"; private static final String NORMAL_COVERAGE = BASE_REPORT_PATH + "NormalCoverage.xml"; private static final String NORMAL_COVERAGE_PART_2 = BASE_REPORT_PATH + "NormalCoverage2.xml"; + private static final String MISMATCHED_CASING_COVERAGE = + BASE_REPORT_PATH + "MismatchedCasingCoverage.xml"; private static final String GLOBALS_FILENAME = "Globals.pas"; private static final String GLOBALS_FILE_KEY = ":" + GLOBALS_FILENAME; @@ -92,10 +94,11 @@ void setup() throws IOException { delphiProjectHelper = new DelphiProjectHelper( context.config(), context.fileSystem(), environmentVariableProvider); - parser = new DelphiCodeCoverageParser(delphiProjectHelper); addFile(ROOT_NAME + "/" + GLOBALS_FILENAME); addFile(ROOT_NAME + "/" + MAIN_WINDOW_FILENAME); + + parser = new DelphiCodeCoverageParser(delphiProjectHelper); } @Test @@ -124,6 +127,22 @@ void testLineHitsFromDifferentReportsAreMerged() { assertThat(context.lineHits(GLOBALS_FILE_KEY, 23)).isEqualTo((Integer) 1); } + @Test + void testMismatchedCasingAllowed() { + parser.parse(context, DelphiUtils.getResource(MISMATCHED_CASING_COVERAGE)); + + assertThat(context.lineHits(GLOBALS_FILE_KEY, 16)).isEqualTo(1); + assertThat(context.lineHits(GLOBALS_FILE_KEY, 17)).isEqualTo(1); + assertThat(context.lineHits(GLOBALS_FILE_KEY, 23)).isZero(); + + assertThat(context.lineHits(MAIN_WINDOW_FILE_KEY, 31)).isEqualTo(1); + assertThat(context.lineHits(MAIN_WINDOW_FILE_KEY, 36)).isEqualTo(1); + assertThat(context.lineHits(MAIN_WINDOW_FILE_KEY, 37)).isEqualTo(1); + assertThat(context.lineHits(MAIN_WINDOW_FILE_KEY, 38)).isEqualTo(1); + assertThat(context.lineHits(MAIN_WINDOW_FILE_KEY, 39)).isEqualTo(1); + assertThat(context.lineHits(MAIN_WINDOW_FILE_KEY, 40)).isEqualTo(1); + } + void testReportFileIsIgnored(File file) { SensorContext mockContext = mock(SensorContext.class); assertThatCode(() -> parser.parse(mockContext, file)).doesNotThrowAnyException(); diff --git a/delphi-frontend/src/test/resources/au/com/integradev/delphi/projects/SimpleProject/delphicodecoveragereports/MismatchedCasingCoverage.xml b/delphi-frontend/src/test/resources/au/com/integradev/delphi/projects/SimpleProject/delphicodecoveragereports/MismatchedCasingCoverage.xml new file mode 100644 index 000000000..c2d47378f --- /dev/null +++ b/delphi-frontend/src/test/resources/au/com/integradev/delphi/projects/SimpleProject/delphicodecoveragereports/MismatchedCasingCoverage.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 16=1;17=1;23=0 + 31=1;36=1;37=1;38=1;39=1;40=1 + + +