diff --git a/src/bld/java/rife/bld/extension/PitestOperationBuild.java b/src/bld/java/rife/bld/extension/PitestOperationBuild.java index 549099b..3e1f722 100644 --- a/src/bld/java/rife/bld/extension/PitestOperationBuild.java +++ b/src/bld/java/rife/bld/extension/PitestOperationBuild.java @@ -35,7 +35,7 @@ public class PitestOperationBuild extends Project { public PitestOperationBuild() { pkg = "rife.bld.extension"; name = "PitestExtension"; - version = version(0, 9, 7); + version = version(0, 9, 8, "SNAPSHOT"); javaRelease = 17; downloadSources = true; @@ -51,7 +51,7 @@ public class PitestOperationBuild extends Project { .include(dependency("org.pitest", "pitest-junit5-plugin", version(1, 2, 1))) .include(dependency("org.junit.jupiter", "junit-jupiter", version(5, 10, 2))) .include(dependency("org.junit.platform", "junit-platform-console-standalone", version(1, 10, 2))) - .include(dependency("org.assertj", "assertj-core", version(3, 25, 3))); + .include(dependency("org.assertj", "assertj-core", version(3, 26, 0))); javadocOperation() .javadocOptions() diff --git a/src/main/java/rife/bld/extension/PitestOperation.java b/src/main/java/rife/bld/extension/PitestOperation.java index 1f32154..f4b737f 100644 --- a/src/main/java/rife/bld/extension/PitestOperation.java +++ b/src/main/java/rife/bld/extension/PitestOperation.java @@ -293,15 +293,13 @@ public class PitestOperation extends AbstractProcessOperation { } /** - * List of globs to match against test class names. Matching tests will not be run (note if a test suite includes - * an excluded class, then it will “leak” back in). + * JUnit4 runners to exclude. * - * @param excludedTest one ore more excluded tests + * @param runners the runners * @return this operation instance - * @see #excludedTests(Collection) */ - public PitestOperation excludedTests(String... excludedTest) { - options.put("--excludedTests", String.join(",", excludedTest)); + public PitestOperation excludedRunners(String runners) { + options.put("--excludedRunners", runners); return this; } @@ -309,13 +307,26 @@ public class PitestOperation extends AbstractProcessOperation { * List of globs to match against test class names. Matching tests will not be run (note if a test suite includes * an excluded class, then it will “leak” back in). * - * @param excludedTests the excluded tests + * @param testClasses one or more excluded tests * @return this operation instance - * @see #excludedTests(String...) + * @see #excludedTestClasses(Collection) */ - public PitestOperation excludedTests(Collection excludedTests) { - options.put("--excludedTests", - String.join(",", excludedTests.stream().filter(this::isNotBlank).toList())); + public PitestOperation excludedTestClasses(String... testClasses) { + options.put("--excludedTestClasses", String.join(",", testClasses)); + return this; + } + + /** + * List of globs to match against test class names. Matching tests will not be run (note if a test suite includes + * an excluded class, then it will “leak” back in). + * + * @param testClasses the excluded tests + * @return this operation instance + * @see #excludedTestClasses(String...) + */ + public PitestOperation excludedTestClasses(Collection testClasses) { + options.put("--excludedTestClasses", + String.join(",", testClasses.stream().filter(this::isNotBlank).toList())); return this; } @@ -420,6 +431,21 @@ public class PitestOperation extends AbstractProcessOperation { return this; } + /** + * Whether to create a full mutation matrix + * + * @param isFullMutationMatrix {@code true} or {@code false} + * @return this operation instance + */ + public PitestOperation fullMutationMatrix(boolean isFullMutationMatrix) { + if (isFullMutationMatrix) { + options.put("--fullMutationMatrix", TRUE); + } else { + options.put("--fullMutationMatrix", FALSE); + } + return this; + } + /** * Path to a file containing history information for incremental analysis. * @@ -493,6 +519,32 @@ public class PitestOperation extends AbstractProcessOperation { return this; } + /** + * Test methods that should be included for challenging the mutants. + * + * @param testMethod the test method + * @return this operation instance + */ + public PitestOperation includedTestMethods(String testMethod) { + options.put("--includedTestMethods", testMethod); + return this; + } + + /** + * Input encoding. + *

+ * Default is {@code UTF-8}. + * + * @param encoding the encoding + * @return this operation instance + */ + public PitestOperation inputEncoding(String encoding) { + if (isNotBlank(encoding)) { + options.put("--inputEncoding", encoding); + } + return this; + } + /* * Determines if a string is not blank. */ @@ -540,6 +592,17 @@ public class PitestOperation extends AbstractProcessOperation { return this; } + /** + * Maximum number of surviving mutants to allow without throwing an error. + * + * @param maxSurviving the maximin number + * @return this operation instance + */ + public PitestOperation maxSurviving(int maxSurviving) { + options.put("--maxSurviving", String.valueOf(maxSurviving)); + return this; + } + /** * List of classpaths which should be considered to contain mutable code. If your build maintains separate output * directories for tests and production classes this parameter should be set to your code output directory in order @@ -578,6 +641,19 @@ public class PitestOperation extends AbstractProcessOperation { return this; } + /** + * Mutation engine to use. + *

+ * Defaults to {@code gregor} + * + * @param engine the engine + * @return this operation instance + */ + public PitestOperation mutationEngine(String engine) { + options.put("--mutationEngine", engine); + return this; + } + /** * Mutation score threshold below which the build will fail. This is an integer percent (0-100) that represents the * fraction of killed mutations out of all mutations. @@ -595,6 +671,17 @@ public class PitestOperation extends AbstractProcessOperation { return this; } + /** + * Maximum number of mutations to include. + * + * @param size the size + * @return this operation instance + */ + public PitestOperation mutationUnitSize(int size) { + options.put("--mutationUnitSize", String.valueOf(size)); + return this; + } + /** * List of mutation operators. * @@ -635,7 +722,7 @@ public class PitestOperation extends AbstractProcessOperation { } /** - * Comma separated list of formats in which to write mutation results as the mutations are analysed. + * A list of formats in which to write mutation results as the mutations are analysed. * Supported formats are {@code HTML}, {@code XML}, {@code CSV}. *

* Defaults to {@code HTML}. @@ -651,7 +738,7 @@ public class PitestOperation extends AbstractProcessOperation { } /** - * Comma separated list of formats in which to write mutation results as the mutations are analysed. + * A list of formats in which to write mutation results as the mutations are analysed. * Supported formats are {@code HTML}, {@code XML}, {@code CSV}. *

* Defaults to {@code HTML}. @@ -665,6 +752,29 @@ public class PitestOperation extends AbstractProcessOperation { return this; } + /** + * Custom plugin properties. + * + * @param key the key + * @param value the value + * @return this operation instance + */ + public PitestOperation pluginConfiguration(String key, String value) { + options.put("--pluginConfiguration", key + '=' + value); + return this; + } + + /** + * Project base. + * + * @param file the file + * @return this operations instance + */ + public PitestOperation projectBase(String file) { + options.put("--projectBase", file); + return this; + } + /** * Output directory for the reports. * @@ -756,14 +866,14 @@ public class PitestOperation extends AbstractProcessOperation { } /** - * A comma separated list of globs can be supplied to this parameter to limit the tests available to be run. + * A list of globs can be supplied to this parameter to limit the tests available to be run. * If this parameter is not supplied then any test fixture that matched targetClasses may be used, it is however * recommended that this parameter is always explicitly set. *

* This parameter can be used to point PIT to a top level suite or suites. Custom suites such as * ClassPathSuite are supported. * - * @param test one ore more tests + * @param test one or more tests * @return this operation instance * @see #targetTests(Collection) */ @@ -773,7 +883,7 @@ public class PitestOperation extends AbstractProcessOperation { } /** - * A comma separated list of globs can be supplied to this parameter to limit the tests available to be run. + * A list of globs can be supplied to this parameter to limit the tests available to be run. * If this parameter is not supplied then any test fixture that matched targetClasses may be used, it is however * recommended that this parameter is always explicitly set. *

@@ -789,6 +899,17 @@ public class PitestOperation extends AbstractProcessOperation { return this; } + /** + * Test strength score below which to throw an error. + * + * @param threshold the threshold + * @return this operation instance + */ + public PitestOperation testStrengthThreshold(int threshold) { + options.put("--testStrengthThreshold", String.valueOf(threshold)); + return this; + } + /** * The number of threads to use when mutation testing. * @@ -878,4 +999,17 @@ public class PitestOperation extends AbstractProcessOperation { } return this; } + + /** + * The verbosity of output. + *

+ * Defaults to {@code DEFAULT} + * + * @param verbosity the verbosity + * @return this operation instance + */ + public PitestOperation verbosity(String verbosity) { + options.put("--verbosity", verbosity); + return this; + } } diff --git a/src/test/java/rife/bld/extension/PitestOperationTest.java b/src/test/java/rife/bld/extension/PitestOperationTest.java index af0e7c1..2b75278 100644 --- a/src/test/java/rife/bld/extension/PitestOperationTest.java +++ b/src/test/java/rife/bld/extension/PitestOperationTest.java @@ -57,6 +57,121 @@ class PitestOperationTest { assertThat(op.options.get("--avoidCallsTo")).as(AS_LIST).isEqualTo(FOOBAR); } + @Test + void checkAll() { + var params = List.of( + "--argLine", + "--avoidCallsTo", + "--classPath", + "--classPathFile", + "--coverageThreshold", + "--detectInlinedCode", + "--excludedClasses", + "--excludedGroups", + "--excludedMethods", + "--excludedRunners", + "--excludedTestClasses", + "--exportLineCoverage", + "--failWhenNoMutations", + "--features", + "--fullMutationMatrix", + "--historyInputLocation", + "--historyOutputLocation", + "--includeLaunchClasspath", + "--includedGroups", + "--includedTestMethods", + "--inputEncoding", + "--jvmArgs", + "--jvmPath", + "--maxSurviving", + "--mutableCodePaths", + "--mutationEngine", + "--mutationThreshold", + "--mutationUnitSize", + "--mutators", + "--outputEncoding", + "--outputFormats", + "--pluginConfiguration", + "--projectBase", + "--reportDir", + "--skipFailingTests", + "--sourceDirs", + "--targetClasses", + "--targetTests", + "--testStrengthThreshold", + "--threads", + "--timeoutConst", + "--timeoutFactor", + "--timestampedReports", + "--useClasspathJar", + "--verbose", + "--verbosity" + ); + + var args = new PitestOperation() + .fromProject(new BaseProject()) + .argLine(FOO) + .avoidCallsTo(FOO, BAR) + .classPath(FOO, BAR) + .classPathFile(FOO) + .coverageThreshold(0) + .detectInlinedCode(false) + .excludedClasses("class") + .excludedClasses(List.of(FOO, BAR)) + .excludedGroups("group") + .excludedGroups(List.of(FOO, BAR)) + .excludedMethods("method") + .excludedMethods(List.of(FOO, BAR)) + .excludedTestClasses("test") + .excludedRunners("runners") + .exportLineCoverage(true) + .failWhenNoMutations(true) + .features("feature") + .fullMutationMatrix(true) + .historyInputLocation("inputLocation") + .historyOutputLocation("outputLocation") + .includeLaunchClasspath(true) + .includedGroups("group") + .includedTestMethods("method") + .inputEncoding("encoding") + .jvmArgs("-XX:+UnlogregckDiagnosticVMOptions") + .jvmPath("path") + .maxSurviving(1) + .mutableCodePaths("codePaths") + .mutationEngine("engine") + .mutationThreshold(0) + .mutationUnitSize(1) + .mutators(List.of(FOO, BAR)) + .outputEncoding("encoding") + .outputFormats("json") + .pluginConfiguration("key", "value") + .projectBase("base") + .reportDir("dir") + .skipFailingTests(true) + .targetClasses("class") + .targetTests("test") + .testStrengthThreshold(0) + .threads(0) + .timeoutConst(0) + .timeoutFactor(0) + .timestampedReports(true) + .useClasspathJar(true) + .verbose(true) + .verbosity("default") + .executeConstructProcessCommandList(); + + for (var p : params) { + var found = false; + for (var a : args) { + if (a.startsWith(p)) { + found = true; + break; + } + } + assertThat(found).as(p + " not found.").isTrue(); + } + } + @Test void classPath() { var op = new PitestOperation() @@ -143,17 +258,25 @@ class PitestOperationTest { assertThat(op.options.get("--excludedMethods")).as(AS_LIST).isEqualTo(FOOBAR); } + @Test + void excludedRunners() { + var op = new PitestOperation() + .fromProject(new BaseProject()) + .excludedRunners(FOO); + assertThat(op.options.get("--excludedRunners")).isEqualTo(FOO); + } + @Test void excludedTests() { var op = new PitestOperation() .fromProject(new BaseProject()) - .excludedTests(FOO, BAR); - assertThat(op.options.get("--excludedTests")).isEqualTo(FOOBAR); + .excludedTestClasses(FOO, BAR); + assertThat(op.options.get("--excludedTestClasses")).isEqualTo(FOOBAR); op = new PitestOperation() .fromProject(new Project()) - .excludedTests(List.of(FOO, BAR)); - assertThat(op.options.get("--excludedTests")).as("as list").isEqualTo(FOOBAR); + .excludedTestClasses(List.of(FOO, BAR)); + assertThat(op.options.get("--excludedTestClasses")).as("as list").isEqualTo(FOOBAR); } @Test @@ -246,6 +369,14 @@ class PitestOperationTest { assertThat(op.options.get("--features")).as(AS_LIST).isEqualTo(FOOBAR); } + @Test + void fullMutationMatrix() { + var op = new PitestOperation() + .fromProject(new BaseProject()) + .fullMutationMatrix(true); + assertThat(op.options.get("--fullMutationMatrix")).isEqualTo(TRUE); + } + @Test void historyInputLocation() { var op = new PitestOperation() @@ -288,6 +419,22 @@ class PitestOperationTest { assertThat(op.options.get("--includedGroups")).as(AS_LIST).isEqualTo(FOOBAR); } + @Test + void includedTestMethods() { + var op = new PitestOperation() + .fromProject(new Project()) + .includedTestMethods(FOO); + assertThat(op.options.get("--includedTestMethods")).isEqualTo(FOO); + } + + @Test + void inputEncoding() { + var op = new PitestOperation() + .fromProject(new BaseProject()) + .inputEncoding(FOO); + assertThat(op.options.get("--inputEncoding")).isEqualTo(FOO); + } + @Test void jvmArgs() { var op = new PitestOperation() @@ -309,6 +456,14 @@ class PitestOperationTest { assertThat(op.options.get("--jvmPath")).isEqualTo(FOO); } + @Test + void maxSurviving() { + var op = new PitestOperation() + .fromProject(new Project()) + .maxSurviving(1); + assertThat(op.options.get("--maxSurviving")).isEqualTo("1"); + } + @Test void mutableCodePaths() { var op = new PitestOperation() @@ -322,6 +477,14 @@ class PitestOperationTest { assertThat(op.options.get("--mutableCodePaths")).as(AS_LIST).isEqualTo(FOOBAR); } + @Test + void mutationEngine() { + var op = new PitestOperation() + .fromProject(new Project()) + .mutationEngine(FOO); + assertThat(op.options.get("--mutationEngine")).isEqualTo(FOO); + } + @Test void mutationThreshold() { var op = new PitestOperation() @@ -335,6 +498,14 @@ class PitestOperationTest { assertThat(op.options.get("--mutationThreshold")).isNull(); } + @Test + void mutationUnitSize() { + var op = new PitestOperation() + .fromProject(new Project()) + .mutationUnitSize(2); + assertThat(op.options.get("--mutationUnitSize")).isEqualTo("2"); + } + @Test void mutators() { var op = new PitestOperation() @@ -369,6 +540,22 @@ class PitestOperationTest { assertThat(op.options.get("--outputFormats")).as(AS_LIST).isEqualTo(FOOBAR); } + @Test + void pluginConfiguration() { + var op = new PitestOperation() + .fromProject(new Project()) + .pluginConfiguration(FOO, BAR); + assertThat(op.options.get("--pluginConfiguration")).isEqualTo(FOO + "=" + BAR); + } + + @Test + void projectBase() { + var op = new PitestOperation() + .fromProject(new Project()) + .projectBase(FOO); + assertThat(op.options.get("--projectBase")).isEqualTo(FOO); + } + @Test void reportDir() { var op = new PitestOperation() @@ -429,6 +616,14 @@ class PitestOperationTest { assertThat(op.options.get("--targetTests")).as(AS_LIST).isEqualTo(FOOBAR); } + @Test + void testStrengthThreshold() { + var op = new PitestOperation() + .fromProject(new Project()) + .testStrengthThreshold(6); + assertThat(op.options.get("--testStrengthThreshold")).isEqualTo("6"); + } + @Test void threads() { var op = new PitestOperation() @@ -491,4 +686,12 @@ class PitestOperationTest { .verbose(false); assertThat(op.options.get("--verbose")).isEqualTo(FALSE); } + + @Test + void verbosity() { + var op = new PitestOperation() + .fromProject(new Project()) + .verbosity(FOO); + assertThat(op.options.get("--verbosity")).isEqualTo(FOO); + } }