From 6f8342f96be60364055754859eb12ae4987001fa Mon Sep 17 00:00:00 2001 From: Henry Coles Date: Tue, 2 Apr 2024 13:50:38 +0100 Subject: [PATCH 1/5] pass build issues to listeners --- .../pitest/aggregate/ReportAggregator.java | 8 ++- .../mutationtest/ListenerArguments.java | 20 +++++-- .../tooling/CombinedStatistics.java | 7 ++- .../tooling/MutationCoverage.java | 15 ++--- .../mutationtest/verify/BuildIssue.java | 58 +++++++++++++++++++ .../mutationtest/verify/BuildVerifier.java | 13 ++++- .../verify/CompoundBuildVerifierFactory.java | 11 +++- .../verify/DefaultBuildVerifier.java | 2 +- .../verify/KotlinVerifierFactory.java | 4 +- .../config/CompoundListenerFactoryTest.java | 3 +- .../tooling/MutationCoverageReportTest.java | 2 +- .../mutationtest/verify/BuildIssueTest.java | 30 ++++++++++ .../CompoundBuildVerifierFactoryTest.java | 23 +++++++- .../verify/DefaultBuildVerifierTest.java | 14 ++--- .../interceptors/BuildVerifierVerifier.java | 5 +- .../report/html/HtmlReportFactory.java | 2 +- .../html/MutationHtmlReportListener.java | 30 ++++++++++ .../mutation/mutation_package_index.st | 7 +++ .../html/MutationHtmlReportListenerTest.java | 2 +- 19 files changed, 219 insertions(+), 37 deletions(-) create mode 100644 pitest-entry/src/main/java/org/pitest/mutationtest/verify/BuildIssue.java create mode 100644 pitest-entry/src/test/java/org/pitest/mutationtest/verify/BuildIssueTest.java diff --git a/pitest-aggregator/src/main/java/org/pitest/aggregate/ReportAggregator.java b/pitest-aggregator/src/main/java/org/pitest/aggregate/ReportAggregator.java index e6b055dcf..3a43f8393 100644 --- a/pitest-aggregator/src/main/java/org/pitest/aggregate/ReportAggregator.java +++ b/pitest-aggregator/src/main/java/org/pitest/aggregate/ReportAggregator.java @@ -117,7 +117,13 @@ private MutationResultListener createResultListener(SourceLocator sourceLocator, final CodeSource codeSource = this.codeSourceAggregator.createCodeSource(); final ReportCoverage coverageDatabase = calculateCoverage(codeSource); - return new MutationHtmlReportListener(outputCharset, coverageDatabase, this.resultOutputStrategy, mutatorNames, partialCoverage, sourceLocator); + return new MutationHtmlReportListener(outputCharset, + coverageDatabase, + this.resultOutputStrategy, + mutatorNames, + partialCoverage, + Collections.emptyList(), + sourceLocator); } private Collection asPaths(Collection files) { diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/ListenerArguments.java b/pitest-entry/src/main/java/org/pitest/mutationtest/ListenerArguments.java index dbad394cc..1f8d490bb 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/ListenerArguments.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/ListenerArguments.java @@ -3,9 +3,12 @@ import org.pitest.coverage.ReportCoverage; import org.pitest.mutationtest.config.ReportOptions; import org.pitest.mutationtest.engine.MutationEngine; +import org.pitest.mutationtest.verify.BuildIssue; import org.pitest.plugin.FeatureSetting; import org.pitest.util.ResultOutputStrategy; +import java.util.Collections; +import java.util.List; import java.util.Optional; /** @@ -22,6 +25,7 @@ public class ListenerArguments { private final boolean fullMutationMatrix; private final ReportOptions data; private final FeatureSetting setting; + private final List issues; public ListenerArguments(ResultOutputStrategy outputStrategy, ReportCoverage coverage, @@ -29,8 +33,9 @@ public ListenerArguments(ResultOutputStrategy outputStrategy, MutationEngine engine, long startTime, boolean fullMutationMatrix, - ReportOptions data) { - this(outputStrategy, coverage, locator, engine, startTime, fullMutationMatrix, data, null); + ReportOptions data, + List issues) { + this(outputStrategy, coverage, locator, engine, startTime, fullMutationMatrix, data, null, issues); } ListenerArguments(ResultOutputStrategy outputStrategy, @@ -40,7 +45,8 @@ public ListenerArguments(ResultOutputStrategy outputStrategy, long startTime, boolean fullMutationMatrix, ReportOptions data, - FeatureSetting setting) { + FeatureSetting setting, + List issues) { this.outputStrategy = outputStrategy; this.coverage = coverage; this.locator = locator; @@ -49,6 +55,7 @@ public ListenerArguments(ResultOutputStrategy outputStrategy, this.fullMutationMatrix = fullMutationMatrix; this.data = data; this.setting = setting; + this.issues = issues; } public ResultOutputStrategy getOutputStrategy() { @@ -83,6 +90,10 @@ public Optional settings() { return Optional.ofNullable(setting); } + public List issues() { + return Collections.unmodifiableList(issues); + } + public ListenerArguments withSetting(FeatureSetting setting) { return new ListenerArguments(outputStrategy, coverage, @@ -91,7 +102,8 @@ public ListenerArguments withSetting(FeatureSetting setting) { startTime, fullMutationMatrix, data, - setting); + setting, + issues); } } diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/tooling/CombinedStatistics.java b/pitest-entry/src/main/java/org/pitest/mutationtest/tooling/CombinedStatistics.java index 771b53cfb..182203075 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/tooling/CombinedStatistics.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/tooling/CombinedStatistics.java @@ -2,6 +2,7 @@ import org.pitest.coverage.CoverageSummary; import org.pitest.mutationtest.statistics.MutationStatistics; +import org.pitest.mutationtest.verify.BuildIssue; import java.util.List; @@ -10,11 +11,11 @@ public class CombinedStatistics { private final MutationStatistics mutationStatistics; private final CoverageSummary coverageSummary; - private final List issues; + private final List issues; public CombinedStatistics(MutationStatistics mutationStatistics, CoverageSummary coverageSummary, - List issues) { + List issues) { this.mutationStatistics = mutationStatistics; this.coverageSummary = coverageSummary; this.issues = issues; @@ -28,7 +29,7 @@ public CoverageSummary getCoverageSummary() { return this.coverageSummary; } - public List getIssues() { + public List getIssues() { return issues; } diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/tooling/MutationCoverage.java b/pitest-entry/src/main/java/org/pitest/mutationtest/tooling/MutationCoverage.java index 1e81dbd95..67138bbfe 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/tooling/MutationCoverage.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/tooling/MutationCoverage.java @@ -50,6 +50,7 @@ import org.pitest.mutationtest.statistics.MutationStatistics; import org.pitest.mutationtest.statistics.MutationStatisticsListener; import org.pitest.mutationtest.statistics.Score; +import org.pitest.mutationtest.verify.BuildIssue; import org.pitest.util.Log; import org.pitest.util.StringUtil; import org.pitest.util.Timings; @@ -113,7 +114,7 @@ public CombinedStatistics runReport() throws IOException { final long t0 = System.nanoTime(); - List issues = verifyBuildSuitableForMutationTesting(); + List issues = verifyBuildSuitableForMutationTesting(); checkExcludedRunners(); @@ -142,7 +143,7 @@ private CombinedStatistics emptyStatistics() { return new CombinedStatistics(mutationStatistics, new CoverageSummary(0,0), Collections.emptyList()); } - private CombinedStatistics runAnalysis(Runtime runtime, long t0, EngineArguments args, MutationEngine engine, List issues) { + private CombinedStatistics runAnalysis(Runtime runtime, long t0, EngineArguments args, MutationEngine engine, List issues) { History history = this.strategies.history(); history.initialize(); @@ -170,7 +171,7 @@ private CombinedStatistics runAnalysis(Runtime runtime, long t0, EngineArguments ReportCoverage modifiedCoverage = transformCoverage(coverageData); final List config = createConfig(t0, modifiedCoverage, history, - stats, engine); + stats, engine, issues); final MutationAnalysisExecutor mae = new MutationAnalysisExecutor( numberOfThreads(), resultInterceptor(), config); this.timings.registerStart(Timings.Stage.RUN_MUTATION_TESTS); @@ -254,14 +255,14 @@ private List createConfig(long t0, ReportCoverage coverageData, History history, MutationStatisticsListener stats, - MutationEngine engine) { + MutationEngine engine, List issues) { final List ls = new ArrayList<>(); ls.add(stats); final ListenerArguments args = new ListenerArguments( this.strategies.output(), coverageData, new SmartSourceLocator( - data.getSourcePaths(), this.data.getInputEncoding()), engine, t0, this.data.isFullMutationMatrix(), data); + data.getSourcePaths(), this.data.getInputEncoding()), engine, t0, this.data.isFullMutationMatrix(), data, issues); final MutationResultListener mutationReportListener = this.strategies .listenerFactory().getListener(this.data.getFreeFormProperties(), args); @@ -279,8 +280,8 @@ private MutationResultInterceptor resultInterceptor() { return this.strategies.resultInterceptor(); } - private List verifyBuildSuitableForMutationTesting() { - return this.strategies.buildVerifier().verify(); + private List verifyBuildSuitableForMutationTesting() { + return this.strategies.buildVerifier().verifyBuild(); } private void printStats(CombinedStatistics combinedStatistics) { diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/verify/BuildIssue.java b/pitest-entry/src/main/java/org/pitest/mutationtest/verify/BuildIssue.java new file mode 100644 index 000000000..1d93fcb2d --- /dev/null +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/verify/BuildIssue.java @@ -0,0 +1,58 @@ +package org.pitest.mutationtest.verify; + +import java.util.Objects; + +public final class BuildIssue implements Comparable { + private final String text; + private final String url; + private final int priority; + + public BuildIssue(String text, String url, int priority) { + this.text = text; + this.url = url; + this.priority = priority; + } + + public static BuildIssue issue(String text) { + return new BuildIssue(text, null, 5); + } + + public String text() { + return text; + } + + public String url() { + return url; + } + + public int priority() { + return priority; + } + + @Override + public String toString() { + return text + " (" + url + ")"; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + BuildIssue that = (BuildIssue) o; + return priority == that.priority && Objects.equals(text, that.text) && Objects.equals(url, that.url); + } + + @Override + public int hashCode() { + return Objects.hash(text, url, priority); + } + + @Override + public int compareTo(BuildIssue o) { + return Integer.compare(this.priority, o.priority); + } +} diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/verify/BuildVerifier.java b/pitest-entry/src/main/java/org/pitest/mutationtest/verify/BuildVerifier.java index 585ad7b21..9059abc31 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/verify/BuildVerifier.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/verify/BuildVerifier.java @@ -1,6 +1,8 @@ package org.pitest.mutationtest.verify; +import java.util.Collections; import java.util.List; +import java.util.stream.Collectors; /** * Checks project for potential issues. Should throw an exception @@ -9,6 +11,15 @@ */ public interface BuildVerifier { - List verify(); + @Deprecated + default List verify() { + return Collections.emptyList(); + } + + default List verifyBuild() { + return verify().stream() + .map(BuildIssue::issue) + .collect(Collectors.toList()); + } } diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/verify/CompoundBuildVerifierFactory.java b/pitest-entry/src/main/java/org/pitest/mutationtest/verify/CompoundBuildVerifierFactory.java index 3d7caa2a4..69d5b5a9f 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/verify/CompoundBuildVerifierFactory.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/verify/CompoundBuildVerifierFactory.java @@ -15,10 +15,17 @@ public CompoundBuildVerifierFactory(List verifiers) { @Override public BuildVerifier create(CodeSource code) { - return () -> verifiers.stream() + List issues = verifiers.stream() .map(f -> f.create(code)) - .flatMap(v -> v.verify().stream()) + .flatMap(v -> v.verifyBuild().stream()) .collect(Collectors.toList()); + + return new BuildVerifier() { + @Override + public List verifyBuild() { + return issues; + } + }; } @Override diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/verify/DefaultBuildVerifier.java b/pitest-entry/src/main/java/org/pitest/mutationtest/verify/DefaultBuildVerifier.java index ec97ef4e2..168c4a91a 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/verify/DefaultBuildVerifier.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/verify/DefaultBuildVerifier.java @@ -33,7 +33,7 @@ public DefaultBuildVerifier(CodeSource code) { } @Override - public List verify() { + public List verifyBuild() { // check we have at least one class that is not an interface // otherwise our checks will fire on an empty project diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/verify/KotlinVerifierFactory.java b/pitest-entry/src/main/java/org/pitest/mutationtest/verify/KotlinVerifierFactory.java index 598a07170..9d336e456 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/verify/KotlinVerifierFactory.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/verify/KotlinVerifierFactory.java @@ -29,9 +29,9 @@ class KotlinVerifier implements BuildVerifier { } @Override - public List verify() { + public List verifyBuild() { if (kotlinIsOnClassPath() && !kotlinPluginIsPresent() && kotlinClassesToBeMutated()) { - return asList("Project uses kotlin, but the Arcmutate kotlin plugin is not present (https://docs.arcmutate.com/docs/kotlin.html)"); + return asList(new BuildIssue("Project uses kotlin, but the Arcmutate kotlin plugin is not present.", "https://docs.arcmutate.com/docs/kotlin.html", 4)); } return Collections.emptyList(); diff --git a/pitest-entry/src/test/java/org/pitest/mutationtest/config/CompoundListenerFactoryTest.java b/pitest-entry/src/test/java/org/pitest/mutationtest/config/CompoundListenerFactoryTest.java index 1b2a3c7be..f2b5eb61a 100644 --- a/pitest-entry/src/test/java/org/pitest/mutationtest/config/CompoundListenerFactoryTest.java +++ b/pitest-entry/src/test/java/org/pitest/mutationtest/config/CompoundListenerFactoryTest.java @@ -22,6 +22,7 @@ import org.pitest.mutationtest.MutationResultListener; import org.pitest.mutationtest.MutationResultListenerFactory; +import java.util.Collections; import java.util.Properties; import static java.util.Arrays.asList; @@ -70,7 +71,7 @@ public void shouldCreateACombinedListenerForAllChildFactories() { private ListenerArguments someArgs() { return new ListenerArguments(null, null, null, null, - 0, false, null); + 0, false, null, Collections.emptyList()); } } diff --git a/pitest-entry/src/test/java/org/pitest/mutationtest/tooling/MutationCoverageReportTest.java b/pitest-entry/src/test/java/org/pitest/mutationtest/tooling/MutationCoverageReportTest.java index 3318c8b74..f4ea301f1 100644 --- a/pitest-entry/src/test/java/org/pitest/mutationtest/tooling/MutationCoverageReportTest.java +++ b/pitest-entry/src/test/java/org/pitest/mutationtest/tooling/MutationCoverageReportTest.java @@ -169,7 +169,7 @@ public void shouldRecordClassPath() { @Test public void shouldCheckBuildSuitableForMutationTesting() { createAndRunTestee(); - verify(this.verifier).verify(); + verify(this.verifier).verifyBuild(); } @Test diff --git a/pitest-entry/src/test/java/org/pitest/mutationtest/verify/BuildIssueTest.java b/pitest-entry/src/test/java/org/pitest/mutationtest/verify/BuildIssueTest.java new file mode 100644 index 000000000..23963c2dd --- /dev/null +++ b/pitest-entry/src/test/java/org/pitest/mutationtest/verify/BuildIssueTest.java @@ -0,0 +1,30 @@ +package org.pitest.mutationtest.verify; + +import nl.jqno.equalsverifier.EqualsVerifier; +import org.junit.Test; + +import java.util.Collections; +import java.util.List; + +import static java.util.Arrays.asList; +import static org.assertj.core.api.Assertions.assertThat; + + +public class BuildIssueTest { + @Test + public void obeysHashcodeEqualsContract() { + EqualsVerifier.forClass(BuildIssue.class) + .verify(); + } + + @Test + public void sortsZeroPriorityFirst() { + BuildIssue a = new BuildIssue("a","",10); + BuildIssue b = new BuildIssue("b","",0); + BuildIssue c = new BuildIssue("c","",5); + + List l = asList(a,b,c); + Collections.sort(l); + assertThat(l).containsExactly(b,c,a); + } +} \ No newline at end of file diff --git a/pitest-entry/src/test/java/org/pitest/mutationtest/verify/CompoundBuildVerifierFactoryTest.java b/pitest-entry/src/test/java/org/pitest/mutationtest/verify/CompoundBuildVerifierFactoryTest.java index b67b76c0d..749844370 100644 --- a/pitest-entry/src/test/java/org/pitest/mutationtest/verify/CompoundBuildVerifierFactoryTest.java +++ b/pitest-entry/src/test/java/org/pitest/mutationtest/verify/CompoundBuildVerifierFactoryTest.java @@ -4,20 +4,25 @@ import org.mockito.Mockito; import org.pitest.classpath.CodeSource; +import java.util.List; +import java.util.stream.Collectors; + import static java.util.Arrays.asList; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; +import static org.pitest.mutationtest.verify.BuildIssue.issue; public class CompoundBuildVerifierFactoryTest { @Test public void returnsResultsFromChildren() { CompoundBuildVerifierFactory underTest = new CompoundBuildVerifierFactory(asList( - factoryFor(() -> asList("one")), - factoryFor(() -> asList("two", "three")))); + factoryFor(buildVerifier(asList("one"))), + factoryFor(buildVerifier(asList("two", "three"))))); - assertThat(underTest.create(aCodeSource()).verify()).containsExactly("one", "two", "three"); + assertThat(underTest.create(aCodeSource()).verifyBuild()) + .containsExactly(issue("one"), issue("two"), issue("three")); } private BuildVerifierFactory factoryFor(BuildVerifier bv) { @@ -29,4 +34,16 @@ private BuildVerifierFactory factoryFor(BuildVerifier bv) { private CodeSource aCodeSource() { return Mockito.mock(CodeSource.class); } + + private BuildVerifier buildVerifier(List issues) { + return new BuildVerifier() { + @Override + public List verifyBuild() { + return issues.stream() + .map(BuildIssue::issue) + .collect(Collectors.toList()); + + } + }; + } } \ No newline at end of file diff --git a/pitest-entry/src/test/java/org/pitest/mutationtest/verify/DefaultBuildVerifierTest.java b/pitest-entry/src/test/java/org/pitest/mutationtest/verify/DefaultBuildVerifierTest.java index 7b34e60b8..4b057fff0 100644 --- a/pitest-entry/src/test/java/org/pitest/mutationtest/verify/DefaultBuildVerifierTest.java +++ b/pitest-entry/src/test/java/org/pitest/mutationtest/verify/DefaultBuildVerifierTest.java @@ -57,21 +57,21 @@ private interface AnInterface { @Test public void shouldNotThrowErrorForClassCompiledWithDebugInfo() { setupClassPath(AClass.class); - this.testee.verify(); + this.testee.verifyBuild(); // pass } @Test(expected = PitHelpError.class) public void shouldThrowErrorForClassCompiledWithoutSourceFileDebugInfo() { setupClassPath(new ResourceFolderByteArraySource(), "FooNoSource"); - this.testee.verify(); + this.testee.verifyBuild(); } @Test public void shouldNotThrowErrorForSyntheticClassCompiledWithoutSourceFileDebugInfo() { setupClassPath(new ResourceFolderByteArraySource(), "SyntheticNoSourceDebug"); try { - this.testee.verify(); + this.testee.verifyBuild(); } catch (final PitHelpError ex) { fail(); } @@ -80,14 +80,14 @@ public void shouldNotThrowErrorForSyntheticClassCompiledWithoutSourceFileDebugIn @Test(expected = PitHelpError.class) public void shouldThrowErrorForClassCompiledWithoutLineNumberDebugInfo() { setupClassPath(new ResourceFolderByteArraySource(), "FooNoLines"); - this.testee.verify(); + this.testee.verifyBuild(); } @Test public void shouldNotThrowAnErrorWhenNoClassesFound() { when(this.code.codeTrees()).thenReturn(Stream.empty()); try { - this.testee.verify(); + this.testee.verifyBuild(); } catch (final PitHelpError e) { fail(); } @@ -97,7 +97,7 @@ public void shouldNotThrowAnErrorWhenNoClassesFound() { public void shouldNotThrowAnErrorWhenOnlyInterfacesPresent() { setupClassPath(AnInterface.class); try { - this.testee.verify(); + this.testee.verifyBuild(); } catch (final PitHelpError e) { fail(); } @@ -106,7 +106,7 @@ public void shouldNotThrowAnErrorWhenOnlyInterfacesPresent() { @Test public void doesNotErrorWhenNoClassesProvided() { when(this.code.codeTrees()).thenReturn(Stream.empty()); - assertThatCode(() -> this.testee.verify()).doesNotThrowAnyException(); + assertThatCode(() -> this.testee.verifyBuild()).doesNotThrowAnyException(); } private void setupClassPath(final Class clazz) { diff --git a/pitest-entry/src/test/java/org/pitest/verifier/interceptors/BuildVerifierVerifier.java b/pitest-entry/src/test/java/org/pitest/verifier/interceptors/BuildVerifierVerifier.java index 830184cd5..1538bce07 100644 --- a/pitest-entry/src/test/java/org/pitest/verifier/interceptors/BuildVerifierVerifier.java +++ b/pitest-entry/src/test/java/org/pitest/verifier/interceptors/BuildVerifierVerifier.java @@ -13,6 +13,7 @@ import org.pitest.classpath.PathFilter; import org.pitest.classpath.ProjectClassPaths; import org.pitest.mutationtest.config.PluginServices; +import org.pitest.mutationtest.verify.BuildIssue; import org.pitest.mutationtest.verify.BuildVerifierFactory; import java.io.ByteArrayInputStream; @@ -48,8 +49,8 @@ public void isOnChain() { factoryIsOnChain(factory.getClass()); } - public ListAssert issues() { - return assertThat(factory.create(codeSource).verify()); + public ListAssert issues() { + return assertThat(factory.create(codeSource).verifyBuild()); } public BuildVerifierVerifier withCodeSource(CodeSource source) { diff --git a/pitest-html-report/src/main/java/org/pitest/mutationtest/report/html/HtmlReportFactory.java b/pitest-html-report/src/main/java/org/pitest/mutationtest/report/html/HtmlReportFactory.java index e47bacb59..3745f7c66 100644 --- a/pitest-html-report/src/main/java/org/pitest/mutationtest/report/html/HtmlReportFactory.java +++ b/pitest-html-report/src/main/java/org/pitest/mutationtest/report/html/HtmlReportFactory.java @@ -28,7 +28,7 @@ public MutationResultListener getListener(Properties props, ListenerArguments args) { return new MutationHtmlReportListener(args.data().getOutputEncoding(), args.getCoverage(), args.getOutputStrategy(), args.getEngine().getMutatorNames(), args.data().shouldReportCoverage(), - args.getLocator()); + args.issues(), args.getLocator()); } @Override diff --git a/pitest-html-report/src/main/java/org/pitest/mutationtest/report/html/MutationHtmlReportListener.java b/pitest-html-report/src/main/java/org/pitest/mutationtest/report/html/MutationHtmlReportListener.java index 4bba4d2dd..542120a70 100644 --- a/pitest-html-report/src/main/java/org/pitest/mutationtest/report/html/MutationHtmlReportListener.java +++ b/pitest-html-report/src/main/java/org/pitest/mutationtest/report/html/MutationHtmlReportListener.java @@ -21,6 +21,7 @@ import org.pitest.mutationtest.ClassMutationResults; import org.pitest.mutationtest.MutationResultListener; import org.pitest.mutationtest.SourceLocator; +import org.pitest.mutationtest.verify.BuildIssue; import org.pitest.util.FileUtil; import org.pitest.util.IsolationUtils; import org.pitest.util.Log; @@ -58,11 +59,14 @@ public class MutationHtmlReportListener implements MutationResultListener { private final Charset outputCharset; private final boolean reportCoverage; + private final List issues; + public MutationHtmlReportListener(Charset outputCharset, ReportCoverage coverage, ResultOutputStrategy outputStrategy, Collection mutatorNames, boolean reportCoverage, + List issues, SourceLocator... locators) { this.outputCharset = outputCharset; this.coverage = coverage; @@ -71,6 +75,7 @@ public MutationHtmlReportListener(Charset outputCharset, this.mutatorNames = new HashSet<>(mutatorNames); this.css = loadCss(); this.reportCoverage = reportCoverage; + this.issues = issues; } private String loadCss() { @@ -221,6 +226,7 @@ private void createIndexPages() { st.setAttribute("packageSummaries", psd); st.setAttribute("outputCharset", this.outputCharset); st.setAttribute("showCoverage", this.reportCoverage); + st.setAttribute("issues", wrap(this.issues)); try { writer.write(st.toString()); writer.close(); @@ -230,6 +236,13 @@ private void createIndexPages() { } + private List wrap(List issues) { + return issues.stream() + .sorted() + .map(ConvertedIssue::new) + .collect(Collectors.toList()); + } + private void createPackageIndexPage(final PackageSummaryData psData) { final StringTemplateGroup group = new StringTemplateGroup("mutation_test"); final StringTemplate st = group @@ -270,4 +283,21 @@ public void handleMutationResult(final ClassMutationResults metaData) { } +} + +// wrapper providing StringTemplate friendly accessors +class ConvertedIssue { + private final BuildIssue issue; + ConvertedIssue(BuildIssue issue) { + this.issue = issue; + } + + public String getText() { + return issue.text(); + } + + public String getUrl() { + return issue.url(); + } + } \ No newline at end of file diff --git a/pitest-html-report/src/main/resources/templates/mutation/mutation_package_index.st b/pitest-html-report/src/main/resources/templates/mutation/mutation_package_index.st index 4916a5053..185978e8b 100644 --- a/pitest-html-report/src/main/resources/templates/mutation/mutation_package_index.st +++ b/pitest-html-report/src/main/resources/templates/mutation/mutation_package_index.st @@ -66,8 +66,15 @@ $errors : { error |
}$ +
+ + Report generated by PIT ${project.version}
diff --git a/pitest-html-report/src/test/java/org/pitest/mutationtest/report/html/MutationHtmlReportListenerTest.java b/pitest-html-report/src/test/java/org/pitest/mutationtest/report/html/MutationHtmlReportListenerTest.java index 2168269b0..335fdc190 100644 --- a/pitest-html-report/src/test/java/org/pitest/mutationtest/report/html/MutationHtmlReportListenerTest.java +++ b/pitest-html-report/src/test/java/org/pitest/mutationtest/report/html/MutationHtmlReportListenerTest.java @@ -69,7 +69,7 @@ public void setUp() { this.classInfo); this.testee = new MutationHtmlReportListener(StandardCharsets.UTF_8, this.coverageDb, - this.outputStrategy, Collections.emptyList(), true, this.sourceLocator); + this.outputStrategy, Collections.emptyList(), true, Collections.emptyList(), this.sourceLocator); } @Test From acd0075087f3b35f4620f2a9ddc33c121114363e Mon Sep 17 00:00:00 2001 From: Henry Coles Date: Tue, 2 Apr 2024 15:19:37 +0100 Subject: [PATCH 2/5] update build verifiers to seperate url --- .../verify/MissingJUnit5PluginVerifierFactory.java | 6 +++--- .../verify/MissingTestNGPluginVerifierFactory.java | 6 +++--- .../pitest/mutationtest/verify/SpringVerifierFactory.java | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/verify/MissingJUnit5PluginVerifierFactory.java b/pitest-entry/src/main/java/org/pitest/mutationtest/verify/MissingJUnit5PluginVerifierFactory.java index e9d6fad0f..51f712b3e 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/verify/MissingJUnit5PluginVerifierFactory.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/verify/MissingJUnit5PluginVerifierFactory.java @@ -31,12 +31,12 @@ class MissingJUnit5PluginVerifier implements BuildVerifier { } @Override - public List verify() { + public List verifyBuild() { if (!junit5PluginIsPresent() && junitJupiterPresent()) { // log as well as return in case the run is aborted before messages are displayed at the end - String msg = "JUnit 5 is on the classpath but the pitest junit 5 plugin is not installed (https://github.com/pitest/pitest-junit5-plugin)"; + String msg = "JUnit 5 is on the classpath but the pitest junit 5 plugin is not installed."; Log.getLogger().warning(msg); - return asList(msg); + return asList(new BuildIssue(msg, "https://github.com/pitest/pitest-junit5-plugin", 5)); } return Collections.emptyList(); diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/verify/MissingTestNGPluginVerifierFactory.java b/pitest-entry/src/main/java/org/pitest/mutationtest/verify/MissingTestNGPluginVerifierFactory.java index 39ea6706e..7a5247467 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/verify/MissingTestNGPluginVerifierFactory.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/verify/MissingTestNGPluginVerifierFactory.java @@ -31,12 +31,12 @@ class MissingTestNGPluginVerifier implements BuildVerifier { } @Override - public List verify() { + public List verifyBuild() { if (!testNGPluginIsPresent() && testNGisPresent()) { // log as well as return in case the run is aborted before messages are displayed at the end - String msg = "TestNG is on the classpath but the pitest TestNG plugin is not installed (https://github.com/pitest/pitest-testng-plugin)"; + String msg = "TestNG is on the classpath but the pitest TestNG plugin is not installed."; Log.getLogger().warning(msg); - return asList(msg); + return asList(new BuildIssue(msg, "https://github.com/pitest/pitest-testng-plugin", 5)); } return Collections.emptyList(); diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/verify/SpringVerifierFactory.java b/pitest-entry/src/main/java/org/pitest/mutationtest/verify/SpringVerifierFactory.java index 15ede5364..9aa287235 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/verify/SpringVerifierFactory.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/verify/SpringVerifierFactory.java @@ -29,9 +29,9 @@ class SpringVerifier implements BuildVerifier { } @Override - public List verify() { + public List verifyBuild() { if (springIsOnClassPath() && !springPluginIsPresent()) { - return asList("Project uses Spring, but the Arcmutate Spring plugin is not present (https://docs.arcmutate.com/docs/spring.html)"); + return asList(new BuildIssue("Project uses Spring, but the Arcmutate Spring plugin is not present.", "https://docs.arcmutate.com/docs/spring.html", 4)); } return Collections.emptyList(); From 887a3509e133f882a67f83d3ec8a26916e7c3488 Mon Sep 17 00:00:00 2001 From: Henry Coles Date: Wed, 3 Apr 2024 10:20:21 +0100 Subject: [PATCH 3/5] order and deuplicate build issues --- .../mutationtest/ListenerArguments.java | 6 +++- .../mutationtest/ListenerArgumentsTest.java | 29 +++++++++++++++++++ .../html/MutationHtmlReportListener.java | 1 + 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 pitest-entry/src/test/java/org/pitest/mutationtest/ListenerArgumentsTest.java diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/ListenerArguments.java b/pitest-entry/src/main/java/org/pitest/mutationtest/ListenerArguments.java index 1f8d490bb..a29882a58 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/ListenerArguments.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/ListenerArguments.java @@ -10,6 +10,7 @@ import java.util.Collections; import java.util.List; import java.util.Optional; +import java.util.stream.Collectors; /** * Data passed to the listener MutationResultListener factories for use when @@ -55,7 +56,10 @@ public ListenerArguments(ResultOutputStrategy outputStrategy, this.fullMutationMatrix = fullMutationMatrix; this.data = data; this.setting = setting; - this.issues = issues; + this.issues = issues.stream() + .distinct() + .sorted() + .collect(Collectors.toList()); } public ResultOutputStrategy getOutputStrategy() { diff --git a/pitest-entry/src/test/java/org/pitest/mutationtest/ListenerArgumentsTest.java b/pitest-entry/src/test/java/org/pitest/mutationtest/ListenerArgumentsTest.java new file mode 100644 index 000000000..d9ac6f33d --- /dev/null +++ b/pitest-entry/src/test/java/org/pitest/mutationtest/ListenerArgumentsTest.java @@ -0,0 +1,29 @@ +package org.pitest.mutationtest; + +import org.junit.Test; +import org.pitest.mutationtest.verify.BuildIssue; + +import java.util.List; + +import static java.util.Arrays.asList; +import static org.assertj.core.api.Assertions.assertThat; + +public class ListenerArgumentsTest { + + @Test + public void removesDuplicateBuildIssues() { + List issues = asList(BuildIssue.issue("foo"), BuildIssue.issue("foo")); + ListenerArguments underTest = new ListenerArguments(null, null, null, null, 0, false, null, issues); + assertThat(underTest.issues()).containsExactly(BuildIssue.issue("foo")); + } + + @Test + public void ordersBuildIssuesByPriority() { + BuildIssue a = new BuildIssue("foo", null, 5); + BuildIssue b = new BuildIssue("important", null, 0); + BuildIssue c = new BuildIssue("bar", null, 4); + List issues = asList(a,b,c); + ListenerArguments underTest = new ListenerArguments(null, null, null, null, 0, false, null, issues); + assertThat(underTest.issues()).containsExactly(b, c, a); + } +} \ No newline at end of file diff --git a/pitest-html-report/src/main/java/org/pitest/mutationtest/report/html/MutationHtmlReportListener.java b/pitest-html-report/src/main/java/org/pitest/mutationtest/report/html/MutationHtmlReportListener.java index 542120a70..b5dcacc59 100644 --- a/pitest-html-report/src/main/java/org/pitest/mutationtest/report/html/MutationHtmlReportListener.java +++ b/pitest-html-report/src/main/java/org/pitest/mutationtest/report/html/MutationHtmlReportListener.java @@ -238,6 +238,7 @@ private void createIndexPages() { private List wrap(List issues) { return issues.stream() + .distinct() .sorted() .map(ConvertedIssue::new) .collect(Collectors.toList()); From b10626d951c441e8ad0dad1eb2ee8af9d940689c Mon Sep 17 00:00:00 2001 From: Henry Coles Date: Fri, 5 Apr 2024 09:14:53 +0100 Subject: [PATCH 4/5] expand BuildVerifierFactory args --- .../mutationtest/ListenerArguments.java | 10 +++---- .../tooling/CombinedStatistics.java | 8 +++--- .../mutationtest/tooling/EntryPoint.java | 3 +- .../tooling/MutationCoverage.java | 10 +++---- .../{BuildIssue.java => BuildMessage.java} | 12 ++++---- .../mutationtest/verify/BuildVerifier.java | 4 +-- .../verify/BuildVerifierArguments.java | 23 +++++++++++++++ .../verify/BuildVerifierFactory.java | 9 +++++- .../verify/CompoundBuildVerifierFactory.java | 10 +++---- .../verify/DefaultBuildVerifier.java | 2 +- .../verify/KotlinVerifierFactory.java | 4 +-- .../MissingJUnit5PluginVerifierFactory.java | 4 +-- .../MissingTestNGPluginVerifierFactory.java | 4 +-- .../verify/SpringVerifierFactory.java | 4 +-- .../mutationtest/ListenerArgumentsTest.java | 14 +++++----- ...ldIssueTest.java => BuildMessageTest.java} | 12 ++++---- .../CompoundBuildVerifierFactoryTest.java | 13 +++++---- .../verify/KotlinVerifierFactoryTest.java | 9 +++--- ...issingJUnit5PluginVerifierFactoryTest.java | 6 ++-- ...issingTestNGPluginVerifierFactoryTest.java | 6 ++-- .../verify/SpringVerifierFactoryTest.java | 6 ++-- .../interceptors/BuildVerifierVerifier.java | 8 ++++-- .../html/MutationHtmlReportListener.java | 28 +++++++++---------- .../mutation/mutation_package_index.st | 4 +-- 24 files changed, 122 insertions(+), 91 deletions(-) rename pitest-entry/src/main/java/org/pitest/mutationtest/verify/{BuildIssue.java => BuildMessage.java} (75%) create mode 100644 pitest-entry/src/main/java/org/pitest/mutationtest/verify/BuildVerifierArguments.java rename pitest-entry/src/test/java/org/pitest/mutationtest/verify/{BuildIssueTest.java => BuildMessageTest.java} (62%) diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/ListenerArguments.java b/pitest-entry/src/main/java/org/pitest/mutationtest/ListenerArguments.java index a29882a58..88296dca4 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/ListenerArguments.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/ListenerArguments.java @@ -3,7 +3,7 @@ import org.pitest.coverage.ReportCoverage; import org.pitest.mutationtest.config.ReportOptions; import org.pitest.mutationtest.engine.MutationEngine; -import org.pitest.mutationtest.verify.BuildIssue; +import org.pitest.mutationtest.verify.BuildMessage; import org.pitest.plugin.FeatureSetting; import org.pitest.util.ResultOutputStrategy; @@ -26,7 +26,7 @@ public class ListenerArguments { private final boolean fullMutationMatrix; private final ReportOptions data; private final FeatureSetting setting; - private final List issues; + private final List issues; public ListenerArguments(ResultOutputStrategy outputStrategy, ReportCoverage coverage, @@ -35,7 +35,7 @@ public ListenerArguments(ResultOutputStrategy outputStrategy, long startTime, boolean fullMutationMatrix, ReportOptions data, - List issues) { + List issues) { this(outputStrategy, coverage, locator, engine, startTime, fullMutationMatrix, data, null, issues); } @@ -47,7 +47,7 @@ public ListenerArguments(ResultOutputStrategy outputStrategy, boolean fullMutationMatrix, ReportOptions data, FeatureSetting setting, - List issues) { + List issues) { this.outputStrategy = outputStrategy; this.coverage = coverage; this.locator = locator; @@ -94,7 +94,7 @@ public Optional settings() { return Optional.ofNullable(setting); } - public List issues() { + public List issues() { return Collections.unmodifiableList(issues); } diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/tooling/CombinedStatistics.java b/pitest-entry/src/main/java/org/pitest/mutationtest/tooling/CombinedStatistics.java index 182203075..cecb55876 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/tooling/CombinedStatistics.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/tooling/CombinedStatistics.java @@ -2,7 +2,7 @@ import org.pitest.coverage.CoverageSummary; import org.pitest.mutationtest.statistics.MutationStatistics; -import org.pitest.mutationtest.verify.BuildIssue; +import org.pitest.mutationtest.verify.BuildMessage; import java.util.List; @@ -11,11 +11,11 @@ public class CombinedStatistics { private final MutationStatistics mutationStatistics; private final CoverageSummary coverageSummary; - private final List issues; + private final List issues; public CombinedStatistics(MutationStatistics mutationStatistics, CoverageSummary coverageSummary, - List issues) { + List issues) { this.mutationStatistics = mutationStatistics; this.coverageSummary = coverageSummary; this.issues = issues; @@ -29,7 +29,7 @@ public CoverageSummary getCoverageSummary() { return this.coverageSummary; } - public List getIssues() { + public List getIssues() { return issues; } diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/tooling/EntryPoint.java b/pitest-entry/src/main/java/org/pitest/mutationtest/tooling/EntryPoint.java index e5b6ec305..973aad398 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/tooling/EntryPoint.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/tooling/EntryPoint.java @@ -18,6 +18,7 @@ import org.pitest.mutationtest.incremental.NullHistory; import org.pitest.mutationtest.incremental.NullWriterFactory; import org.pitest.mutationtest.incremental.WriterFactory; +import org.pitest.mutationtest.verify.BuildVerifierArguments; import org.pitest.plugin.Feature; import org.pitest.plugin.FeatureParameter; import org.pitest.plugin.FeatureParser; @@ -127,7 +128,7 @@ public AnalysisResult execute(File baseDir, ReportOptions data, final MutationStrategies strategies = new MutationStrategies( settings.createEngine(), history, coverageDatabase, reportFactory, settings.getResultInterceptor().add(new HistoryResultInterceptor(history)), settings.createCoverageTransformer(code), - reportOutput, settings.createVerifier().create(code)); + reportOutput, settings.createVerifier().create(new BuildVerifierArguments(code, data))); final MutationCoverage report = new MutationCoverage(strategies, baseDir, code, data, settings, timings); diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/tooling/MutationCoverage.java b/pitest-entry/src/main/java/org/pitest/mutationtest/tooling/MutationCoverage.java index 67138bbfe..7547e0105 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/tooling/MutationCoverage.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/tooling/MutationCoverage.java @@ -50,7 +50,7 @@ import org.pitest.mutationtest.statistics.MutationStatistics; import org.pitest.mutationtest.statistics.MutationStatisticsListener; import org.pitest.mutationtest.statistics.Score; -import org.pitest.mutationtest.verify.BuildIssue; +import org.pitest.mutationtest.verify.BuildMessage; import org.pitest.util.Log; import org.pitest.util.StringUtil; import org.pitest.util.Timings; @@ -114,7 +114,7 @@ public CombinedStatistics runReport() throws IOException { final long t0 = System.nanoTime(); - List issues = verifyBuildSuitableForMutationTesting(); + List issues = verifyBuildSuitableForMutationTesting(); checkExcludedRunners(); @@ -143,7 +143,7 @@ private CombinedStatistics emptyStatistics() { return new CombinedStatistics(mutationStatistics, new CoverageSummary(0,0), Collections.emptyList()); } - private CombinedStatistics runAnalysis(Runtime runtime, long t0, EngineArguments args, MutationEngine engine, List issues) { + private CombinedStatistics runAnalysis(Runtime runtime, long t0, EngineArguments args, MutationEngine engine, List issues) { History history = this.strategies.history(); history.initialize(); @@ -255,7 +255,7 @@ private List createConfig(long t0, ReportCoverage coverageData, History history, MutationStatisticsListener stats, - MutationEngine engine, List issues) { + MutationEngine engine, List issues) { final List ls = new ArrayList<>(); ls.add(stats); @@ -280,7 +280,7 @@ private MutationResultInterceptor resultInterceptor() { return this.strategies.resultInterceptor(); } - private List verifyBuildSuitableForMutationTesting() { + private List verifyBuildSuitableForMutationTesting() { return this.strategies.buildVerifier().verifyBuild(); } diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/verify/BuildIssue.java b/pitest-entry/src/main/java/org/pitest/mutationtest/verify/BuildMessage.java similarity index 75% rename from pitest-entry/src/main/java/org/pitest/mutationtest/verify/BuildIssue.java rename to pitest-entry/src/main/java/org/pitest/mutationtest/verify/BuildMessage.java index 1d93fcb2d..60189e7aa 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/verify/BuildIssue.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/verify/BuildMessage.java @@ -2,19 +2,19 @@ import java.util.Objects; -public final class BuildIssue implements Comparable { +public final class BuildMessage implements Comparable { private final String text; private final String url; private final int priority; - public BuildIssue(String text, String url, int priority) { + public BuildMessage(String text, String url, int priority) { this.text = text; this.url = url; this.priority = priority; } - public static BuildIssue issue(String text) { - return new BuildIssue(text, null, 5); + public static BuildMessage buildMessage(String text) { + return new BuildMessage(text, null, 5); } public String text() { @@ -42,7 +42,7 @@ public boolean equals(Object o) { if (o == null || getClass() != o.getClass()) { return false; } - BuildIssue that = (BuildIssue) o; + BuildMessage that = (BuildMessage) o; return priority == that.priority && Objects.equals(text, that.text) && Objects.equals(url, that.url); } @@ -52,7 +52,7 @@ public int hashCode() { } @Override - public int compareTo(BuildIssue o) { + public int compareTo(BuildMessage o) { return Integer.compare(this.priority, o.priority); } } diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/verify/BuildVerifier.java b/pitest-entry/src/main/java/org/pitest/mutationtest/verify/BuildVerifier.java index 9059abc31..7692d41e8 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/verify/BuildVerifier.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/verify/BuildVerifier.java @@ -16,9 +16,9 @@ default List verify() { return Collections.emptyList(); } - default List verifyBuild() { + default List verifyBuild() { return verify().stream() - .map(BuildIssue::issue) + .map(BuildMessage::buildMessage) .collect(Collectors.toList()); } diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/verify/BuildVerifierArguments.java b/pitest-entry/src/main/java/org/pitest/mutationtest/verify/BuildVerifierArguments.java new file mode 100644 index 000000000..487abff5b --- /dev/null +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/verify/BuildVerifierArguments.java @@ -0,0 +1,23 @@ +package org.pitest.mutationtest.verify; + +import org.pitest.classpath.CodeSource; +import org.pitest.mutationtest.config.ReportOptions; + +public class BuildVerifierArguments { + + private final CodeSource code; + private final ReportOptions data; + + public BuildVerifierArguments(CodeSource code, ReportOptions data) { + this.code = code; + this.data = data; + } + + public ReportOptions data() { + return data; + } + + public CodeSource code() { + return code; + } +} diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/verify/BuildVerifierFactory.java b/pitest-entry/src/main/java/org/pitest/mutationtest/verify/BuildVerifierFactory.java index 2f2e13c71..b0f848941 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/verify/BuildVerifierFactory.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/verify/BuildVerifierFactory.java @@ -5,5 +5,12 @@ public interface BuildVerifierFactory extends ToolClasspathPlugin { - BuildVerifier create(CodeSource code); + default BuildVerifier create(BuildVerifierArguments args) { + return create(args.code()); + } + + @Deprecated + default BuildVerifier create(CodeSource code) { + throw new IllegalStateException(); + } } diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/verify/CompoundBuildVerifierFactory.java b/pitest-entry/src/main/java/org/pitest/mutationtest/verify/CompoundBuildVerifierFactory.java index 69d5b5a9f..829c8414f 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/verify/CompoundBuildVerifierFactory.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/verify/CompoundBuildVerifierFactory.java @@ -1,7 +1,5 @@ package org.pitest.mutationtest.verify; -import org.pitest.classpath.CodeSource; - import java.util.List; import java.util.stream.Collectors; @@ -14,15 +12,15 @@ public CompoundBuildVerifierFactory(List verifiers) { } @Override - public BuildVerifier create(CodeSource code) { - List issues = verifiers.stream() - .map(f -> f.create(code)) + public BuildVerifier create(BuildVerifierArguments args) { + List issues = verifiers.stream() + .map(f -> f.create(args)) .flatMap(v -> v.verifyBuild().stream()) .collect(Collectors.toList()); return new BuildVerifier() { @Override - public List verifyBuild() { + public List verifyBuild() { return issues; } }; diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/verify/DefaultBuildVerifier.java b/pitest-entry/src/main/java/org/pitest/mutationtest/verify/DefaultBuildVerifier.java index 168c4a91a..c9067c81a 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/verify/DefaultBuildVerifier.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/verify/DefaultBuildVerifier.java @@ -33,7 +33,7 @@ public DefaultBuildVerifier(CodeSource code) { } @Override - public List verifyBuild() { + public List verifyBuild() { // check we have at least one class that is not an interface // otherwise our checks will fire on an empty project diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/verify/KotlinVerifierFactory.java b/pitest-entry/src/main/java/org/pitest/mutationtest/verify/KotlinVerifierFactory.java index 9d336e456..1f6bded0e 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/verify/KotlinVerifierFactory.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/verify/KotlinVerifierFactory.java @@ -29,9 +29,9 @@ class KotlinVerifier implements BuildVerifier { } @Override - public List verifyBuild() { + public List verifyBuild() { if (kotlinIsOnClassPath() && !kotlinPluginIsPresent() && kotlinClassesToBeMutated()) { - return asList(new BuildIssue("Project uses kotlin, but the Arcmutate kotlin plugin is not present.", "https://docs.arcmutate.com/docs/kotlin.html", 4)); + return asList(new BuildMessage("Project uses kotlin, but the Arcmutate kotlin plugin is not present.", "https://docs.arcmutate.com/docs/kotlin.html", 4)); } return Collections.emptyList(); diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/verify/MissingJUnit5PluginVerifierFactory.java b/pitest-entry/src/main/java/org/pitest/mutationtest/verify/MissingJUnit5PluginVerifierFactory.java index 51f712b3e..e7f822556 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/verify/MissingJUnit5PluginVerifierFactory.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/verify/MissingJUnit5PluginVerifierFactory.java @@ -31,12 +31,12 @@ class MissingJUnit5PluginVerifier implements BuildVerifier { } @Override - public List verifyBuild() { + public List verifyBuild() { if (!junit5PluginIsPresent() && junitJupiterPresent()) { // log as well as return in case the run is aborted before messages are displayed at the end String msg = "JUnit 5 is on the classpath but the pitest junit 5 plugin is not installed."; Log.getLogger().warning(msg); - return asList(new BuildIssue(msg, "https://github.com/pitest/pitest-junit5-plugin", 5)); + return asList(new BuildMessage(msg, "https://github.com/pitest/pitest-junit5-plugin", 5)); } return Collections.emptyList(); diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/verify/MissingTestNGPluginVerifierFactory.java b/pitest-entry/src/main/java/org/pitest/mutationtest/verify/MissingTestNGPluginVerifierFactory.java index 7a5247467..4f1e9fa48 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/verify/MissingTestNGPluginVerifierFactory.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/verify/MissingTestNGPluginVerifierFactory.java @@ -31,12 +31,12 @@ class MissingTestNGPluginVerifier implements BuildVerifier { } @Override - public List verifyBuild() { + public List verifyBuild() { if (!testNGPluginIsPresent() && testNGisPresent()) { // log as well as return in case the run is aborted before messages are displayed at the end String msg = "TestNG is on the classpath but the pitest TestNG plugin is not installed."; Log.getLogger().warning(msg); - return asList(new BuildIssue(msg, "https://github.com/pitest/pitest-testng-plugin", 5)); + return asList(new BuildMessage(msg, "https://github.com/pitest/pitest-testng-plugin", 5)); } return Collections.emptyList(); diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/verify/SpringVerifierFactory.java b/pitest-entry/src/main/java/org/pitest/mutationtest/verify/SpringVerifierFactory.java index 9aa287235..291ef6020 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/verify/SpringVerifierFactory.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/verify/SpringVerifierFactory.java @@ -29,9 +29,9 @@ class SpringVerifier implements BuildVerifier { } @Override - public List verifyBuild() { + public List verifyBuild() { if (springIsOnClassPath() && !springPluginIsPresent()) { - return asList(new BuildIssue("Project uses Spring, but the Arcmutate Spring plugin is not present.", "https://docs.arcmutate.com/docs/spring.html", 4)); + return asList(new BuildMessage("Project uses Spring, but the Arcmutate Spring plugin is not present.", "https://docs.arcmutate.com/docs/spring.html", 4)); } return Collections.emptyList(); diff --git a/pitest-entry/src/test/java/org/pitest/mutationtest/ListenerArgumentsTest.java b/pitest-entry/src/test/java/org/pitest/mutationtest/ListenerArgumentsTest.java index d9ac6f33d..b64b2ec2e 100644 --- a/pitest-entry/src/test/java/org/pitest/mutationtest/ListenerArgumentsTest.java +++ b/pitest-entry/src/test/java/org/pitest/mutationtest/ListenerArgumentsTest.java @@ -1,7 +1,7 @@ package org.pitest.mutationtest; import org.junit.Test; -import org.pitest.mutationtest.verify.BuildIssue; +import org.pitest.mutationtest.verify.BuildMessage; import java.util.List; @@ -12,17 +12,17 @@ public class ListenerArgumentsTest { @Test public void removesDuplicateBuildIssues() { - List issues = asList(BuildIssue.issue("foo"), BuildIssue.issue("foo")); + List issues = asList(BuildMessage.buildMessage("foo"), BuildMessage.buildMessage("foo")); ListenerArguments underTest = new ListenerArguments(null, null, null, null, 0, false, null, issues); - assertThat(underTest.issues()).containsExactly(BuildIssue.issue("foo")); + assertThat(underTest.issues()).containsExactly(BuildMessage.buildMessage("foo")); } @Test public void ordersBuildIssuesByPriority() { - BuildIssue a = new BuildIssue("foo", null, 5); - BuildIssue b = new BuildIssue("important", null, 0); - BuildIssue c = new BuildIssue("bar", null, 4); - List issues = asList(a,b,c); + BuildMessage a = new BuildMessage("foo", null, 5); + BuildMessage b = new BuildMessage("important", null, 0); + BuildMessage c = new BuildMessage("bar", null, 4); + List issues = asList(a,b,c); ListenerArguments underTest = new ListenerArguments(null, null, null, null, 0, false, null, issues); assertThat(underTest.issues()).containsExactly(b, c, a); } diff --git a/pitest-entry/src/test/java/org/pitest/mutationtest/verify/BuildIssueTest.java b/pitest-entry/src/test/java/org/pitest/mutationtest/verify/BuildMessageTest.java similarity index 62% rename from pitest-entry/src/test/java/org/pitest/mutationtest/verify/BuildIssueTest.java rename to pitest-entry/src/test/java/org/pitest/mutationtest/verify/BuildMessageTest.java index 23963c2dd..f97387359 100644 --- a/pitest-entry/src/test/java/org/pitest/mutationtest/verify/BuildIssueTest.java +++ b/pitest-entry/src/test/java/org/pitest/mutationtest/verify/BuildMessageTest.java @@ -10,20 +10,20 @@ import static org.assertj.core.api.Assertions.assertThat; -public class BuildIssueTest { +public class BuildMessageTest { @Test public void obeysHashcodeEqualsContract() { - EqualsVerifier.forClass(BuildIssue.class) + EqualsVerifier.forClass(BuildMessage.class) .verify(); } @Test public void sortsZeroPriorityFirst() { - BuildIssue a = new BuildIssue("a","",10); - BuildIssue b = new BuildIssue("b","",0); - BuildIssue c = new BuildIssue("c","",5); + BuildMessage a = new BuildMessage("a","",10); + BuildMessage b = new BuildMessage("b","",0); + BuildMessage c = new BuildMessage("c","",5); - List l = asList(a,b,c); + List l = asList(a,b,c); Collections.sort(l); assertThat(l).containsExactly(b,c,a); } diff --git a/pitest-entry/src/test/java/org/pitest/mutationtest/verify/CompoundBuildVerifierFactoryTest.java b/pitest-entry/src/test/java/org/pitest/mutationtest/verify/CompoundBuildVerifierFactoryTest.java index 749844370..85d302c30 100644 --- a/pitest-entry/src/test/java/org/pitest/mutationtest/verify/CompoundBuildVerifierFactoryTest.java +++ b/pitest-entry/src/test/java/org/pitest/mutationtest/verify/CompoundBuildVerifierFactoryTest.java @@ -3,6 +3,7 @@ import org.junit.Test; import org.mockito.Mockito; import org.pitest.classpath.CodeSource; +import org.pitest.mutationtest.config.ReportOptions; import java.util.List; import java.util.stream.Collectors; @@ -11,7 +12,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; -import static org.pitest.mutationtest.verify.BuildIssue.issue; +import static org.pitest.mutationtest.verify.BuildMessage.buildMessage; public class CompoundBuildVerifierFactoryTest { @@ -21,13 +22,13 @@ public void returnsResultsFromChildren() { factoryFor(buildVerifier(asList("one"))), factoryFor(buildVerifier(asList("two", "three"))))); - assertThat(underTest.create(aCodeSource()).verifyBuild()) - .containsExactly(issue("one"), issue("two"), issue("three")); + assertThat(underTest.create(new BuildVerifierArguments(aCodeSource(), new ReportOptions())).verifyBuild()) + .containsExactly(buildMessage("one"), buildMessage("two"), buildMessage("three")); } private BuildVerifierFactory factoryFor(BuildVerifier bv) { BuildVerifierFactory vs = Mockito.mock(BuildVerifierFactory.class); - when(vs.create(any(CodeSource.class))).thenReturn(bv); + when(vs.create(any(BuildVerifierArguments.class))).thenReturn(bv); return vs; } @@ -38,9 +39,9 @@ private CodeSource aCodeSource() { private BuildVerifier buildVerifier(List issues) { return new BuildVerifier() { @Override - public List verifyBuild() { + public List verifyBuild() { return issues.stream() - .map(BuildIssue::issue) + .map(BuildMessage::buildMessage) .collect(Collectors.toList()); } diff --git a/pitest-entry/src/test/java/org/pitest/mutationtest/verify/KotlinVerifierFactoryTest.java b/pitest-entry/src/test/java/org/pitest/mutationtest/verify/KotlinVerifierFactoryTest.java index b41f009de..dd28045c4 100644 --- a/pitest-entry/src/test/java/org/pitest/mutationtest/verify/KotlinVerifierFactoryTest.java +++ b/pitest-entry/src/test/java/org/pitest/mutationtest/verify/KotlinVerifierFactoryTest.java @@ -3,7 +3,6 @@ import org.junit.Test; import org.pitest.bytecode.analysis.ClassTree; import org.pitest.classinfo.ClassName; -import org.pitest.classpath.ClassloaderByteArraySource; import org.pitest.verifier.interceptors.BuildVerifierVerifier; import static org.pitest.verifier.interceptors.BuildVerifierVerifier.aValidClass; @@ -22,7 +21,7 @@ public void isOnChain() { @Test public void doesNotDisplayMessageWhenKotlinNotPresent() { v.withCodeSource(codeSourceReturning(ClassName.fromString("not.relevant.Foo"))) - .issues() + .messages() .isEmpty(); } @@ -37,7 +36,7 @@ public void displaysWarningWhenKotlinLibPresentAndKotlinClassesPresent() { clientCode.rawNode().sourceFile = "Foo.kt"; v.withCodeSource(codeSourceForClasses(kotlinMarker, clientCode)) - .issues() + .messages() .isNotEmpty(); } @@ -54,7 +53,7 @@ public void doesNotDisplayWarningWhenPluginPresent() { clientCode.rawNode().sourceFile = "Foo.kt"; v.withCodeSource(codeSourceForClasses(kotlinMarker, interceptor, clientCode)) - .issues() + .messages() .isEmpty(); } @@ -63,7 +62,7 @@ public void doesNotDisplayWarningWhenNoKotlinCodePresent() { v.withCodeSource(codeSourceReturning(ClassName.fromString("kotlin.KotlinVersion"), ClassName.fromString("com.groupcdg.pitest.kotlin.KotlinFilterInterceptor") )) - .issues() + .messages() .isEmpty(); } diff --git a/pitest-entry/src/test/java/org/pitest/mutationtest/verify/MissingJUnit5PluginVerifierFactoryTest.java b/pitest-entry/src/test/java/org/pitest/mutationtest/verify/MissingJUnit5PluginVerifierFactoryTest.java index 60f8d0e05..1bc2c63f7 100644 --- a/pitest-entry/src/test/java/org/pitest/mutationtest/verify/MissingJUnit5PluginVerifierFactoryTest.java +++ b/pitest-entry/src/test/java/org/pitest/mutationtest/verify/MissingJUnit5PluginVerifierFactoryTest.java @@ -18,14 +18,14 @@ public void isOnChain() { @Test public void doesNotDisplayMessageWhenJUnit5NotPresent() { v.withCodeSource(codeSourceReturning(ClassName.fromString("not.relevant.Foo"))) - .issues() + .messages() .isEmpty(); } @Test public void displaysWarningWhenJUnit5PresentWithoutPlugin() { v.withCodeSource(codeSourceReturning(ClassName.fromString("org.junit.jupiter.api.Test"))) - .issues() + .messages() .isNotEmpty(); } @@ -34,7 +34,7 @@ public void doesNotDisplayWarningWhenPluginPresent() { v.withCodeSource(codeSourceReturning(ClassName.fromString("org.junit.jupiter.api.Test"), ClassName.fromString("org.pitest.junit5.JUnit5TestPluginFactory") )) - .issues() + .messages() .isEmpty(); } diff --git a/pitest-entry/src/test/java/org/pitest/mutationtest/verify/MissingTestNGPluginVerifierFactoryTest.java b/pitest-entry/src/test/java/org/pitest/mutationtest/verify/MissingTestNGPluginVerifierFactoryTest.java index ce173373a..d5a087c04 100644 --- a/pitest-entry/src/test/java/org/pitest/mutationtest/verify/MissingTestNGPluginVerifierFactoryTest.java +++ b/pitest-entry/src/test/java/org/pitest/mutationtest/verify/MissingTestNGPluginVerifierFactoryTest.java @@ -17,14 +17,14 @@ public void isOnChain() { @Test public void doesNotDisplayMessageWhenJUnit5NotPresent() { v.withCodeSource(codeSourceReturning(ClassName.fromString("not.relevant.Foo"))) - .issues() + .messages() .isEmpty(); } @Test public void displaysWarningWhenJUnit5PresentWithoutPlugin() { v.withCodeSource(codeSourceReturning(ClassName.fromString("org.testng.annotations.Test"))) - .issues() + .messages() .isNotEmpty(); } @@ -33,7 +33,7 @@ public void doesNotDisplayWarningWhenPluginPresent() { v.withCodeSource(codeSourceReturning(ClassName.fromString("org.testng.annotations.Test"), ClassName.fromString("org.pitest.testng.TestNGPlugin") )) - .issues() + .messages() .isEmpty(); } } \ No newline at end of file diff --git a/pitest-entry/src/test/java/org/pitest/mutationtest/verify/SpringVerifierFactoryTest.java b/pitest-entry/src/test/java/org/pitest/mutationtest/verify/SpringVerifierFactoryTest.java index e3a937354..bb2bc297c 100644 --- a/pitest-entry/src/test/java/org/pitest/mutationtest/verify/SpringVerifierFactoryTest.java +++ b/pitest-entry/src/test/java/org/pitest/mutationtest/verify/SpringVerifierFactoryTest.java @@ -20,7 +20,7 @@ public void isOnChain() { @Test public void doesNotDisplayMessageWhenSpringNotPresent() { v.withCodeSource(codeSourceReturning(ClassName.fromString("not.relevant.Foo"))) - .issues() + .messages() .isEmpty(); } @@ -35,7 +35,7 @@ public void displaysWarningWhenSpringPresentWithoutPlugin() { clientCode.rawNode().sourceFile = "Foo.kt"; v.withCodeSource(codeSourceForClasses(springMarker, clientCode)) - .issues() + .messages() .isNotEmpty(); } @@ -52,7 +52,7 @@ public void doesNotDisplayWarningWhenPluginPresent() { clientCode.rawNode().sourceFile = "Foo.kt"; v.withCodeSource(codeSourceForClasses(springMarker, pluginMarker, clientCode)) - .issues() + .messages() .isEmpty(); } } diff --git a/pitest-entry/src/test/java/org/pitest/verifier/interceptors/BuildVerifierVerifier.java b/pitest-entry/src/test/java/org/pitest/verifier/interceptors/BuildVerifierVerifier.java index 1538bce07..205f257bc 100644 --- a/pitest-entry/src/test/java/org/pitest/verifier/interceptors/BuildVerifierVerifier.java +++ b/pitest-entry/src/test/java/org/pitest/verifier/interceptors/BuildVerifierVerifier.java @@ -13,7 +13,9 @@ import org.pitest.classpath.PathFilter; import org.pitest.classpath.ProjectClassPaths; import org.pitest.mutationtest.config.PluginServices; -import org.pitest.mutationtest.verify.BuildIssue; +import org.pitest.mutationtest.config.ReportOptions; +import org.pitest.mutationtest.verify.BuildMessage; +import org.pitest.mutationtest.verify.BuildVerifierArguments; import org.pitest.mutationtest.verify.BuildVerifierFactory; import java.io.ByteArrayInputStream; @@ -49,8 +51,8 @@ public void isOnChain() { factoryIsOnChain(factory.getClass()); } - public ListAssert issues() { - return assertThat(factory.create(codeSource).verifyBuild()); + public ListAssert messages() { + return assertThat(factory.create(new BuildVerifierArguments(codeSource, new ReportOptions())).verifyBuild()); } public BuildVerifierVerifier withCodeSource(CodeSource source) { diff --git a/pitest-html-report/src/main/java/org/pitest/mutationtest/report/html/MutationHtmlReportListener.java b/pitest-html-report/src/main/java/org/pitest/mutationtest/report/html/MutationHtmlReportListener.java index b5dcacc59..f7b57a804 100644 --- a/pitest-html-report/src/main/java/org/pitest/mutationtest/report/html/MutationHtmlReportListener.java +++ b/pitest-html-report/src/main/java/org/pitest/mutationtest/report/html/MutationHtmlReportListener.java @@ -21,7 +21,7 @@ import org.pitest.mutationtest.ClassMutationResults; import org.pitest.mutationtest.MutationResultListener; import org.pitest.mutationtest.SourceLocator; -import org.pitest.mutationtest.verify.BuildIssue; +import org.pitest.mutationtest.verify.BuildMessage; import org.pitest.util.FileUtil; import org.pitest.util.IsolationUtils; import org.pitest.util.Log; @@ -59,14 +59,14 @@ public class MutationHtmlReportListener implements MutationResultListener { private final Charset outputCharset; private final boolean reportCoverage; - private final List issues; + private final List messages; public MutationHtmlReportListener(Charset outputCharset, ReportCoverage coverage, ResultOutputStrategy outputStrategy, Collection mutatorNames, boolean reportCoverage, - List issues, + List messages, SourceLocator... locators) { this.outputCharset = outputCharset; this.coverage = coverage; @@ -75,7 +75,7 @@ public MutationHtmlReportListener(Charset outputCharset, this.mutatorNames = new HashSet<>(mutatorNames); this.css = loadCss(); this.reportCoverage = reportCoverage; - this.issues = issues; + this.messages = messages; } private String loadCss() { @@ -226,7 +226,7 @@ private void createIndexPages() { st.setAttribute("packageSummaries", psd); st.setAttribute("outputCharset", this.outputCharset); st.setAttribute("showCoverage", this.reportCoverage); - st.setAttribute("issues", wrap(this.issues)); + st.setAttribute("messages", wrap(this.messages)); try { writer.write(st.toString()); writer.close(); @@ -236,11 +236,11 @@ private void createIndexPages() { } - private List wrap(List issues) { - return issues.stream() + private List wrap(List messages) { + return messages.stream() .distinct() .sorted() - .map(ConvertedIssue::new) + .map(ConvertedMessage::new) .collect(Collectors.toList()); } @@ -287,18 +287,18 @@ public void handleMutationResult(final ClassMutationResults metaData) { } // wrapper providing StringTemplate friendly accessors -class ConvertedIssue { - private final BuildIssue issue; - ConvertedIssue(BuildIssue issue) { - this.issue = issue; +class ConvertedMessage { + private final BuildMessage message; + ConvertedMessage(BuildMessage message) { + this.message = message; } public String getText() { - return issue.text(); + return message.text(); } public String getUrl() { - return issue.url(); + return message.url(); } } \ No newline at end of file diff --git a/pitest-html-report/src/main/resources/templates/mutation/mutation_package_index.st b/pitest-html-report/src/main/resources/templates/mutation/mutation_package_index.st index 185978e8b..d6dadfbcb 100644 --- a/pitest-html-report/src/main/resources/templates/mutation/mutation_package_index.st +++ b/pitest-html-report/src/main/resources/templates/mutation/mutation_package_index.st @@ -70,8 +70,8 @@ $errors : { error |
From e52d86c2898b854e03eb926140ab0f5328a45109 Mon Sep 17 00:00:00 2001 From: Henry Coles Date: Mon, 8 Apr 2024 10:51:10 +0100 Subject: [PATCH 5/5] hide arcmutate link when installed --- .../java/org/pitest/aggregate/ReportAggregator.java | 1 + .../pitest/mutationtest/config/ReportOptions.java | 12 +++++++++++- .../mutationtest/tooling/MutationCoverage.java | 4 ++-- .../org/pitest/mutationtest/verify/BuildMessage.java | 4 +++- .../pitest/mutationtest/verify/BuildMessageTest.java | 12 ++++++++++++ .../mutationtest/report/html/HtmlReportFactory.java | 2 +- .../report/html/MutationHtmlReportListener.java | 5 +++++ .../templates/mutation/mutation_package_index.st | 7 +++++-- .../report/html/MutationHtmlReportListenerTest.java | 2 +- 9 files changed, 41 insertions(+), 8 deletions(-) diff --git a/pitest-aggregator/src/main/java/org/pitest/aggregate/ReportAggregator.java b/pitest-aggregator/src/main/java/org/pitest/aggregate/ReportAggregator.java index 3a43f8393..4a684e351 100644 --- a/pitest-aggregator/src/main/java/org/pitest/aggregate/ReportAggregator.java +++ b/pitest-aggregator/src/main/java/org/pitest/aggregate/ReportAggregator.java @@ -123,6 +123,7 @@ private MutationResultListener createResultListener(SourceLocator sourceLocator, mutatorNames, partialCoverage, Collections.emptyList(), + true, sourceLocator); } diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/config/ReportOptions.java b/pitest-entry/src/main/java/org/pitest/mutationtest/config/ReportOptions.java index c35927a3b..723eaf20d 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/config/ReportOptions.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/config/ReportOptions.java @@ -151,6 +151,8 @@ public class ReportOptions { private Charset inputEncoding; private Charset outputEncoding; + private boolean arcmutateMissing = true; + // currently used only via maven private Map environmentVariables = new HashMap<>(); @@ -666,6 +668,14 @@ public Map getEnvironmentVariables() { return environmentVariables; } + public boolean isArcmutateMissing() { + return arcmutateMissing; + } + + public void setArcmutateMissing(boolean arcmutateMissing) { + this.arcmutateMissing = arcmutateMissing; + } + @Override public String toString() { return new StringJoiner(", ", ReportOptions.class.getSimpleName() + "[", "]") @@ -714,8 +724,8 @@ public String toString() { .add("inputEncoding=" + inputEncoding) .add("outputEncoding=" + outputEncoding) .add("reportCoverage=" + reportCoverage) + .add("arcmutateMissing=" + arcmutateMissing) .toString(); } - } diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/tooling/MutationCoverage.java b/pitest-entry/src/main/java/org/pitest/mutationtest/tooling/MutationCoverage.java index 7547e0105..2529233d0 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/tooling/MutationCoverage.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/tooling/MutationCoverage.java @@ -315,8 +315,8 @@ private void printStats(CombinedStatistics combinedStatistics) { if (!combinedStatistics.getIssues().isEmpty()) { ps.println(); - ps.println("!! The following issues were detected during the run !!"); - combinedStatistics.getIssues().forEach(ps::println); + ps.println("Build messages:- "); + combinedStatistics.getIssues().forEach(m -> ps.println("* " + m)); } } diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/verify/BuildMessage.java b/pitest-entry/src/main/java/org/pitest/mutationtest/verify/BuildMessage.java index 60189e7aa..c6370c532 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/verify/BuildMessage.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/verify/BuildMessage.java @@ -1,6 +1,7 @@ package org.pitest.mutationtest.verify; import java.util.Objects; +import java.util.Optional; public final class BuildMessage implements Comparable { private final String text; @@ -31,7 +32,8 @@ public int priority() { @Override public String toString() { - return text + " (" + url + ")"; + return text + Optional.ofNullable(url) + .map( u -> " (" + u + ")").orElse(""); } @Override diff --git a/pitest-entry/src/test/java/org/pitest/mutationtest/verify/BuildMessageTest.java b/pitest-entry/src/test/java/org/pitest/mutationtest/verify/BuildMessageTest.java index f97387359..c12657e8a 100644 --- a/pitest-entry/src/test/java/org/pitest/mutationtest/verify/BuildMessageTest.java +++ b/pitest-entry/src/test/java/org/pitest/mutationtest/verify/BuildMessageTest.java @@ -27,4 +27,16 @@ public void sortsZeroPriorityFirst() { Collections.sort(l); assertThat(l).containsExactly(b,c,a); } + + @Test + public void includesURLInToStringWhenPresent() { + BuildMessage underTest = new BuildMessage("text", "https://pitest.org", 0); + assertThat(underTest.toString()).isEqualTo("text (https://pitest.org)"); + } + + @Test + public void doesNotIncludeURLInToStringWhenNull() { + BuildMessage underTest = new BuildMessage("text", null, 0); + assertThat(underTest.toString()).isEqualTo("text"); + } } \ No newline at end of file diff --git a/pitest-html-report/src/main/java/org/pitest/mutationtest/report/html/HtmlReportFactory.java b/pitest-html-report/src/main/java/org/pitest/mutationtest/report/html/HtmlReportFactory.java index 3745f7c66..0802fe0ed 100644 --- a/pitest-html-report/src/main/java/org/pitest/mutationtest/report/html/HtmlReportFactory.java +++ b/pitest-html-report/src/main/java/org/pitest/mutationtest/report/html/HtmlReportFactory.java @@ -28,7 +28,7 @@ public MutationResultListener getListener(Properties props, ListenerArguments args) { return new MutationHtmlReportListener(args.data().getOutputEncoding(), args.getCoverage(), args.getOutputStrategy(), args.getEngine().getMutatorNames(), args.data().shouldReportCoverage(), - args.issues(), args.getLocator()); + args.issues(), args.data().isArcmutateMissing(), args.getLocator()); } @Override diff --git a/pitest-html-report/src/main/java/org/pitest/mutationtest/report/html/MutationHtmlReportListener.java b/pitest-html-report/src/main/java/org/pitest/mutationtest/report/html/MutationHtmlReportListener.java index f7b57a804..f76b2dcad 100644 --- a/pitest-html-report/src/main/java/org/pitest/mutationtest/report/html/MutationHtmlReportListener.java +++ b/pitest-html-report/src/main/java/org/pitest/mutationtest/report/html/MutationHtmlReportListener.java @@ -61,12 +61,15 @@ public class MutationHtmlReportListener implements MutationResultListener { private final List messages; + private final boolean arcmutateMissing; + public MutationHtmlReportListener(Charset outputCharset, ReportCoverage coverage, ResultOutputStrategy outputStrategy, Collection mutatorNames, boolean reportCoverage, List messages, + boolean arcmutateMissing, SourceLocator... locators) { this.outputCharset = outputCharset; this.coverage = coverage; @@ -76,6 +79,7 @@ public MutationHtmlReportListener(Charset outputCharset, this.css = loadCss(); this.reportCoverage = reportCoverage; this.messages = messages; + this.arcmutateMissing = arcmutateMissing; } private String loadCss() { @@ -227,6 +231,7 @@ private void createIndexPages() { st.setAttribute("outputCharset", this.outputCharset); st.setAttribute("showCoverage", this.reportCoverage); st.setAttribute("messages", wrap(this.messages)); + st.setAttribute("arcmutateMissing", arcmutateMissing); try { writer.write(st.toString()); writer.close(); diff --git a/pitest-html-report/src/main/resources/templates/mutation/mutation_package_index.st b/pitest-html-report/src/main/resources/templates/mutation/mutation_package_index.st index d6dadfbcb..efacb9020 100644 --- a/pitest-html-report/src/main/resources/templates/mutation/mutation_package_index.st +++ b/pitest-html-report/src/main/resources/templates/mutation/mutation_package_index.st @@ -71,7 +71,9 @@ $errors : { error | @@ -80,7 +82,8 @@ Report generated by PIT ${project.version}

-Enhanced functionality available at arcmutate.com +$if(arcmutateMissing)$ Enhanced functionality available at arcmutate.com +$endif$ \ No newline at end of file diff --git a/pitest-html-report/src/test/java/org/pitest/mutationtest/report/html/MutationHtmlReportListenerTest.java b/pitest-html-report/src/test/java/org/pitest/mutationtest/report/html/MutationHtmlReportListenerTest.java index 335fdc190..47e6998b9 100644 --- a/pitest-html-report/src/test/java/org/pitest/mutationtest/report/html/MutationHtmlReportListenerTest.java +++ b/pitest-html-report/src/test/java/org/pitest/mutationtest/report/html/MutationHtmlReportListenerTest.java @@ -69,7 +69,7 @@ public void setUp() { this.classInfo); this.testee = new MutationHtmlReportListener(StandardCharsets.UTF_8, this.coverageDb, - this.outputStrategy, Collections.emptyList(), true, Collections.emptyList(), this.sourceLocator); + this.outputStrategy, Collections.emptyList(), true, Collections.emptyList(), true, this.sourceLocator); } @Test