Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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<Map<String, InputFile>> fileNameToInputFile;

public DelphiCodeCoverageParser(DelphiProjectHelper delphiProjectHelper) {
this.delphiProjectHelper = delphiProjectHelper;
this.fileNameToInputFile = Suppliers.memoize(this::indexInputFiles);
}

private Map<String, InputFile> indexInputFiles() {
var builder = ImmutableSortedMap.<String, InputFile>orderedBy(String.CASE_INSENSITIVE_ORDER);
for (InputFile inputFile : delphiProjectHelper.inputFiles()) {
builder.put(inputFile.filename(), inputFile);
}
return builder.build();
}

@Override
Expand Down Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?xml version="1.0" encoding="Windows-1252" standalone="no"?>
<report>
<stats>
<packages value="1"/>
<classes value="2"/>
<methods value="3"/>
<srcfiles value="4"/>
<srclines value="5"/>
<totallines value="6"/>
<coveredlines value="7"/>
<coveredpercent value="8"/>
</stats>
<data>
<all name="all classes">
<coverage type="class, %" value="41% (41/101)"/>
<coverage type="method, %" value="18% (112/636)"/>
<coverage type="block, %" value="12% (815/6924)"/>
<coverage type="line, %" value="12% (815/6924)"/>
<package name="[default]">
<coverage type="class, %" value="100% (5/5)"/>
<coverage type="method, %" value="74% (14/19)"/>
<coverage type="block, %" value="66% (93/140)"/>
<coverage type="line, %" value="66% (93/140)"/>
<srcfile name="MainWindow.pas">
<coverage type="class, %" value="100% (5/5)"/>
<coverage type="method, %" value="74% (14/19)"/>
<coverage type="block, %" value="66% (93/140)"/>
<coverage type="line, %" value="66% (93/140)"/>
<class name="TMainWindow">
<coverage type="class, %" value="100% (1/1)"/>
<coverage type="method, %" value="100% (1/1)"/>
<coverage type="block, %" value="56% (5/9)"/>
<coverage type="line, %" value="56% (5/9)"/>
<method name="foo2">
<coverage type="method, %" value="100% (1/1)"/>
<coverage type="block, %" value="56% (5/9)"/>
<coverage type="line, %" value="56% (5/9)"/>
<line number="36" covered="True"/>
<line number="37" covered="False"/>
<line number="38" covered="True"/>
<line number="39" covered="False"/>
</method>
</class>
</srcfile>
<srcfile name="Globals.pas">
<coverage type="class, %" value="100% (5/5)"/>
<coverage type="method, %" value="74% (14/19)"/>
<coverage type="block, %" value="66% (93/140)"/>
<coverage type="line, %" value="66% (93/140)"/>
<class name="TGlobals">
<coverage type="class, %" value="100% (1/1)"/>
<coverage type="method, %" value="100% (1/1)"/>
<coverage type="block, %" value="56% (5/9)"/>
<coverage type="line, %" value="56% (5/9)"/>
<method name="globalProcedure">
<coverage type="method, %" value="100% (2/2)"/>
<coverage type="block, %" value="100% (1/1)"/>
<coverage type="line, %" value="100% (2/2)"/>
<line number="19" covered="True"/>
<line number="20" covered="True"/>
</method>
</class>
</srcfile>
</package>
</all>
<linehits>
<file name="GlObAlS.pas">16=1;17=1;23=0</file>
<file name="maINwInDoW.pas">31=1;36=1;37=1;38=1;39=1;40=1</file>
</linehits>
</data>
</report>
Loading