Skip to content

Commit

Permalink
suppress reporting of coverage stats
Browse files Browse the repository at this point in the history
Arcmutates advanced incremental processing includes the option to avoid
gathering coverage for tests which cannot kill an in scope mutant.
Although this speeds up processing the html report shows most lines
as uncovered when this feature is activated. Reporting of line coverage
it therefore disabled when this feature is activated.
  • Loading branch information
Henry Coles committed Sep 21, 2023
1 parent a2c7a89 commit 4111156
Show file tree
Hide file tree
Showing 12 changed files with 83 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import org.pitest.coverage.analysis.LineMapper;
import org.pitest.mutationtest.ClassMutationResults;
import org.pitest.mutationtest.MutationMetaData;
import org.pitest.mutationtest.MutationResult;
import org.pitest.mutationtest.MutationResultListener;
import org.pitest.mutationtest.SourceLocator;
import org.pitest.mutationtest.build.CoverageTransformer;
Expand All @@ -21,17 +20,20 @@
import org.pitest.util.ResultOutputStrategy;

import java.io.File;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static java.util.Arrays.asList;

Expand Down Expand Up @@ -68,7 +70,9 @@ private ReportAggregator(SettingsFactory settings,
public AggregationResult aggregateReport() throws ReportAggregationException {
SmartSourceLocator sourceLocator = new SmartSourceLocator(asPaths(this.sourceCodeDirectories), inputCharset);

final MutationResultListener mutationResultListener = createResultListener(sourceLocator, Collections.emptySet());
boolean partialCoverage = scanForPartialCoverageFlag(mutationFiles);

final MutationResultListener mutationResultListener = createResultListener(sourceLocator, Collections.emptySet(), partialCoverage);
final ReportAggregatorResultListener reportAggregatorResultListener = new ReportAggregatorResultListener();

reportAggregatorResultListener.runStart();
Expand All @@ -93,11 +97,27 @@ public AggregationResult aggregateReport() throws ReportAggregationException {
return reportAggregatorResultListener.result();
}

private MutationResultListener createResultListener(SourceLocator sourceLocator, Collection<String> mutatorNames) throws ReportAggregationException {
private boolean scanForPartialCoverageFlag(Set<File> mutationFiles) {
// scan for the partial coverage flag. All files should have the same flag, so only really
// need to scan the first line of the first file, but expressing as a loop here just because.
for (File each : mutationFiles) {
try (Stream<String> lines = Files.lines(each.toPath())) {
// search for a false flag as this is the most likely case
if (lines.anyMatch(l -> l.contains("<mutations partial=\"false\"")) ) {
return false;
}
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
return true;
}

private MutationResultListener createResultListener(SourceLocator sourceLocator, Collection<String> mutatorNames, boolean partialCoverage) throws ReportAggregationException {
final CodeSource codeSource = this.codeSourceAggregator.createCodeSource();
final ReportCoverage coverageDatabase = calculateCoverage(codeSource);

return new MutationHtmlReportListener(outputCharset, coverageDatabase, this.resultOutputStrategy, mutatorNames, sourceLocator);
return new MutationHtmlReportListener(outputCharset, coverageDatabase, this.resultOutputStrategy, mutatorNames, partialCoverage, sourceLocator);
}

private Collection<Path> asPaths(Collection<File> files) {
Expand All @@ -106,17 +126,6 @@ private Collection<Path> asPaths(Collection<File> files) {
.collect(Collectors.toList());
}

private static Function<MutationResult, List<String>> resultToMutatorName() {
return a -> {
try {
final String mutatorName = a.getDetails().getId().getMutator();//MutatorUtil.loadMutator(a.getDetails().getMutator()).getName();
return Collections.singletonList(mutatorName);
} catch (final Exception e) {
throw new RuntimeException("Cannot convert to mutator: " + a.getDetails().getMutator(), e);
}
};
}

private ReportCoverage calculateCoverage(final CodeSource codeSource) throws ReportAggregationException {
try {
Collection<BlockLocation> coverageData = this.blockCoverageLoader.loadData().stream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ public class ReportOptions {

private boolean includeLaunchClasspath = true;

private boolean reportCoverage = true;

private Properties properties;

private int maxSurvivors;
Expand Down Expand Up @@ -647,6 +649,13 @@ public void setOutputEncoding(Charset outputEncoding) {
this.outputEncoding = outputEncoding;
}

public boolean shouldReportCoverage() {
return reportCoverage;
}

public void setReportCoverage(boolean reportCoverage) {
this.reportCoverage = reportCoverage;
}

@Override
public String toString() {
Expand Down Expand Up @@ -695,6 +704,7 @@ public String toString() {
.add("projectBase=" + projectBase)
.add("inputEncoding=" + inputEncoding)
.add("outputEncoding=" + outputEncoding)
.add("reportCoverage=" + reportCoverage)
.toString();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class XMLReportFactory implements MutationResultListenerFactory {
@Override
public MutationResultListener getListener(Properties props,
final ListenerArguments args) {
return new XMLReportListener(args.getOutputStrategy(), args.isFullMutationMatrix());
return new XMLReportListener(args.getOutputStrategy(), args.isFullMutationMatrix(), args.data().shouldReportCoverage());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,16 @@ public class XMLReportListener implements MutationResultListener {
private final Writer out;
private final boolean fullMutationMatrix;

public XMLReportListener(final ResultOutputStrategy outputStrategy, boolean fullMutationMatrix) {
this(outputStrategy.createWriterForFile("mutations.xml"), fullMutationMatrix);
private final boolean partialCoverage;

public XMLReportListener(final ResultOutputStrategy outputStrategy, boolean fullMutationMatrix, boolean partialCoverage) {
this(outputStrategy.createWriterForFile("mutations.xml"), fullMutationMatrix, partialCoverage);
}

public XMLReportListener(final Writer out, boolean fullMutationMatrix) {
public XMLReportListener(final Writer out, boolean fullMutationMatrix, boolean partialCoverage) {
this.out = out;
this.fullMutationMatrix = fullMutationMatrix;
this.partialCoverage = partialCoverage;
}

private void writeResult(final ClassMutationResults metaData) {
Expand Down Expand Up @@ -176,7 +179,7 @@ private void write(final String value) {
@Override
public void runStart() {
write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
write("<mutations>\n");
write("<mutations partial=\"" + this.partialCoverage + "\">\n");
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,14 @@ public class XMLReportListenerTest {
@Before
public void setup() {
this.out = new StringWriter();
this.testee = new XMLReportListener(this.out, false);
this.testee = new XMLReportListener(this.out, false, false);
}

@Test
public void shouldCreateAValidXmlDocumentWhenNoResults() {
this.testee.runStart();
this.testee.runEnd();
final String expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<mutations>\n</mutations>\n";
final String expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<mutations partial=\"false\">\n</mutations>\n";
assertThat(expected).isEqualTo(this.out.toString());
}

Expand All @@ -61,7 +61,7 @@ public void shouldOutputKillingTestWhenOneFound() {

@Test
public void shouldOutputFullMutationMatrixWhenEnabled() {
this.testee = new XMLReportListener(this.out, true);
this.testee = new XMLReportListener(this.out, true, false);
final MutationResult mr = new MutationResult(
MutationTestResultMother.createDetails(),
new MutationStatusTestPair(3, DetectionStatus.KILLED, Arrays.asList("foo", "foo2"), Arrays.asList("bar")));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,20 @@

public class AnnotatedLineFactory {

private final Collection<MutationResult> mutations;
private final ReportCoverage coverage;
private final Collection<ClassLines> classesInFile;

private final Set<Integer> coveredLines;
private final Collection<MutationResult> mutations;
private final Collection<ClassLines> classesInFile;
private final Set<Integer> coveredLines;
private final boolean reportCoverage;

public AnnotatedLineFactory(
final Collection<MutationResult> mutations,
final ReportCoverage coverage, final Collection<ClassLines> classes) {
final ReportCoverage coverage,
final Collection<ClassLines> classes,
boolean reportCoverage) {
this.mutations = mutations;
this.coverage = coverage;
this.classesInFile = classes;
this.coveredLines = findCoveredLines(classes,coverage);
this.reportCoverage = reportCoverage;
}

private Set<Integer> findCoveredLines(Collection<ClassLines> classes, ReportCoverage coverage) {
Expand Down Expand Up @@ -93,7 +94,7 @@ private Predicate<MutationResult> isAtLineNumber(final int lineNumber) {

private LineStatus lineCovered(final int line) {

if (!isCodeLine(line)) {
if (!isCodeLine(line) || !reportCoverage) {
return LineStatus.NotApplicable;
} else {
if (isLineCovered(line)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public class HtmlReportFactory implements MutationResultListenerFactory {
public MutationResultListener getListener(Properties props,
ListenerArguments args) {
return new MutationHtmlReportListener(args.data().getOutputEncoding(), args.getCoverage(),
args.getOutputStrategy(), args.getEngine().getMutatorNames(),
args.getOutputStrategy(), args.getEngine().getMutatorNames(), args.data().shouldReportCoverage(),
args.getLocator());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,16 +56,21 @@ public class MutationHtmlReportListener implements MutationResultListener {

private final String css;
private final Charset outputCharset;

public MutationHtmlReportListener(Charset outputCharset, final ReportCoverage coverage,
final ResultOutputStrategy outputStrategy,
Collection<String> mutatorNames, final SourceLocator... locators) {
private final boolean reportCoverage;

public MutationHtmlReportListener(Charset outputCharset,
ReportCoverage coverage,
ResultOutputStrategy outputStrategy,
Collection<String> mutatorNames,
boolean reportCoverage,
SourceLocator... locators) {
this.outputCharset = outputCharset;
this.coverage = coverage;
this.outputStrategy = outputStrategy;
this.sourceRoots = new HashSet<>(asList(locators));
this.mutatorNames = new HashSet<>(mutatorNames);
this.css = loadCss();
this.reportCoverage = reportCoverage;
}

private String loadCss() {
Expand Down Expand Up @@ -101,7 +106,7 @@ private void generateAnnotatedSourceFile(
st.setAttribute("sourceFile", sourceFile);
st.setAttribute("mutatedClasses", mutationMetaData.getMutatedClasses());
st.setAttribute("outputCharset", this.outputCharset);

st.setAttribute("showCoverage", this.reportCoverage);
writer.write(st.toString());


Expand Down Expand Up @@ -153,7 +158,7 @@ private List<Line> createAnnotatedSourceCodeLines(final String sourceFile,
sourceFile);
if (reader.isPresent()) {
final AnnotatedLineFactory alf = new AnnotatedLineFactory(
mutationsForThisFile.list(), this.coverage, classes);
mutationsForThisFile.list(), this.coverage, classes, this.reportCoverage);
return alf.convert(reader.get());
}
return Collections.emptyList();
Expand Down Expand Up @@ -215,6 +220,7 @@ private void createIndexPages() {
st.setAttribute("totals", totals);
st.setAttribute("packageSummaries", psd);
st.setAttribute("outputCharset", this.outputCharset);
st.setAttribute("showCoverage", this.reportCoverage);
try {
writer.write(st.toString());
writer.close();
Expand All @@ -233,6 +239,7 @@ private void createPackageIndexPage(final PackageSummaryData psData) {
.getPackageDirectory() + File.separator + "index.html");
st.setAttribute("packageData", psData);
st.setAttribute("outputCharset", this.outputCharset);
st.setAttribute("showCoverage", this.reportCoverage);
try {
writer.write(st.toString());
writer.close();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
<tbody>
<tr>
<td>$totals.numberOfFiles$</td>
<td>$totals.lineCoverage$% <div class="coverage_bar"><div class="coverage_complete width-$totals.lineCoverage$"></div><div class="coverage_legend">$totals.numberOfLinesCovered$/$totals.numberOfLines$</div></div></td>
$if(showCoverage)$ <td>$totals.lineCoverage$% <div class="coverage_bar"><div class="coverage_complete width-$totals.lineCoverage$"></div><div class="coverage_legend">$totals.numberOfLinesCovered$/$totals.numberOfLines$</div></div></td>
$else$<td><div class="coverage_bar"><div class="coverage_complete width-100"></div><div class="coverage_legend">n/a</div></div></td>
$endif$
<td>$totals.mutationCoverage$% <div class="coverage_bar"><div class="coverage_complete width-$totals.mutationCoverage$"></div><div class="coverage_legend">$totals.numberOfMutationsDetected$/$totals.numberOfMutations$</div></div></td>
<td>$totals.testStrength$% <div class="coverage_bar"><div class="coverage_complete width-$totals.testStrength$"></div><div class="coverage_legend">$totals.numberOfMutationsDetected$/$totals.numberOfMutationsWithCoverage$</div></div></td>
</tr>
Expand All @@ -45,7 +47,9 @@ $packageSummaries:{ summary |
<tr>
<td><a href="./$summary.packageDirectory$/index.html">$summary.packageName$</a></td>
<td>$summary.totals.numberOfFiles$</td>
<td><div class="coverage_percentage">$summary.totals.lineCoverage$% </div><div class="coverage_bar"><div class="coverage_complete width-$summary.totals.lineCoverage$"></div><div class="coverage_legend">$summary.totals.numberOfLinesCovered$/$summary.totals.numberOfLines$</div></div></td>
$if(showCoverage)$ <td><div class="coverage_percentage">$summary.totals.lineCoverage$% </div><div class="coverage_bar"><div class="coverage_complete width-$summary.totals.lineCoverage$"></div><div class="coverage_legend">$summary.totals.numberOfLinesCovered$/$summary.totals.numberOfLines$</div></div></td>
$else$<td><div class="coverage_bar"><div class="coverage_complete width-100"></div><div class="coverage_legend">n/a</div></div></td>
$endif$
<td><div class="coverage_percentage">$summary.totals.mutationCoverage$% </div><div class="coverage_bar"><div class="coverage_complete width-$summary.totals.mutationCoverage$"></div><div class="coverage_legend">$summary.totals.numberOfMutationsDetected$/$summary.totals.numberOfMutations$</div></div></td>
<td><div class="coverage_percentage">$summary.totals.testStrength$% </div><div class="coverage_bar"><div class="coverage_complete width-$summary.totals.testStrength$"></div><div class="coverage_legend">$summary.totals.numberOfMutationsDetected$/$summary.totals.numberOfMutationsWithCoverage$</div></div></td>
</tr>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
<tbody>
<tr>
<td>$packageData.totals.numberOfFiles$</td>
<td>$packageData.totals.lineCoverage$% <div class="coverage_bar"><div class="coverage_complete width-$packageData.totals.lineCoverage$"></div><div class="coverage_legend">$packageData.totals.numberOfLinesCovered$/$packageData.totals.numberOfLines$</div></div></td>
$if(showCoverage)$<td>$packageData.totals.lineCoverage$% <div class="coverage_bar"><div class="coverage_complete width-$packageData.totals.lineCoverage$"></div><div class="coverage_legend">$packageData.totals.numberOfLinesCovered$/$packageData.totals.numberOfLines$</div></div></td>
$else$<td><div class="coverage_bar"><div class="coverage_complete width-100"></div><div class="coverage_legend">n/a</div></div></td>
$endif$
<td>$packageData.totals.mutationCoverage$% <div class="coverage_bar"><div class="coverage_complete width-$packageData.totals.mutationCoverage$"></div><div class="coverage_legend">$packageData.totals.numberOfMutationsDetected$/$packageData.totals.numberOfMutations$</div></div></td>
<td>$packageData.totals.testStrength$% <div class="coverage_bar"><div class="coverage_complete width-$packageData.totals.testStrength$"></div><div class="coverage_legend">$packageData.totals.numberOfMutationsDetected$/$packageData.totals.numberOfMutationsWithCoverage$</div></div></td>
</tr>
Expand All @@ -43,7 +45,9 @@
$packageData.summaryData:{ summary |
<tr>
<td><a href="./$summary.fileName$.html">$summary.fileName$</a></td>
<td><div class="coverage_percentage">$summary.totals.lineCoverage$% </div><div class="coverage_bar"><div class="coverage_complete width-$summary.totals.lineCoverage$"></div><div class="coverage_legend">$summary.totals.numberOfLinesCovered$/$summary.totals.numberOfLines$</div></div></td>
$if(showCoverage)$<td><div class="coverage_percentage">$summary.totals.lineCoverage$% </div><div class="coverage_bar"><div class="coverage_complete width-$summary.totals.lineCoverage$"></div><div class="coverage_legend">$summary.totals.numberOfLinesCovered$/$summary.totals.numberOfLines$</div></div></td>
$else$<td><div class="coverage_bar"><div class="coverage_complete width-100"></div><div class="coverage_legend">n/a</div></div></td>
$endif$
<td><div class="coverage_percentage">$summary.totals.mutationCoverage$% </div><div class="coverage_bar"><div class="coverage_complete width-$summary.totals.mutationCoverage$"></div><div class="coverage_legend">$summary.totals.numberOfMutationsDetected$/$summary.totals.numberOfMutations$</div></div></td>
<td><div class="coverage_percentage">$summary.totals.testStrength$% </div><div class="coverage_bar"><div class="coverage_complete width-$summary.totals.testStrength$"></div><div class="coverage_legend">$summary.totals.numberOfMutationsDetected$/$summary.totals.numberOfMutationsWithCoverage$</div></div></td>
</tr>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public void setUp() {
this.classInfo);

this.testee = new MutationHtmlReportListener(StandardCharsets.UTF_8, this.coverageDb,
this.outputStrategy, Collections.<String>emptyList(), this.sourceLocator);
this.outputStrategy, Collections.<String>emptyList(), true, this.sourceLocator);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,7 @@ private List<File> getProjectFilesByFilter(final File projectBaseDir,
}

@SuppressWarnings("unchecked")
private List<File> getCompiledDirs(final MavenProject project)
throws Exception {
private List<File> getCompiledDirs(final MavenProject project) {
final List<String> sourceRoots = new ArrayList<>();
for (final Object artifactObj : FCollection
.filter(project.getPluginArtifactMap().values(), new DependencyFilter(
Expand Down

0 comments on commit 4111156

Please sign in to comment.