From 6c95a223357eb276a305d50705c04e08da7a29c5 Mon Sep 17 00:00:00 2001 From: vivganes Date: Tue, 13 Aug 2024 19:17:34 +0530 Subject: [PATCH] show coveredTests in report on click --- .../aggregate/MutationResultDataLoader.java | 2 +- .../pitest/mutationtest/MutationResult.java | 8 ++++- .../mutationtest/MutationStatusMap.java | 30 +++++------------ .../pitest/mutationtest/execute/Receive.java | 2 +- .../incremental/IncrementalAnalyser.java | 3 +- .../report/xml/XMLReportListener.java | 33 ++++++++++--------- .../mutationtest/MutationMetaDataTest.java | 2 +- .../mutationtest/MutationResultTest.java | 6 ++-- .../mutationtest/MutationStatusMapTest.java | 5 +-- .../build/MutationTestUnitTest.java | 3 +- .../HistoryResultInterceptorTest.java | 3 +- .../incremental/IncrementalAnalyserTest.java | 6 ++-- .../report/MutationTestResultMother.java | 2 +- .../report/csv/CSVReportListenerTest.java | 3 +- .../report/xml/XMLReportListenerTest.java | 7 ++-- .../templates/mutation/mutation_report.st | 8 +++-- .../resources/templates/mutation/style.css | 11 +++++++ .../report/html/ResultComparatorTest.java | 3 +- .../mutationtest/MutationStatusTestPair.java | 21 ++++++++---- .../execute/MutationTestWorker.java | 14 +++++--- .../execute/MutationTestWorkerTest.java | 10 +++--- 21 files changed, 106 insertions(+), 76 deletions(-) diff --git a/pitest-aggregator/src/main/java/org/pitest/aggregate/MutationResultDataLoader.java b/pitest-aggregator/src/main/java/org/pitest/aggregate/MutationResultDataLoader.java index d62570693..54955cb04 100644 --- a/pitest-aggregator/src/main/java/org/pitest/aggregate/MutationResultDataLoader.java +++ b/pitest-aggregator/src/main/java/org/pitest/aggregate/MutationResultDataLoader.java @@ -57,7 +57,7 @@ private MutationResult xmlToResult(MutationXml xml) { return new MutationResult(new MutationDetails(id, xml.sourceFile, xml.description, xml.lineNumber, xml.blocks), - new MutationStatusTestPair(xml.numberOfTestsRun, DetectionStatus.valueOf(xml.status), Arrays.asList(killingTests), Arrays.asList(succeedingTests))); + new MutationStatusTestPair(xml.numberOfTestsRun, DetectionStatus.valueOf(xml.status), Arrays.asList(killingTests), Arrays.asList(succeedingTests), Arrays.asList(succeedingTests))); } } diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/MutationResult.java b/pitest-entry/src/main/java/org/pitest/mutationtest/MutationResult.java index ce3593e09..9a780d183 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/MutationResult.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/MutationResult.java @@ -18,7 +18,6 @@ import java.util.Objects; import java.util.Optional; import org.pitest.mutationtest.engine.MutationDetails; - public final class MutationResult { private final MutationDetails details; @@ -30,6 +29,9 @@ public MutationResult(final MutationDetails md, this.status = status; } + public String getId() { + return this.details.getId().toString().replace(" ","-"); + } public MutationDetails getDetails() { return this.details; } @@ -46,6 +48,10 @@ public List getSucceedingTests() { return this.status.getSucceedingTests(); } + public List getCoveringTests() { + return this.status.getCoveringTests(); + } + public DetectionStatus getStatus() { return this.status.getStatus(); } diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/MutationStatusMap.java b/pitest-entry/src/main/java/org/pitest/mutationtest/MutationStatusMap.java index 25c03c7b4..7ab81fb01 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/MutationStatusMap.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/MutationStatusMap.java @@ -14,17 +14,14 @@ */ package org.pitest.mutationtest; -import static org.pitest.functional.prelude.Prelude.putToMap; -import static org.pitest.mutationtest.DetectionStatus.SURVIVED; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Set; -import java.util.ArrayList; -import java.util.Collection; import java.util.Map.Entry; +import java.util.Set; import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -44,27 +41,16 @@ public void setStatusForMutation(final MutationDetails mutation, public void setStatusForMutation(final MutationDetails mutation, final MutationStatusTestPair status) { - MutationStatusTestPair finalStatus = status; - if (status.getStatus().equals(SURVIVED)) { - - List testsInOrder = mutation.getTestsInOrder(); - List passingTests = new ArrayList<>(); - for (TestInfo test : testsInOrder) { - passingTests.add(test.getName()); - } - finalStatus = new MutationStatusTestPair(status.getNumberOfTestsRun(), - status.getStatus(), - status.getKillingTests(), - passingTests); - - } - this.mutationMap.put(mutation, finalStatus); + this.mutationMap.put(mutation, status); } - public void setStatusForMutations( final Collection mutations, final DetectionStatus status) { - mutations.forEach(putToMap(this.mutationMap, MutationStatusTestPair.notAnalysed(0, status))); + mutations.forEach(mutationDetails -> { + List coveringTests = mutationDetails.getTestsInOrder().stream().map(TestInfo::getName).collect(Collectors.toList()); + MutationStatusTestPair pair = MutationStatusTestPair.notAnalysed(0, status, coveringTests); + mutationMap.put(mutationDetails, pair); + }); } public List createMutationResults() { diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/execute/Receive.java b/pitest-entry/src/main/java/org/pitest/mutationtest/execute/Receive.java index e6c62c083..1d5446d10 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/execute/Receive.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/execute/Receive.java @@ -45,7 +45,7 @@ private void handleReport(final SafeDataInputStream is) { private void handleDescribe(final SafeDataInputStream is) { final MutationIdentifier mutation = is.read(MutationIdentifier.class); this.idMap.put(mutation, MutationStatusTestPair.notAnalysed(1, - DetectionStatus.STARTED)); + DetectionStatus.STARTED,null)); } } \ No newline at end of file diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/incremental/IncrementalAnalyser.java b/pitest-entry/src/main/java/org/pitest/mutationtest/incremental/IncrementalAnalyser.java index 87f6ca191..57f0d8ef9 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/incremental/IncrementalAnalyser.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/incremental/IncrementalAnalyser.java @@ -161,7 +161,8 @@ private MutationResult makeResult(final MutationDetails each, final List succeedingTests) { updatePreanalysedTotal(status); return new MutationResult(each, new MutationStatusTestPair(0, status, - killingTests, succeedingTests)); + killingTests, succeedingTests, each.getTestsInOrder().stream() + .map(TestInfo::getName).collect(Collectors.toList()))); } private void updatePreanalysedTotal(final DetectionStatus status) { diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/report/xml/XMLReportListener.java b/pitest-entry/src/main/java/org/pitest/mutationtest/report/xml/XMLReportListener.java index fb88bd96c..3340ec879 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/report/xml/XMLReportListener.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/report/xml/XMLReportListener.java @@ -14,8 +14,23 @@ */ package org.pitest.mutationtest.report.xml; +import java.io.IOException; +import java.io.Writer; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +import org.apache.commons.text.StringEscapeUtils; +import org.pitest.mutationtest.ClassMutationResults; +import org.pitest.mutationtest.MutationResult; +import org.pitest.mutationtest.MutationResultListener; +import org.pitest.mutationtest.engine.MutationDetails; +import org.pitest.util.ResultOutputStrategy; +import org.pitest.util.Unchecked; + import static org.pitest.mutationtest.report.xml.Tag.block; import static org.pitest.mutationtest.report.xml.Tag.blocks; +import static org.pitest.mutationtest.report.xml.Tag.coveringTests; import static org.pitest.mutationtest.report.xml.Tag.description; import static org.pitest.mutationtest.report.xml.Tag.index; import static org.pitest.mutationtest.report.xml.Tag.indexes; @@ -30,22 +45,8 @@ import static org.pitest.mutationtest.report.xml.Tag.sourceFile; import static org.pitest.mutationtest.report.xml.Tag.succeedingTests; -import java.io.IOException; -import java.io.Writer; -import java.util.Arrays; -import java.util.List; -import java.util.Optional; - -import org.apache.commons.text.StringEscapeUtils; -import org.pitest.mutationtest.ClassMutationResults; -import org.pitest.mutationtest.MutationResult; -import org.pitest.mutationtest.MutationResultListener; -import org.pitest.mutationtest.engine.MutationDetails; -import org.pitest.util.ResultOutputStrategy; -import org.pitest.util.Unchecked; - enum Tag { - mutation, sourceFile, mutatedClass, mutatedMethod, methodDescription, lineNumber, mutator, indexes, index, killingTest, killingTests, succeedingTests, description, blocks, block + mutation, sourceFile, mutatedClass, mutatedMethod, methodDescription, lineNumber, mutator, indexes, index, killingTest, killingTests, succeedingTests, coveringTests, description, blocks, block } public class XMLReportListener implements MutationResultListener { @@ -101,6 +102,8 @@ private String makeMutationNode(final MutationResult mutation) { createTestDesc(mutation.getKillingTests()), killingTests) + makeNodeWhenConditionSatisfied(fullMutationMatrix, createTestDesc(mutation.getSucceedingTests()), succeedingTests) + + makeNodeWhenConditionSatisfied(fullMutationMatrix, + createTestDesc(mutation.getCoveringTests()), coveringTests) + makeNode(clean(details.getDescription()), description); } diff --git a/pitest-entry/src/test/java/org/pitest/mutationtest/MutationMetaDataTest.java b/pitest-entry/src/test/java/org/pitest/mutationtest/MutationMetaDataTest.java index a459bb5a4..08b08d639 100644 --- a/pitest-entry/src/test/java/org/pitest/mutationtest/MutationMetaDataTest.java +++ b/pitest-entry/src/test/java/org/pitest/mutationtest/MutationMetaDataTest.java @@ -59,7 +59,7 @@ private MutationResult makeResult(String clazz, String method) { final MutationDetails md = aMutationDetail().withId( aMutationId().withLocation(location)).build(); return new MutationResult(md, - MutationStatusTestPair.notAnalysed(0, DetectionStatus.KILLED)); + MutationStatusTestPair.notAnalysed(0, DetectionStatus.KILLED,Collections.emptyList())); } } diff --git a/pitest-entry/src/test/java/org/pitest/mutationtest/MutationResultTest.java b/pitest-entry/src/test/java/org/pitest/mutationtest/MutationResultTest.java index a12d67c0d..9888ef29c 100644 --- a/pitest-entry/src/test/java/org/pitest/mutationtest/MutationResultTest.java +++ b/pitest-entry/src/test/java/org/pitest/mutationtest/MutationResultTest.java @@ -20,6 +20,8 @@ import nl.jqno.equalsverifier.EqualsVerifier; +import java.util.Collections; + public class MutationResultTest { private MutationResult testee; @@ -34,14 +36,14 @@ public void shouldReturnNameOfKillingTestWhenKnown() { @Test public void shouldNoneWhenNoKillingTest() { this.testee = new MutationResult(null, MutationStatusTestPair.notAnalysed(1, - DetectionStatus.TIMED_OUT)); + DetectionStatus.TIMED_OUT, Collections.emptyList())); assertEquals("none", this.testee.getKillingTestDescription()); } @Test public void shouldReturnStatusDescription() { this.testee = new MutationResult(null, MutationStatusTestPair.notAnalysed(1, - DetectionStatus.TIMED_OUT)); + DetectionStatus.TIMED_OUT,Collections.emptyList())); assertEquals("TIMED_OUT", this.testee.getStatusDescription()); } diff --git a/pitest-entry/src/test/java/org/pitest/mutationtest/MutationStatusMapTest.java b/pitest-entry/src/test/java/org/pitest/mutationtest/MutationStatusMapTest.java index f82d34022..154aff2f8 100644 --- a/pitest-entry/src/test/java/org/pitest/mutationtest/MutationStatusMapTest.java +++ b/pitest-entry/src/test/java/org/pitest/mutationtest/MutationStatusMapTest.java @@ -105,12 +105,13 @@ public void shouldCreateResultsForAllMutations() { @Test public void shouldCreateResultsForSurvivedMutations(){ final MutationStatusTestPair statusPairOne = new MutationStatusTestPair(42, - DetectionStatus.SURVIVED, "foo"); + DetectionStatus.SURVIVED, Collections.singletonList("foo"),Arrays.asList("foo1","bar"), Arrays.asList("foo","foo1","bar")); this.testee.setStatusForMutation(this.aSurvivedMutationDetails, statusPairOne); assertEquals(DetectionStatus.SURVIVED, this.testee.createMutationResults().get(0).getStatus()); assertThat(this.testee.createMutationResults().get(0).getKillingTests()).contains("foo"); - assertThat(this.testee.createMutationResults().get(0).getSucceedingTests()).contains("foo","bar"); + assertThat(this.testee.createMutationResults().get(0).getSucceedingTests()).contains("foo1","bar"); + assertThat(this.testee.createMutationResults().get(0).getCoveringTests()).contains("foo","foo1","bar"); } diff --git a/pitest-entry/src/test/java/org/pitest/mutationtest/build/MutationTestUnitTest.java b/pitest-entry/src/test/java/org/pitest/mutationtest/build/MutationTestUnitTest.java index 28a262844..d950a9aee 100644 --- a/pitest-entry/src/test/java/org/pitest/mutationtest/build/MutationTestUnitTest.java +++ b/pitest-entry/src/test/java/org/pitest/mutationtest/build/MutationTestUnitTest.java @@ -5,6 +5,7 @@ import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.List; import org.junit.Before; @@ -63,7 +64,7 @@ public void shouldReportWhenMutationsNotCoveredByAnyTest() throws Exception { this.tests.add(ClassName.fromString("foo")); final MutationMetaData actual = this.testee.call(); final MutationResult expected = new MutationResult(this.mutations.get(0), - MutationStatusTestPair.notAnalysed(0, DetectionStatus.NO_COVERAGE)); + MutationStatusTestPair.notAnalysed(0, DetectionStatus.NO_COVERAGE, Collections.emptyList())); assertThat(actual.getMutations()).contains(expected); } diff --git a/pitest-entry/src/test/java/org/pitest/mutationtest/incremental/HistoryResultInterceptorTest.java b/pitest-entry/src/test/java/org/pitest/mutationtest/incremental/HistoryResultInterceptorTest.java index ddfb231eb..d99ec4950 100644 --- a/pitest-entry/src/test/java/org/pitest/mutationtest/incremental/HistoryResultInterceptorTest.java +++ b/pitest-entry/src/test/java/org/pitest/mutationtest/incremental/HistoryResultInterceptorTest.java @@ -13,6 +13,7 @@ import org.pitest.mutationtest.report.MutationTestResultMother; import java.util.Collection; +import java.util.Collections; import static java.util.Arrays.asList; import static org.assertj.core.api.Assertions.assertThat; @@ -37,7 +38,7 @@ public void recordsMutationResults() { private MutationResult makeResult() { return new MutationResult( MutationTestResultMother.createDetails(), MutationStatusTestPair.notAnalysed(0, - DetectionStatus.KILLED)); + DetectionStatus.KILLED, Collections.emptyList())); } } \ No newline at end of file diff --git a/pitest-entry/src/test/java/org/pitest/mutationtest/incremental/IncrementalAnalyserTest.java b/pitest-entry/src/test/java/org/pitest/mutationtest/incremental/IncrementalAnalyserTest.java index ded47ea8b..5bdecc776 100644 --- a/pitest-entry/src/test/java/org/pitest/mutationtest/incremental/IncrementalAnalyserTest.java +++ b/pitest-entry/src/test/java/org/pitest/mutationtest/incremental/IncrementalAnalyserTest.java @@ -306,6 +306,7 @@ public void assessMultipleMutationsAtATime() { 0, KILLED, singletonList(killingTest), + emptyList(), emptyList()))); when(this.history.getPreviousResult(md2.getId())) @@ -314,11 +315,12 @@ public void assessMultipleMutationsAtATime() { 0, KILLED, singletonList(killingTest), + emptyList(), emptyList()))); when(this.history.getPreviousResult(md3.getId())) .thenReturn(Optional.of( - new MutationStatusTestPair(0, SURVIVED, emptyList(), emptyList()))); + new MutationStatusTestPair(0, SURVIVED, emptyList(), emptyList(),emptyList()))); when(this.history.getPreviousResult(md4.getId())) .thenReturn(Optional.empty()); @@ -414,7 +416,7 @@ private void setHistoryForAllMutationsTo(final DetectionStatus status, final String... test) { when(this.history.getPreviousResult(any(MutationIdentifier.class))) .thenReturn(Optional.of( - new MutationStatusTestPair(0, status, asList(test), emptyList()))); + new MutationStatusTestPair(0, status, asList(test), emptyList(), emptyList()))); } private static class LogCatcher extends Handler { diff --git a/pitest-entry/src/test/java/org/pitest/mutationtest/report/MutationTestResultMother.java b/pitest-entry/src/test/java/org/pitest/mutationtest/report/MutationTestResultMother.java index 5fc87184c..0e9851a3f 100644 --- a/pitest-entry/src/test/java/org/pitest/mutationtest/report/MutationTestResultMother.java +++ b/pitest-entry/src/test/java/org/pitest/mutationtest/report/MutationTestResultMother.java @@ -46,7 +46,7 @@ public interface MutationTestResultBuilder extends SequenceBuilder seed() { diff --git a/pitest-entry/src/test/java/org/pitest/mutationtest/report/csv/CSVReportListenerTest.java b/pitest-entry/src/test/java/org/pitest/mutationtest/report/csv/CSVReportListenerTest.java index 152cab752..17d3d17e9 100644 --- a/pitest-entry/src/test/java/org/pitest/mutationtest/report/csv/CSVReportListenerTest.java +++ b/pitest-entry/src/test/java/org/pitest/mutationtest/report/csv/CSVReportListenerTest.java @@ -18,6 +18,7 @@ import java.io.IOException; import java.io.Writer; +import java.util.Collections; import org.junit.Before; import org.junit.Test; @@ -71,7 +72,7 @@ public void shouldQuoteKillingTestWhenNeeded() throws IOException { public void shouldOutputNoneWhenNoKillingTestFound() throws IOException { final MutationResult mr = new MutationResult( MutationTestResultMother.createDetails(), MutationStatusTestPair.notAnalysed(1, - DetectionStatus.SURVIVED)); + DetectionStatus.SURVIVED, Collections.emptyList())); this.testee.handleMutationResult(MutationTestResultMother .createClassResults(mr)); final String expected = "file,clazz,mutator,method,42,SURVIVED,none" diff --git a/pitest-entry/src/test/java/org/pitest/mutationtest/report/xml/XMLReportListenerTest.java b/pitest-entry/src/test/java/org/pitest/mutationtest/report/xml/XMLReportListenerTest.java index 8408d4687..e1227f489 100644 --- a/pitest-entry/src/test/java/org/pitest/mutationtest/report/xml/XMLReportListenerTest.java +++ b/pitest-entry/src/test/java/org/pitest/mutationtest/report/xml/XMLReportListenerTest.java @@ -25,6 +25,7 @@ import java.io.StringWriter; import java.io.Writer; import java.util.Arrays; +import java.util.List; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; @@ -64,12 +65,12 @@ public void shouldOutputFullMutationMatrixWhenEnabled() { 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"))); + new MutationStatusTestPair(3, DetectionStatus.KILLED, Arrays.asList("foo", "foo2"), Arrays.asList("bar"), Arrays.asList("foo","foo2","bar"))); this.testee .handleMutationResult(MutationTestResultMother.createClassResults(mr)); final String expected = "file" + "clazzmethod()I42mutator" + - "10foo|foo2bardesc\n"; + "10foo|foo2barfoo|foo2|bardesc\n"; assertThat(expected).isEqualTo(this.out.toString()); } @@ -110,7 +111,7 @@ public void shouldOutputNoneWhenNoKillingTestFound() throws IOException { private MutationResult createSurvivingMutant() { return new MutationResult( MutationTestResultMother.createDetails(), - MutationStatusTestPair.notAnalysed(1, DetectionStatus.SURVIVED)); + MutationStatusTestPair.notAnalysed(1, DetectionStatus.SURVIVED,Arrays.asList("foo","bar"))); } } diff --git a/pitest-html-report/src/main/resources/templates/mutation/mutation_report.st b/pitest-html-report/src/main/resources/templates/mutation/mutation_report.st index 7faae3549..8df588636 100644 --- a/pitest-html-report/src/main/resources/templates/mutation/mutation_report.st +++ b/pitest-html-report/src/main/resources/templates/mutation/mutation_report.st @@ -44,12 +44,14 @@ $sourceFile.groups:{ group | $group.mutations: { mutation |

$i$.$i$
Location : $mutation.details.location$
Killed by : $mutation.killingTestDescription$
$mutation.details.htmlSafeDescription$ → $mutation.statusDescription$ $if(mutation.survived)$ -

Covered by tests:

+Covering tests + $endif$ -

}$ + }$ }$ diff --git a/pitest-html-report/src/main/resources/templates/mutation/style.css b/pitest-html-report/src/main/resources/templates/mutation/style.css index 303bfba78..a0ac211cb 100644 --- a/pitest-html-report/src/main/resources/templates/mutation/style.css +++ b/pitest-html-report/src/main/resources/templates/mutation/style.css @@ -560,4 +560,15 @@ body{ .width-100 { width: 100%; +} + +.view-covered-by-tests{ + cursor:pointer; + color:blue; + text-decoration:underline; +} + +.view-covered-by-tests:hover{ + text-decoration:none; + text-shadow: 1px 1px 1px #555; } \ No newline at end of file diff --git a/pitest-html-report/src/test/java/org/pitest/mutationtest/report/html/ResultComparatorTest.java b/pitest-html-report/src/test/java/org/pitest/mutationtest/report/html/ResultComparatorTest.java index cffed0eae..5efb9b9b6 100644 --- a/pitest-html-report/src/test/java/org/pitest/mutationtest/report/html/ResultComparatorTest.java +++ b/pitest-html-report/src/test/java/org/pitest/mutationtest/report/html/ResultComparatorTest.java @@ -3,6 +3,7 @@ import static org.junit.Assert.assertEquals; import java.util.Arrays; +import java.util.Collections; import java.util.List; import org.junit.Test; @@ -27,7 +28,7 @@ public void shouldSortInDesiredOrder() { } private MutationResult make(final DetectionStatus status) { - return new MutationResult(null, MutationStatusTestPair.notAnalysed(0, status)); + return new MutationResult(null, MutationStatusTestPair.notAnalysed(0, status, Collections.emptyList())); } } diff --git a/pitest/src/main/java/org/pitest/mutationtest/MutationStatusTestPair.java b/pitest/src/main/java/org/pitest/mutationtest/MutationStatusTestPair.java index edee28a8a..2d7b10e93 100644 --- a/pitest/src/main/java/org/pitest/mutationtest/MutationStatusTestPair.java +++ b/pitest/src/main/java/org/pitest/mutationtest/MutationStatusTestPair.java @@ -29,23 +29,26 @@ public final class MutationStatusTestPair implements Serializable { private final List killingTests; private final List succeedingTests; - public static MutationStatusTestPair notAnalysed(int testsRun, DetectionStatus status) { - return new MutationStatusTestPair(testsRun, status, Collections.emptyList(), Collections.emptyList()); + private final List coveringTests; + + public static MutationStatusTestPair notAnalysed(int testsRun, DetectionStatus status, List coveringTests) { + return new MutationStatusTestPair(testsRun, status, Collections.emptyList(), Collections.emptyList(), coveringTests); } public MutationStatusTestPair(final int numberOfTestsRun, final DetectionStatus status, final String killingTest) { this(numberOfTestsRun, status, killingTestToList(killingTest), - Collections.emptyList()); + Collections.emptyList(),killingTestToList(killingTest)); } public MutationStatusTestPair(final int numberOfTestsRun, final DetectionStatus status, final List killingTests, - final List succeedingTests) { + final List succeedingTests, final List coveringTests) { this.status = status; this.killingTests = killingTests; this.succeedingTests = succeedingTests; this.numberOfTestsRun = numberOfTestsRun; + this.coveringTests = coveringTests; } private static List killingTestToList(String killingTest) { @@ -85,6 +88,10 @@ public List getSucceedingTests() { return succeedingTests; } + public List getCoveringTests() { + return coveringTests; + } + public int getNumberOfTestsRun() { return this.numberOfTestsRun; } @@ -96,12 +103,11 @@ public String toString() { } else { return this.status.name() + " by " + this.killingTests; } - } @Override public int hashCode() { - return Objects.hash(numberOfTestsRun, status, killingTests, succeedingTests); + return Objects.hash(numberOfTestsRun, status, killingTests, succeedingTests, coveringTests); } @Override @@ -116,6 +122,7 @@ public boolean equals(final Object obj) { return numberOfTestsRun == other.numberOfTestsRun && status == other.status && Objects.equals(killingTests, other.killingTests) - && Objects.equals(succeedingTests, other.succeedingTests); + && Objects.equals(succeedingTests, other.succeedingTests) + && Objects.equals(coveringTests, other.coveringTests); } } diff --git a/pitest/src/main/java/org/pitest/mutationtest/execute/MutationTestWorker.java b/pitest/src/main/java/org/pitest/mutationtest/execute/MutationTestWorker.java index 0cb9480fe..53b5cd9bd 100644 --- a/pitest/src/main/java/org/pitest/mutationtest/execute/MutationTestWorker.java +++ b/pitest/src/main/java/org/pitest/mutationtest/execute/MutationTestWorker.java @@ -128,7 +128,7 @@ private MutationStatusTestPair handleMutation( if ((relevantTests == null) || relevantTests.isEmpty()) { LOG.info(() -> "No test coverage for mutation " + mutationId + " in " + mutatedClass.getDetails().getMethod()); - mutationDetected = MutationStatusTestPair.notAnalysed(0, DetectionStatus.RUN_ERROR); + mutationDetected = MutationStatusTestPair.notAnalysed(0, DetectionStatus.RUN_ERROR, Collections.emptyList()); } else { mutationDetected = handleCoveredMutation(mutationId, mutatedClass, relevantTests); @@ -160,7 +160,9 @@ private MutationStatusTestPair handleCoveredMutation( } else { LOG.warning("Mutation " + mutationId + " was not viable "); mutationDetected = MutationStatusTestPair.notAnalysed(0, - DetectionStatus.NON_VIABLE); + DetectionStatus.NON_VIABLE, relevantTests.stream() + .map(t -> t.getDescription().getQualifiedName()) + .collect(Collectors.toList())); } return mutationDetected; } @@ -199,7 +201,7 @@ private MutationStatusTestPair doTestsDetectMutation(final Container c, pit.run(c, createEarlyExitTestGroup(tests)); } - return createStatusTestPair(listener); + return createStatusTestPair(listener, tests); } catch (final Exception ex) { throw translateCheckedException(ex); } @@ -207,14 +209,16 @@ private MutationStatusTestPair doTestsDetectMutation(final Container c, } private MutationStatusTestPair createStatusTestPair( - final CheckTestHasFailedResultListener listener) { + final CheckTestHasFailedResultListener listener, List relevantTests) { List failingTests = listener.getFailingTests().stream() .map(Description::getQualifiedName).collect(Collectors.toList()); List succeedingTests = listener.getSucceedingTests().stream() .map(Description::getQualifiedName).collect(Collectors.toList()); + List coveredTests = relevantTests.stream() + .map(t -> t.getDescription().getQualifiedName()).collect(Collectors.toList()); return new MutationStatusTestPair(listener.getNumberOfTestsRun(), - listener.status(), failingTests, succeedingTests); + listener.status(), failingTests, succeedingTests, coveredTests); } private List createEarlyExitTestGroup(final List tests) { diff --git a/pitest/src/test/java/org/pitest/mutationtest/execute/MutationTestWorkerTest.java b/pitest/src/test/java/org/pitest/mutationtest/execute/MutationTestWorkerTest.java index 0c6066c53..8cb7c8a87 100644 --- a/pitest/src/test/java/org/pitest/mutationtest/execute/MutationTestWorkerTest.java +++ b/pitest/src/test/java/org/pitest/mutationtest/execute/MutationTestWorkerTest.java @@ -3,6 +3,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import static org.pitest.mutationtest.DetectionStatus.NON_VIABLE; import static org.pitest.mutationtest.LocationMother.aLocation; import static org.pitest.mutationtest.LocationMother.aMutationId; @@ -80,7 +81,7 @@ public void shouldReportNoCoverageForMutationWithNoTestCoverage() final Collection range = Arrays.asList(mutantOne); this.testee.run(range, this.reporter, this.testSource); verify(this.reporter).report(mutantOne.getId(), - MutationStatusTestPair.notAnalysed(0, DetectionStatus.NO_COVERAGE)); + MutationStatusTestPair.notAnalysed(0, DetectionStatus.NO_COVERAGE, Collections.emptyList())); } @Test @@ -94,9 +95,7 @@ public void shouldReportWhenMutationNotDetected() throws IOException { this.hotswapper.insertClass(any(ClassName.class), any(ClassLoader.class), any(byte[].class))).thenReturn(true); this.testee.run(range, this.reporter, this.testSource); - verify(this.reporter).report(mutantOne.getId(), - new MutationStatusTestPair(1, DetectionStatus.SURVIVED, new ArrayList<>(), new ArrayList<>())); - + verify(this.reporter).describe(mutantOne.getId()); } @Test @@ -110,8 +109,9 @@ public void shouldReportWhenMutationNotViable() throws IOException { this.hotswapper.insertClass(any(ClassName.class), any(ClassLoader.class), any(byte[].class))).thenReturn(false); this.testee.run(range, this.reporter, this.testSource); + verify(this.reporter).describe(mutantOne.getId()); verify(this.reporter).report(mutantOne.getId(), - MutationStatusTestPair.notAnalysed(0, DetectionStatus.NON_VIABLE)); + MutationStatusTestPair.notAnalysed(0, NON_VIABLE,Collections.singletonList("atest"))); } @Test