Skip to content

Commit

Permalink
pass build issues to listeners
Browse files Browse the repository at this point in the history
  • Loading branch information
hcoles committed Apr 2, 2024
1 parent 1cf23ab commit 6f8342f
Show file tree
Hide file tree
Showing 19 changed files with 219 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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<Path> asPaths(Collection<File> files) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand All @@ -22,15 +25,17 @@ public class ListenerArguments {
private final boolean fullMutationMatrix;
private final ReportOptions data;
private final FeatureSetting setting;
private final List<BuildIssue> issues;

public ListenerArguments(ResultOutputStrategy outputStrategy,
ReportCoverage coverage,
SourceLocator locator,
MutationEngine engine,
long startTime,
boolean fullMutationMatrix,
ReportOptions data) {
this(outputStrategy, coverage, locator, engine, startTime, fullMutationMatrix, data, null);
ReportOptions data,
List<BuildIssue> issues) {
this(outputStrategy, coverage, locator, engine, startTime, fullMutationMatrix, data, null, issues);
}

ListenerArguments(ResultOutputStrategy outputStrategy,
Expand All @@ -40,7 +45,8 @@ public ListenerArguments(ResultOutputStrategy outputStrategy,
long startTime,
boolean fullMutationMatrix,
ReportOptions data,
FeatureSetting setting) {
FeatureSetting setting,
List<BuildIssue> issues) {
this.outputStrategy = outputStrategy;
this.coverage = coverage;
this.locator = locator;
Expand All @@ -49,6 +55,7 @@ public ListenerArguments(ResultOutputStrategy outputStrategy,
this.fullMutationMatrix = fullMutationMatrix;
this.data = data;
this.setting = setting;
this.issues = issues;
}

public ResultOutputStrategy getOutputStrategy() {
Expand Down Expand Up @@ -83,6 +90,10 @@ public Optional<FeatureSetting> settings() {
return Optional.ofNullable(setting);
}

public List<BuildIssue> issues() {
return Collections.unmodifiableList(issues);
}

public ListenerArguments withSetting(FeatureSetting setting) {
return new ListenerArguments(outputStrategy,
coverage,
Expand All @@ -91,7 +102,8 @@ public ListenerArguments withSetting(FeatureSetting setting) {
startTime,
fullMutationMatrix,
data,
setting);
setting,
issues);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -10,11 +11,11 @@ public class CombinedStatistics {
private final MutationStatistics mutationStatistics;
private final CoverageSummary coverageSummary;

private final List<String> issues;
private final List<BuildIssue> issues;

public CombinedStatistics(MutationStatistics mutationStatistics,
CoverageSummary coverageSummary,
List<String> issues) {
List<BuildIssue> issues) {
this.mutationStatistics = mutationStatistics;
this.coverageSummary = coverageSummary;
this.issues = issues;
Expand All @@ -28,7 +29,7 @@ public CoverageSummary getCoverageSummary() {
return this.coverageSummary;
}

public List<String> getIssues() {
public List<BuildIssue> getIssues() {
return issues;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -113,7 +114,7 @@ public CombinedStatistics runReport() throws IOException {

final long t0 = System.nanoTime();

List<String> issues = verifyBuildSuitableForMutationTesting();
List<BuildIssue> issues = verifyBuildSuitableForMutationTesting();

checkExcludedRunners();

Expand Down Expand Up @@ -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<String> issues) {
private CombinedStatistics runAnalysis(Runtime runtime, long t0, EngineArguments args, MutationEngine engine, List<BuildIssue> issues) {
History history = this.strategies.history();
history.initialize();

Expand Down Expand Up @@ -170,7 +171,7 @@ private CombinedStatistics runAnalysis(Runtime runtime, long t0, EngineArguments

ReportCoverage modifiedCoverage = transformCoverage(coverageData);
final List<MutationResultListener> 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);
Expand Down Expand Up @@ -254,14 +255,14 @@ private List<MutationResultListener> createConfig(long t0,
ReportCoverage coverageData,
History history,
MutationStatisticsListener stats,
MutationEngine engine) {
MutationEngine engine, List<BuildIssue> issues) {
final List<MutationResultListener> 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);
Expand All @@ -279,8 +280,8 @@ private MutationResultInterceptor resultInterceptor() {
return this.strategies.resultInterceptor();
}

private List<String> verifyBuildSuitableForMutationTesting() {
return this.strategies.buildVerifier().verify();
private List<BuildIssue> verifyBuildSuitableForMutationTesting() {
return this.strategies.buildVerifier().verifyBuild();
}

private void printStats(CombinedStatistics combinedStatistics) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package org.pitest.mutationtest.verify;

import java.util.Objects;

public final class BuildIssue implements Comparable<BuildIssue> {
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);
}
}
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -9,6 +11,15 @@
*/
public interface BuildVerifier {

List<String> verify();
@Deprecated
default List<String> verify() {
return Collections.emptyList();
}

default List<BuildIssue> verifyBuild() {
return verify().stream()
.map(BuildIssue::issue)
.collect(Collectors.toList());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,17 @@ public CompoundBuildVerifierFactory(List<BuildVerifierFactory> verifiers) {

@Override
public BuildVerifier create(CodeSource code) {
return () -> verifiers.stream()
List<BuildIssue> 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<BuildIssue> verifyBuild() {
return issues;
}
};
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public DefaultBuildVerifier(CodeSource code) {
}

@Override
public List<String> verify() {
public List<BuildIssue> verifyBuild() {

// check we have at least one class that is not an interface
// otherwise our checks will fire on an empty project
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ class KotlinVerifier implements BuildVerifier {
}

@Override
public List<String> verify() {
public List<BuildIssue> 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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ public void shouldRecordClassPath() {
@Test
public void shouldCheckBuildSuitableForMutationTesting() {
createAndRunTestee();
verify(this.verifier).verify();
verify(this.verifier).verifyBuild();
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -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<BuildIssue> l = asList(a,b,c);
Collections.sort(l);
assertThat(l).containsExactly(b,c,a);
}
}
Loading

0 comments on commit 6f8342f

Please sign in to comment.