diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 000000000..b9e31c74c
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,41 @@
+name: CI
+on:
+ push:
+ branches:
+ - 'master'
+ pull_request:
+ branches-ignore:
+ - 'release'
+jobs:
+ supported-jdk:
+ name: ${{ matrix.title }}
+ continue-on-error: false
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - title: "JDK 8"
+ java: 8
+ - title: "JDK 11"
+ java: 11
+ - title: "JDK 15"
+ java: 15
+ runs-on: ubuntu-latest
+ steps:
+ - name: 'Checkout from Git'
+ uses: actions/checkout@v2
+ - name: 'Set up JDK ${{ matrix.java }}'
+ uses: actions/setup-java@v1
+ with:
+ java-version: ${{ matrix.java }}
+ - name: 'Display JDK version'
+ run: java -version
+ - name: Cache local Maven repository
+ uses: actions/cache@v2
+ with:
+ path: ~/.m2/repository
+ key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
+ restore-keys: ${{ runner.os }}-maven-
+ - name: 'Test'
+ # install rather than verify to ensure correct version used during integration test
+ run: mvn -B install
diff --git a/.github/workflows/snapshot.yml b/.github/workflows/snapshot.yml
new file mode 100644
index 000000000..8b332ea03
--- /dev/null
+++ b/.github/workflows/snapshot.yml
@@ -0,0 +1,30 @@
+name: Deploy snapshot
+on:
+ push:
+ branches:
+ - master
+jobs:
+ snapshot:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout project
+ uses: actions/checkout@v2
+ - name: Cache local Maven repository
+ uses: actions/cache@v2
+ with:
+ path: ~/.m2/repository
+ key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
+ restore-keys: ${{ runner.os }}-maven-
+ - name: Setup Java JDK
+ uses: actions/setup-java@v1.4.3
+ with:
+ java-version: 8
+ server-id: ossrh
+ server-username: MAVEN_USERNAME
+ server-password: MAVEN_PASSWORD
+ - name: Publish JARs
+ run: mvn -B deploy -DskipTests=true
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }}
+ MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }}
diff --git a/.gitignore b/.gitignore
index b0345ac09..e0d2b0856 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,3 +13,5 @@ target/
dependency-reduced-pom.xml
.flattened-pom.xml
*/bin
+.DS_Store
+
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 5a38e0268..000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,48 +0,0 @@
-sudo: false
-
-language: java
-
-# Get latest install-jdk.sh script
-before_install:
- - wget https://github.com/sormuras/bach/raw/master/install-jdk.sh
-
-env:
- global:
- # taken first download mirror from http://maven.apache.org/
- - BASEURL=http://mirror.softaculous.com/apache/maven/maven-3/VERSION/binaries/apache-maven-VERSION-bin.tar.gz
- - FILE=apache-maven-VERSION-bin.tar.gz
- - DIR=apache-maven-VERSION/bin
-
-matrix:
- include:
- - jdk: openjdk8
- env: MAVEN=3.2.5
-
- - jdk: openjdk9
- env: MAVEN=3.5.4
-
- - jdk: openjdk10
- env: MAVEN=3.5.4
-
- - jdk: openjdk11
- env: MAVEN=3.5.4
-
- - jdk: openjdk12
- env: MAVEN=3.5.4
-
- - jdk: openjdk13
- env: MAVEN=3.6.3
-
- - env: JDK=14 MAVEN=3.6.3
- install: . ./install-jdk.sh --feature 14
-
- - env: JDK='OpenJ9 11' MAVEN=3.5.4
- install: . ./install-jdk.sh --url "https://api.adoptopenjdk.net/v2/binary/releases/openjdk11?openjdk_impl=openj9&os=linux&arch=x64&release=latest&type=jdk&heap_size=normal"
-
-script:
- - wget $(echo -n $BASEURL | sed -e 's#VERSION#'$MAVEN'#g')
- - tar -xvzf $(echo -n $FILE | sed -e 's#VERSION#'$MAVEN'#')
- - export PATH=$(echo -n $DIR | sed -e 's#VERSION#'$MAVEN'#'):$PATH
- - java -version
- - mvn -version
- - mvn clean install
diff --git a/README.md b/README.md
index ba1d24ebd..5296543cd 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
[](https://maven-badges.herokuapp.com/maven-central/org.pitest/pitest)
-[](https://travis-ci.org/hcoles/pitest)
+
[](https://dev.azure.com/henrycoles/pitest/_build/latest?definitionId=3&branchName=master)
Pitest (aka PIT) is a state of the art mutation testing system for Java and the JVM.
@@ -8,6 +8,14 @@ Read all about it at http://pitest.org
## Releases
+### 1.6.1
+
+* Automate release to maven central
+* #774 Test strength statistic (thanks @alex859)
+* #798 Enable jvm args to be passed from command line (thanks @yfrolov)
+* #797 Add line coverage to console (thanks @qxo)
+* #822 Mitigate NPE on accidental dependency (thanks @szpak)
+
### 1.5.2
* #749 ANT support for the fullMutationMatrix option (thanks @ayaankazerouni)
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index c17310a53..faaf359ee 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -3,8 +3,6 @@ trigger:
strategy:
matrix:
- linux:
- imageName: 'Ubuntu-16.04'
mac:
imageName: 'macos-10.14'
windows:
diff --git a/pitest-build-config/src/main/resources/pitest/checkstyle.xml b/pitest-build-config/src/main/resources/pitest/checkstyle.xml
index f174b5a15..9effbb976 100644
--- a/pitest-build-config/src/main/resources/pitest/checkstyle.xml
+++ b/pitest-build-config/src/main/resources/pitest/checkstyle.xml
@@ -45,6 +45,7 @@
+
diff --git a/pitest-entry/pom.xml b/pitest-entry/pom.xml
index 126e499a9..d7c644659 100644
--- a/pitest-entry/pom.xml
+++ b/pitest-entry/pom.xml
@@ -143,7 +143,7 @@
com.thoughtworks.xstream
xstream
- 1.4.8
+ 1.4.15
test
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 8b4f0a44f..146974933 100644
--- a/pitest-entry/src/main/java/org/pitest/mutationtest/ListenerArguments.java
+++ b/pitest-entry/src/main/java/org/pitest/mutationtest/ListenerArguments.java
@@ -1,9 +1,13 @@
package org.pitest.mutationtest;
import org.pitest.coverage.CoverageDatabase;
+import org.pitest.mutationtest.config.ReportOptions;
import org.pitest.mutationtest.engine.MutationEngine;
+import org.pitest.plugin.FeatureSetting;
import org.pitest.util.ResultOutputStrategy;
+import java.util.Optional;
+
/**
* Data passed to the listener MutationResultListener factories for use when
* constructing listeners.
@@ -16,16 +20,35 @@ public class ListenerArguments {
private final SourceLocator locator;
private final MutationEngine engine;
private final boolean fullMutationMatrix;
+ private final ReportOptions data;
+ private final FeatureSetting setting;
+
+ public ListenerArguments(ResultOutputStrategy outputStrategy,
+ CoverageDatabase coverage,
+ SourceLocator locator,
+ MutationEngine engine,
+ long startTime,
+ boolean fullMutationMatrix,
+ ReportOptions data) {
+ this(outputStrategy, coverage, locator, engine, startTime, fullMutationMatrix, data, null);
+ }
- public ListenerArguments(final ResultOutputStrategy outputStrategy,
- final CoverageDatabase coverage, final SourceLocator locator,
- final MutationEngine engine, final long startTime, final boolean fullMutationMatrix) {
+ ListenerArguments(ResultOutputStrategy outputStrategy,
+ CoverageDatabase coverage,
+ SourceLocator locator,
+ MutationEngine engine,
+ long startTime,
+ boolean fullMutationMatrix,
+ ReportOptions data,
+ FeatureSetting setting) {
this.outputStrategy = outputStrategy;
this.coverage = coverage;
this.locator = locator;
this.startTime = startTime;
this.engine = engine;
this.fullMutationMatrix = fullMutationMatrix;
+ this.data = data;
+ this.setting = setting;
}
public ResultOutputStrategy getOutputStrategy() {
@@ -51,4 +74,24 @@ public MutationEngine getEngine() {
public boolean isFullMutationMatrix() {
return fullMutationMatrix;
}
+
+ public ReportOptions data() {
+ return data;
+ }
+
+ public Optional settings() {
+ return Optional.ofNullable(setting);
+ }
+
+ public ListenerArguments withSetting(FeatureSetting setting) {
+ return new ListenerArguments(outputStrategy,
+ coverage,
+ locator,
+ engine,
+ startTime,
+ fullMutationMatrix,
+ data,
+ setting);
+ }
+
}
diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/MutationResultListenerFactory.java b/pitest-entry/src/main/java/org/pitest/mutationtest/MutationResultListenerFactory.java
index 4251c4364..9b73aaf48 100644
--- a/pitest-entry/src/main/java/org/pitest/mutationtest/MutationResultListenerFactory.java
+++ b/pitest-entry/src/main/java/org/pitest/mutationtest/MutationResultListenerFactory.java
@@ -15,14 +15,23 @@
package org.pitest.mutationtest;
+import org.pitest.plugin.Feature;
+import org.pitest.plugin.ProvidesFeature;
+import org.pitest.plugin.ToolClasspathPlugin;
+
import java.util.Properties;
-import org.pitest.plugin.ToolClasspathPlugin;
+public interface MutationResultListenerFactory extends ToolClasspathPlugin, ProvidesFeature {
-public interface MutationResultListenerFactory extends ToolClasspathPlugin {
+ Feature LEGACY_MODE = Feature.named("_internal_activate_by_output_string")
+ .withOnByDefault(true);
MutationResultListener getListener(Properties props, ListenerArguments args);
String name();
+ default Feature provides() {
+ return LEGACY_MODE;
+ }
+
}
diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/build/CompoundInterceptorFactory.java b/pitest-entry/src/main/java/org/pitest/mutationtest/build/CompoundInterceptorFactory.java
index 463b2c8bc..6b3755bad 100644
--- a/pitest-entry/src/main/java/org/pitest/mutationtest/build/CompoundInterceptorFactory.java
+++ b/pitest-entry/src/main/java/org/pitest/mutationtest/build/CompoundInterceptorFactory.java
@@ -1,15 +1,15 @@
package org.pitest.mutationtest.build;
-import java.util.Collection;
-import java.util.List;
-import java.util.function.Function;
-
import org.pitest.classinfo.ClassByteArraySource;
-import org.pitest.functional.FCollection;
import org.pitest.mutationtest.config.ReportOptions;
import org.pitest.plugin.FeatureSelector;
import org.pitest.plugin.FeatureSetting;
+import java.util.Collection;
+import java.util.List;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
public class CompoundInterceptorFactory {
private final FeatureSelector features;
@@ -22,8 +22,9 @@ public CompoundInterceptorFactory(List features,
public MutationInterceptor createInterceptor(
ReportOptions data,
ClassByteArraySource source) {
- final List interceptors = FCollection.map(this.features.getActiveFeatures(),
- toInterceptor(this.features, data, source));
+ final List interceptors = this.features.getActiveFeatures().stream()
+ .map(toInterceptor(this.features, data, source))
+ .collect(Collectors.toList());
return new CompoundMutationInterceptor(interceptors);
}
diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/config/CompoundListenerFactory.java b/pitest-entry/src/main/java/org/pitest/mutationtest/config/CompoundListenerFactory.java
index dc17d11c7..c0f2f6072 100644
--- a/pitest-entry/src/main/java/org/pitest/mutationtest/config/CompoundListenerFactory.java
+++ b/pitest-entry/src/main/java/org/pitest/mutationtest/config/CompoundListenerFactory.java
@@ -14,33 +14,35 @@
*/
package org.pitest.mutationtest.config;
-import java.util.Properties;
-import java.util.function.Function;
-
-import org.pitest.functional.FCollection;
import org.pitest.mutationtest.ListenerArguments;
import org.pitest.mutationtest.MutationResultListener;
import org.pitest.mutationtest.MutationResultListenerFactory;
+import org.pitest.plugin.Feature;
+import org.pitest.plugin.FeatureSelector;
+import org.pitest.plugin.FeatureSetting;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Properties;
+import java.util.function.Function;
+import java.util.stream.Collectors;
public class CompoundListenerFactory implements MutationResultListenerFactory {
- private final Iterable children;
+ private final FeatureSelector features;
- public CompoundListenerFactory(
- final Iterable children) {
- this.children = children;
+ public CompoundListenerFactory(List features, final Collection children) {
+ this.features = new FeatureSelector<>(features, children);
}
@Override
public MutationResultListener getListener(final Properties props,
final ListenerArguments args) {
- return new CompoundTestListener(FCollection.map(this.children,
- factoryToListener(props, args)));
- }
+ final List listeners = this.features.getActiveFeatures().stream()
+ .map(toListener(props, args))
+ .collect(Collectors.toList());
- private Function factoryToListener(
- final Properties props, final ListenerArguments args) {
- return a -> a.getListener(props, args);
+ return new CompoundTestListener(listeners);
}
@Override
@@ -53,4 +55,13 @@ public String description() {
throw new UnsupportedOperationException();
}
+ @Override
+ public Feature provides() {
+ throw new UnsupportedOperationException();
+ }
+
+ private Function toListener(Properties props,
+ ListenerArguments args) {
+ return a -> a.getListener(props, args.withSetting(features.getSettingForFeature(a.provides().name())));
+ }
}
diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/config/PluginServices.java b/pitest-entry/src/main/java/org/pitest/mutationtest/config/PluginServices.java
index d91b65766..b3febb8d2 100644
--- a/pitest-entry/src/main/java/org/pitest/mutationtest/config/PluginServices.java
+++ b/pitest-entry/src/main/java/org/pitest/mutationtest/config/PluginServices.java
@@ -1,20 +1,22 @@
package org.pitest.mutationtest.config;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
import org.pitest.mutationtest.MutationEngineFactory;
import org.pitest.mutationtest.MutationResultListenerFactory;
import org.pitest.mutationtest.build.MutationGrouperFactory;
import org.pitest.mutationtest.build.MutationInterceptorFactory;
import org.pitest.mutationtest.build.TestPrioritiserFactory;
import org.pitest.plugin.ClientClasspathPlugin;
+import org.pitest.plugin.ProvidesFeature;
import org.pitest.plugin.ToolClasspathPlugin;
import org.pitest.testapi.TestPluginFactory;
import org.pitest.util.IsolationUtils;
import org.pitest.util.ServiceLoader;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.stream.Collectors;
+
public class PluginServices {
private final ClassLoader loader;
@@ -33,7 +35,7 @@ public static PluginServices makeForContextLoader() {
*
* @return list of plugins
*/
- public Iterable extends ToolClasspathPlugin> findToolClasspathPlugins() {
+ public Collection extends ToolClasspathPlugin> findToolClasspathPlugins() {
final List l = new ArrayList<>();
l.addAll(findListeners());
l.addAll(findGroupers());
@@ -81,4 +83,11 @@ public Collection extends MutationInterceptorFactory> findInterceptors() {
return ServiceLoader.load(MutationInterceptorFactory.class, this.loader);
}
+ public Collection extends ProvidesFeature> findFeatures() {
+ return findToolClasspathPlugins().stream()
+ .filter(p -> p instanceof ProvidesFeature)
+ .map(p -> ProvidesFeature.class.cast(p))
+ .collect(Collectors.toList());
+ }
+
}
diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/config/SettingsFactory.java b/pitest-entry/src/main/java/org/pitest/mutationtest/config/SettingsFactory.java
index 3e86bb554..6454c94f6 100644
--- a/pitest-entry/src/main/java/org/pitest/mutationtest/config/SettingsFactory.java
+++ b/pitest-entry/src/main/java/org/pitest/mutationtest/config/SettingsFactory.java
@@ -1,14 +1,5 @@
package org.pitest.mutationtest.config;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.List;
-import java.util.function.Consumer;
-import java.util.function.Function;
-import java.util.function.Predicate;
-import java.util.stream.Collectors;
-
import org.pitest.coverage.CoverageExporter;
import org.pitest.coverage.execute.CoverageOptions;
import org.pitest.coverage.export.DefaultCoverageExporter;
@@ -33,6 +24,17 @@
import org.pitest.util.PitError;
import org.pitest.util.ResultOutputStrategy;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
public class SettingsFactory {
private final ReportOptions options;
@@ -67,7 +69,8 @@ public MutationEngineFactory createEngine() {
}
public MutationResultListenerFactory createListener() {
- return new CompoundListenerFactory(findListeners());
+ final FeatureParser parser = new FeatureParser();
+ return new CompoundListenerFactory(parser.parseFeatures(this.options.getFeatures()), findListeners());
}
public JavaExecutableLocator getJavaExecutable() {
@@ -86,7 +89,7 @@ public MutationGrouperFactory getMutationGrouper() {
public void describeFeatures(Consumer enabled, Consumer disabled) {
final FeatureParser parser = new FeatureParser();
- final Collection available = new ArrayList<>(this.plugins.findInterceptors());
+ final Collection available = new ArrayList<>(this.plugins.findFeatures());
final List settings = parser.parseFeatures(this.options.getFeatures());
final FeatureSelector selector = new FeatureSelector<>(settings, available);
@@ -104,9 +107,22 @@ public void describeFeatures(Consumer enabled, Consumer disabl
.sorted(byName())
.filter(f -> !enabledFeatures.contains(f))
.forEach(disabled);
-
}
+ public void checkRequestedFeatures() {
+ FeatureParser parser = new FeatureParser();
+ Set available = this.plugins.findFeatures().stream()
+ .map(f -> f.provides().name())
+ .collect(Collectors.toSet());
+
+ Optional unknown = parser.parseFeatures(this.options.getFeatures()).stream()
+ .filter(f -> !available.contains(f.feature()))
+ .findAny();
+
+ unknown.ifPresent(setting -> {
+ throw new IllegalArgumentException("Unknown feature " + setting.feature());
+ });
+ }
public TestPrioritiserFactory getTestPrioritiser() {
final Collection extends TestPrioritiserFactory> testPickers = this.plugins
@@ -128,12 +144,7 @@ public CompoundInterceptorFactory getInterceptor() {
return new CompoundInterceptorFactory(parser.parseFeatures(this.options.getFeatures()), new ArrayList<>(interceptors));
}
- private static Predicate nameMatches(
- final Iterable outputFormats) {
- return a -> FCollection.contains(outputFormats, equalsIgnoreCase(a.name()));
- }
-
- private Iterable findListeners() {
+ private Collection findListeners() {
final Iterable extends MutationResultListenerFactory> listeners = this.plugins
.findListeners();
final Collection matches = FCollection
@@ -145,6 +156,15 @@ private Iterable findListeners() {
return matches;
}
+ private static Predicate nameMatches(
+ final Iterable outputFormats) {
+ // plugins can be either activated here by name
+ // or later via the feature mechanism
+ return a -> FCollection.contains(outputFormats, equalsIgnoreCase(a.name()))
+ || !a.provides().equals(MutationResultListenerFactory.LEGACY_MODE);
+ }
+
+
private static Predicate equalsIgnoreCase(final String other) {
return a -> a.equalsIgnoreCase(other);
}
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 fce5e7f31..23ac0c60e 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
@@ -1,10 +1,5 @@
package org.pitest.mutationtest.tooling;
-import java.io.File;
-import java.io.IOException;
-import java.io.Reader;
-import java.util.Map;
-
import org.pitest.classpath.ClassPath;
import org.pitest.classpath.ClassPathByteArraySource;
import org.pitest.classpath.CodeSource;
@@ -12,9 +7,6 @@
import org.pitest.coverage.CoverageGenerator;
import org.pitest.coverage.execute.CoverageOptions;
import org.pitest.coverage.execute.DefaultCoverageGenerator;
-import java.util.Optional;
-import java.util.function.Consumer;
-
import org.pitest.mutationtest.HistoryStore;
import org.pitest.mutationtest.MutationResultListenerFactory;
import org.pitest.mutationtest.config.PluginServices;
@@ -31,6 +23,13 @@
import org.pitest.util.ResultOutputStrategy;
import org.pitest.util.Timings;
+import java.io.File;
+import java.io.IOException;
+import java.io.Reader;
+import java.util.Map;
+import java.util.Optional;
+import java.util.function.Consumer;
+
public class EntryPoint {
/**
@@ -72,6 +71,7 @@ public AnalysisResult execute(File baseDir, ReportOptions data,
settings.describeFeatures(asInfo("+"), asInfo("-"));
Log.getLogger().info("---------------------------------------------------------------------------");
}
+ settings.checkRequestedFeatures();
checkMatrixMode(data);
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 9c136c3db..8edd0ed9b 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
@@ -14,18 +14,6 @@
*/
package org.pitest.mutationtest.tooling;
-import java.io.File;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Optional;
-import java.util.Set;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
import org.pitest.classinfo.ClassByteArraySource;
import org.pitest.classinfo.ClassInfo;
import org.pitest.classinfo.ClassName;
@@ -66,6 +54,18 @@
import org.pitest.util.StringUtil;
import org.pitest.util.Timings;
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
public class MutationCoverage {
private static final int MB = 1024 * 1024;
@@ -174,7 +174,7 @@ private void checkExcludedRunners() {
}
}
-private int numberOfThreads() {
+ private int numberOfThreads() {
return Math.max(1, this.data.getNumberOfThreads());
}
@@ -187,7 +187,7 @@ private List createConfig(final long t0,
final ListenerArguments args = new ListenerArguments(
this.strategies.output(), coverageData, new SmartSourceLocator(
- this.data.getSourceDirs()), engine, t0, this.data.isFullMutationMatrix());
+ this.data.getSourceDirs()), engine, t0, this.data.isFullMutationMatrix(), data);
final MutationResultListener mutationReportListener = this.strategies
.listenerFactory().getListener(this.data.getFreeFormProperties(), args);
diff --git a/pitest-entry/src/test/java/com/example/coverage/execute/samples/simple/ParentChildInitializationTest.java b/pitest-entry/src/test/java/com/example/coverage/execute/samples/simple/ParentChildInitializationTest.java
new file mode 100644
index 000000000..7de72f79a
--- /dev/null
+++ b/pitest-entry/src/test/java/com/example/coverage/execute/samples/simple/ParentChildInitializationTest.java
@@ -0,0 +1,22 @@
+package com.example.coverage.execute.samples.simple;
+
+import org.junit.Test;
+
+public class ParentChildInitializationTest {
+ @Test
+ public void test() {
+ new TesteeChild();
+ }
+}
+
+class TesteeParent {
+ static TesteeChild child = new TesteeChild();
+}
+
+class TesteeChild extends TesteeParent {
+ final static Object f = "hello";
+
+ TesteeChild() {
+ System.out.println(f);
+ }
+}
diff --git a/pitest-entry/src/test/java/org/pitest/coverage/execute/CoverageProcessSystemTest.java b/pitest-entry/src/test/java/org/pitest/coverage/execute/CoverageProcessSystemTest.java
index 1fe5a1729..d86c06204 100644
--- a/pitest-entry/src/test/java/org/pitest/coverage/execute/CoverageProcessSystemTest.java
+++ b/pitest-entry/src/test/java/org/pitest/coverage/execute/CoverageProcessSystemTest.java
@@ -7,6 +7,7 @@
import com.example.coverage.execute.samples.exceptions.ThrowsExceptionFromLargeMethodTestee;
import com.example.coverage.execute.samples.exceptions.ThrowsExceptionInFinallyBlockTestee;
import com.example.coverage.execute.samples.exceptions.ThrowsExceptionTestee;
+import com.example.coverage.execute.samples.simple.ParentChildInitializationTest;
import com.example.coverage.execute.samples.simple.Testee;
import com.example.coverage.execute.samples.simple.Testee2;
import com.example.coverage.execute.samples.simple.TesteeWithComplexConstructorsTest;
@@ -57,8 +58,7 @@ public class CoverageProcessSystemTest {
private final MethodName foo = MethodName.fromString("foo");
@Test
- public void shouldRecordSomeCoverage() throws IOException,
- InterruptedException, ExecutionException {
+ public void shouldRecordSomeCoverage() throws Exception {
final List coverage = runCoverageForTest(TestsForMultiBlockCoverage.class);
assertFalse(coverage.iterator().next().getCoverage().isEmpty());
}
@@ -80,8 +80,7 @@ public void shouldCalculateCoverageForSingleBlockMethods()
// }
@Test
- public void shouldCalculateCoverageFor3BlockMethods() throws IOException,
- InterruptedException, ExecutionException {
+ public void shouldCalculateCoverageFor3BlockMethods() throws Exception {
final List coveredClasses = runCoverageForTest(TestsForMultiBlockCoverage.class);
assertCoverage(coveredClasses, "test3", 2);
}
@@ -122,22 +121,19 @@ public void shouldCalculateCoverageForBlockMethods() throws IOException,
}
@Test
- public void shouldCalculateCoverageFor7BlockMethods() throws IOException,
- InterruptedException, ExecutionException {
+ public void shouldCalculateCoverageFor7BlockMethods() throws Exception {
final List coveredClasses = runCoverageForTest(TestsForMultiBlockCoverage.class);
assertCoverage(coveredClasses, "test7", 2);
}
@Test
- public void shouldCalculateCoverageFor8BlockMethods() throws IOException,
- InterruptedException, ExecutionException {
+ public void shouldCalculateCoverageFor8BlockMethods() throws Exception {
final List coveredClasses = runCoverageForTest(TestsForMultiBlockCoverage.class);
assertCoverage(coveredClasses, "test8", 2);
}
@Test
- public void shouldCalculateCoverageFor9BlockMethods() throws IOException,
- InterruptedException, ExecutionException {
+ public void shouldCalculateCoverageFor9BlockMethods() throws Exception {
final List coveredClasses = runCoverageForTest(TestsForMultiBlockCoverage.class);
assertCoverage(coveredClasses, "test9", 2);
}
@@ -150,50 +146,44 @@ public void shouldCalculateCoverageFor10BlockMethods() throws IOException,
}
@Test
- public void shouldCalculateCoverageFor11BlockMethods() throws IOException,
- InterruptedException, ExecutionException {
+ public void shouldCalculateCoverageFor11BlockMethods() throws Exception {
final List coveredClasses = runCoverageForTest(TestsForMultiBlockCoverage.class);
assertCoverage(coveredClasses, "test11", 2);
}
@Test
- public void shouldCalculateCoverageFor12BlockMethods() throws IOException,
- InterruptedException, ExecutionException {
+ public void shouldCalculateCoverageFor12BlockMethods() throws Exception {
final List coveredClasses = runCoverageForTest(TestsForMultiBlockCoverage.class);
assertCoverage(coveredClasses, "test12", 2);
}
@Test
- public void shouldCalculateCoverageFor13BlockMethods() throws IOException,
- InterruptedException, ExecutionException {
+ public void shouldCalculateCoverageFor13BlockMethods() throws Exception {
final List coveredClasses = runCoverageForTest(TestsForMultiBlockCoverage.class);
assertCoverage(coveredClasses, "test13", 2);
}
@Test
- public void shouldCalculateCoverageFor14BlockMethods() throws IOException,
- InterruptedException, ExecutionException {
+ public void shouldCalculateCoverageFor14BlockMethods() throws Exception {
final List coveredClasses = runCoverageForTest(TestsForMultiBlockCoverage.class);
assertCoverage(coveredClasses, "test14", 2);
}
@Test
- public void shouldCalculateCoverageFor15BlockMethods() throws IOException,
- InterruptedException, ExecutionException {
+ public void shouldCalculateCoverageFor15BlockMethods() throws Exception {
final List coveredClasses = runCoverageForTest(TestsForMultiBlockCoverage.class);
assertCoverage(coveredClasses, "test15", 2);
}
@Test
- public void shouldCalculateCoverageForLargeBlockMethods() throws IOException,
- InterruptedException, ExecutionException {
+ public void shouldCalculateCoverageForLargeBlockMethods() throws Exception {
final List coveredClasses = runCoverageForTest(TestsForMultiBlockCoverage.class);
assertCoverage(coveredClasses, "testMany", 2);
}
@Test
public void shouldCalculateCoverageForAllRelevantClasses()
- throws IOException, InterruptedException, ExecutionException {
+ throws Exception{
final List coveredClasses = runCoverageForTest(Tests.class);
@@ -204,7 +194,7 @@ public void shouldCalculateCoverageForAllRelevantClasses()
@Test
public void shouldCalculateCoverageForSmallMethodThatThrowsException()
- throws IOException, InterruptedException, ExecutionException {
+ throws Exception {
final List coveredClasses = runCoverageForTest(TestsClassWithException.class);
assertThat(coveredClasses).anyMatch(coverageFor(CoveredBeforeExceptionTestee.class));
@@ -222,7 +212,7 @@ public void shouldCalculateCoverageForSmallMethodThatThrowsException()
@Test
public void shouldCalculateCoverageForMethodThatThrowsExceptionWithFinallyBlock()
- throws IOException, InterruptedException, ExecutionException {
+ throws Exception {
final List coveredClasses = runCoverageForTest(TestThrowsExceptionInFinallyBlock.class);
final ClassName clazz = ClassName
@@ -237,7 +227,7 @@ public void shouldCalculateCoverageForMethodThatThrowsExceptionWithFinallyBlock(
@Test
public void shouldCalculateCoverageForLargeMethodThatThrowsException()
- throws IOException, InterruptedException, ExecutionException {
+ throws IOException, InterruptedException {
final List coveredClasses = runCoverageForTest(TestThrowsExceptionFromLargeMethodTestee.class);
final ClassName clazz = ClassName
@@ -262,7 +252,7 @@ public void testFoo() {
@Test
public void shouldCalculateCoverageOfClassesRunInDifferentClassLoader()
- throws IOException, InterruptedException, ExecutionException {
+ throws IOException, InterruptedException {
final List coveredClasses = runCoverageForTest(TestInDifferentClassLoader.class);
assertThat(coveredClasses).anyMatch(coverageFor(Testee2.class));
assertThat(coveredClasses).anyMatch(coverageFor(Testee.class));
@@ -314,6 +304,13 @@ public void shouldFailWithExitCode() throws Exception {
assertEquals(ExitCode.JUNIT_ISSUE, exitCode);
}
+ @Test
+ public void handlesParentChildInitializationOrderIssues() throws Exception {
+ final List coveredClasses = runCoverageForTest(ParentChildInitializationTest.class);
+ assertThat(coveredClasses)
+ .anyMatch(coverageFor(ClassName.fromString("com.example.coverage.execute.samples.simple.TesteeChild")));
+ }
+
private ClassPath classPathWithoutJUnit() {
final List cpWithoutJUnit =
ClassPath.getClassPathElementsAsFiles().stream()
@@ -328,7 +325,7 @@ private Predicate failingTest() {
}
private List runCoverageForTest(final Class> test)
- throws IOException, InterruptedException, ExecutionException {
+ throws IOException, InterruptedException {
final List coveredClasses = new ArrayList<>();
@@ -360,16 +357,20 @@ private void runCoverageProcess(final Class> test,
}
}
- private Predicate coverageFor(final Class> class1) {
+ private Predicate coverageFor(final Class> clazz) {
+ return coverageFor(ClassName.fromClass(clazz));
+ }
+
+ private Predicate coverageFor(ClassName clazz) {
return new Predicate() {
@Override
public boolean test(final CoverageResult a) {
- return FCollection.contains(a.getCoverage(), resultFor(class1));
+ return FCollection.contains(a.getCoverage(), resultFor(clazz));
}
- private Predicate resultFor(final Class> class1) {
- return a -> a.isFor(ClassName.fromClass(class1));
+ private Predicate resultFor(ClassName clazz) {
+ return a -> a.isFor(clazz);
}
};
}
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 7ca3321c4..a11f50a1f 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
@@ -14,15 +14,6 @@
*/
package org.pitest.mutationtest.config;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import java.util.Arrays;
-import java.util.Properties;
-
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
@@ -31,6 +22,16 @@
import org.pitest.mutationtest.MutationResultListener;
import org.pitest.mutationtest.MutationResultListenerFactory;
+import java.util.Properties;
+
+import static java.util.Arrays.asList;
+import static java.util.Collections.emptyList;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
public class CompoundListenerFactoryTest {
private CompoundListenerFactory testee;
@@ -44,7 +45,11 @@ public class CompoundListenerFactoryTest {
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- this.testee = new CompoundListenerFactory(Arrays.asList(this.firstChild,
+
+ when(firstChild.provides()).thenReturn(MutationResultListenerFactory.LEGACY_MODE);
+ when(secondChild.provides()).thenReturn(MutationResultListenerFactory.LEGACY_MODE);
+
+ this.testee = new CompoundListenerFactory(emptyList(),asList(this.firstChild,
this.secondChild));
}
@@ -58,9 +63,14 @@ public void shouldCreateACombinedListenerForAllChildFactories() {
when(
this.secondChild.getListener(any(Properties.class),
any(ListenerArguments.class))).thenReturn(listenerTwo);
- this.testee.getListener(null, null).runStart();
+ this.testee.getListener(null, someArgs()).runStart();
verify(listenerOne, times(1)).runStart();
verify(listenerTwo, times(1)).runStart();
}
+ private ListenerArguments someArgs() {
+ return new ListenerArguments(null, null, null, null,
+ 0, false, null);
+ }
+
}
diff --git a/pitest-entry/src/test/java/org/pitest/mutationtest/config/PluginServicesTest.java b/pitest-entry/src/test/java/org/pitest/mutationtest/config/PluginServicesTest.java
index 469a62178..69baf5e71 100644
--- a/pitest-entry/src/test/java/org/pitest/mutationtest/config/PluginServicesTest.java
+++ b/pitest-entry/src/test/java/org/pitest/mutationtest/config/PluginServicesTest.java
@@ -1,15 +1,18 @@
package org.pitest.mutationtest.config;
-import static org.junit.Assert.assertTrue;
-
-import java.util.function.Predicate;
-
import org.junit.Test;
import org.pitest.functional.FCollection;
+import org.pitest.mutationtest.MutationResultListenerFactory;
+import org.pitest.mutationtest.build.MutationInterceptorFactory;
import org.pitest.mutationtest.engine.gregor.config.GregorEngineFactory;
import org.pitest.mutationtest.filter.LimitNumberOfMutationsPerClassFilterFactory;
import org.pitest.mutationtest.report.csv.CSVReportFactory;
+import java.util.function.Predicate;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertTrue;
+
public class PluginServicesTest {
private final PluginServices testee = PluginServices.makeForContextLoader();
@@ -32,6 +35,12 @@ public void shouldListDefaultMutationFilterAsToolClasspathPlugin() {
theClass(LimitNumberOfMutationsPerClassFilterFactory.class)));
}
+ @Test
+ public void shouldListAllTypesOfFeature() {
+ assertThat(testee.findFeatures()).hasAtLeastOneElementOfType(MutationInterceptorFactory.class);
+ assertThat(testee.findFeatures()).hasAtLeastOneElementOfType(MutationResultListenerFactory.class);
+ }
+
private static Predicate