Skip to content

Commit 52314cb

Browse files
authored
Merge pull request #1437 from hcoles/feature/test_filters
test filter extension point
2 parents 50652ea + 58946b4 commit 52314cb

File tree

12 files changed

+224
-4
lines changed

12 files changed

+224
-4
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ jobs:
2828
uses: actions/setup-java@v4
2929
with:
3030
java-version: ${{ matrix.java }}
31-
distribution: adopt
31+
distribution: temurin
3232
- name: 'Display JDK version'
3333
run: java -version
3434
- name: Cache local Maven repository

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ jobs:
2828
- name: Setup Java JDK
2929
uses: actions/setup-java@v4
3030
with:
31-
distribution: adopt
31+
distribution: temurin
3232
java-version: 11
3333
server-id: central
3434
server-username: MAVEN_USERNAME

.github/workflows/snapshot.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
uses: actions/setup-java@v4
2020
with:
2121
java-version: 11
22-
distribution: adopt
22+
distribution: temurin
2323
server-id: central
2424
server-username: MAVEN_USERNAME
2525
server-password: MAVEN_PASSWORD
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package org.pitest.mutationtest.build;
2+
3+
import org.pitest.classpath.CodeSource;
4+
import org.pitest.coverage.CoverageDatabase;
5+
6+
import java.util.Properties;
7+
import java.util.stream.Collectors;
8+
9+
public class FilteringPrioritiser implements TestPrioritiserFactory {
10+
11+
private final TestPrioritiserFactory delegate;
12+
private final TestFilter filter;
13+
14+
public FilteringPrioritiser(TestPrioritiserFactory delegate, TestFilter filter) {
15+
this.delegate = delegate;
16+
this.filter = filter;
17+
}
18+
19+
@Override
20+
public TestPrioritiser makeTestPrioritiser(Properties props, CodeSource code, CoverageDatabase coverage) {
21+
TestPrioritiser p = delegate.makeTestPrioritiser(props, code, coverage);
22+
23+
return mutation -> p.assignTests(mutation).stream()
24+
.filter(test -> filter.include(test, mutation))
25+
.collect(Collectors.toList());
26+
}
27+
28+
@Override
29+
public String description() {
30+
return "Internal prioritiser factory";
31+
}
32+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package org.pitest.mutationtest.build;
2+
3+
import org.pitest.coverage.TestInfo;
4+
import org.pitest.mutationtest.engine.MutationDetails;
5+
6+
import java.util.List;
7+
8+
public interface TestFilter {
9+
boolean include(TestInfo test, MutationDetails mutant);
10+
11+
static TestFilter combine(List<TestFilter> filters) {
12+
return (test, mutant) -> filters.stream()
13+
.allMatch(f -> f.include(test, mutant));
14+
}
15+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package org.pitest.mutationtest.build;
2+
3+
import org.pitest.plugin.ProvidesFeature;
4+
import org.pitest.plugin.ToolClasspathPlugin;
5+
6+
public interface TestFilterFactory extends ToolClasspathPlugin, ProvidesFeature {
7+
8+
TestFilter makeFilter(TestFilterParams params);
9+
10+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package org.pitest.mutationtest.build;
2+
3+
import org.pitest.plugin.FeatureSetting;
4+
5+
public class TestFilterParams {
6+
private final FeatureSetting conf;
7+
8+
public TestFilterParams(FeatureSetting conf) {
9+
this.conf = conf;
10+
}
11+
12+
public FeatureSetting conf() {
13+
return conf;
14+
}
15+
16+
}

pitest-entry/src/main/java/org/pitest/mutationtest/config/PluginServices.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import org.pitest.mutationtest.MutationResultListenerFactory;
1111
import org.pitest.mutationtest.build.MutationGrouperFactory;
1212
import org.pitest.mutationtest.build.MutationInterceptorFactory;
13+
import org.pitest.mutationtest.build.TestFilterFactory;
1314
import org.pitest.mutationtest.build.TestPrioritiserFactory;
1415
import org.pitest.mutationtest.engine.gregor.MethodMutatorFactory;
1516
import org.pitest.mutationtest.engine.gregor.MutatorInfo;
@@ -65,6 +66,7 @@ public Collection<? extends ToolClasspathPlugin> findToolClasspathPlugins() {
6566
l.addAll(findCoverageExport());
6667
l.addAll(findStandAloneMutatorInfos());
6768
l.addAll(findTestStatListeners());
69+
l.addAll(findTestFilters());
6870
return l;
6971
}
7072

@@ -148,6 +150,11 @@ public List<TestStatListenerFactory> findTestStatListeners() {
148150
return new ArrayList<>(load(TestStatListenerFactory.class));
149151
}
150152

153+
154+
public List<TestFilterFactory> findTestFilters() {
155+
return new ArrayList<>(load(TestFilterFactory.class));
156+
}
157+
151158
public List<MutatorInfo> findMutatorInfos() {
152159
List<MutatorInfo> combined = findMutationOperators().stream()
153160
.filter(p -> p instanceof MutatorInfo)

pitest-entry/src/main/java/org/pitest/mutationtest/config/SettingsFactory.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,12 @@
2121
import org.pitest.mutationtest.build.CompoundInterceptorFactory;
2222
import org.pitest.mutationtest.build.DefaultMutationGrouperFactory;
2323
import org.pitest.mutationtest.build.DefaultTestPrioritiserFactory;
24+
import org.pitest.mutationtest.build.FilteringPrioritiser;
2425
import org.pitest.mutationtest.build.MutationGrouperFactory;
2526
import org.pitest.mutationtest.build.MutationInterceptorFactory;
27+
import org.pitest.mutationtest.build.TestFilter;
28+
import org.pitest.mutationtest.build.TestFilterFactory;
29+
import org.pitest.mutationtest.build.TestFilterParams;
2630
import org.pitest.mutationtest.build.TestPrioritiserFactory;
2731
import org.pitest.mutationtest.incremental.DefaultHistoryFactory;
2832
import org.pitest.mutationtest.verify.BuildVerifierFactory;
@@ -88,6 +92,19 @@ public TestStatListener createTestStatListener() {
8892
return new CompoundTestStatListener(listeners);
8993
}
9094

95+
public TestFilter createTestFilter() {
96+
FeatureParser parser = new FeatureParser();
97+
List<TestFilterFactory> available = plugins.findTestFilters();
98+
FeatureSelector<TestFilterFactory> features = new FeatureSelector<>(parser.parseFeatures(this.options.getFeatures()), available);
99+
List<TestFilterFactory> enabled = features.getActiveFeatures();
100+
101+
List<TestFilter> filters = enabled.stream()
102+
.map(f -> f.makeFilter(new TestFilterParams(features.getSettingForFeature(f.provides().name()))))
103+
.collect(Collectors.toList());
104+
return TestFilter.combine(filters);
105+
}
106+
107+
91108
public MutationEngineFactory createEngine() {
92109
for (final MutationEngineFactory each : this.plugins.findMutationEngines()) {
93110
if (each.name().equals(this.options.getMutationEngine())) {
@@ -193,7 +210,8 @@ public void checkRequestedFeatures() {
193210
public TestPrioritiserFactory getTestPrioritiser() {
194211
final Collection<? extends TestPrioritiserFactory> testPickers = this.plugins
195212
.findTestPrioritisers();
196-
return firstOrDefault(testPickers, new DefaultTestPrioritiserFactory());
213+
TestFilter filter = createTestFilter();
214+
return new FilteringPrioritiser(firstOrDefault(testPickers, new DefaultTestPrioritiserFactory()), filter);
197215
}
198216

199217
public CoverageOptions createCoverageOptions() {
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package org.pitest.mutationtest.build;
2+
3+
import org.junit.Test;
4+
import org.pitest.classinfo.ClassName;
5+
import org.pitest.classpath.CodeSource;
6+
import org.pitest.coverage.CoverageDatabase;
7+
import org.pitest.coverage.TestInfo;
8+
9+
import java.util.List;
10+
import java.util.Optional;
11+
import java.util.Properties;
12+
13+
import static java.util.Arrays.asList;
14+
import static org.assertj.core.api.Assertions.assertThat;
15+
16+
public class FilteringPrioritiserTest {
17+
18+
@Test
19+
public void appliesFilterToPrioritisedTestWhenFalse() {
20+
TestFilter alwaysFalse = (t, m) -> false;
21+
List<TestInfo> tests = asList(aTest(), aTest());
22+
FilteringPrioritiser underTest = new FilteringPrioritiser(alwaysSupply(tests), alwaysFalse);
23+
24+
TestPrioritiser prioritiser = underTest.makeTestPrioritiser(new Properties(), unused(), unused());
25+
26+
assertThat(prioritiser.assignTests(unused())).isEmpty();
27+
}
28+
29+
@Test
30+
public void appliesFilterToPrioritisedTestWhenTrue() {
31+
TestFilter alwaysTrue = (t, m) -> true;
32+
List<TestInfo> tests = asList(aTest(), aTest());
33+
FilteringPrioritiser underTest = new FilteringPrioritiser(alwaysSupply(tests), alwaysTrue);
34+
35+
TestPrioritiser prioritiser = underTest.makeTestPrioritiser(new Properties(), unused(), unused());
36+
37+
assertThat(prioritiser.assignTests(unused())).containsExactlyElementsOf(tests);
38+
}
39+
40+
41+
private <T> T unused() {
42+
return null;
43+
}
44+
45+
private TestInfo aTest() {
46+
return new TestInfo("foo", "bar", 1, Optional.<ClassName> empty(), 0);
47+
}
48+
49+
private TestPrioritiserFactory alwaysSupply(List<TestInfo> tests) {
50+
return new TestPrioritiserFactory() {
51+
@Override
52+
public String description() {
53+
return "";
54+
}
55+
56+
@Override
57+
public TestPrioritiser makeTestPrioritiser(Properties props, CodeSource code, CoverageDatabase coverage) {
58+
return m -> tests;
59+
}
60+
};
61+
}
62+
}

0 commit comments

Comments
 (0)