Skip to content

Commit

Permalink
Merge pull request #930 from hcoles/pluggable_mutators
Browse files Browse the repository at this point in the history
pluggable mutators
  • Loading branch information
hcoles authored Sep 1, 2021
2 parents 6996a97 + 15ceef5 commit 979a7df
Show file tree
Hide file tree
Showing 128 changed files with 755 additions and 557 deletions.
19 changes: 13 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,23 @@ Read all about it at http://pitest.org

## Releases

### current snapshot
### current snapshot (1.7.0)

TBC - release version will be 1.7.0 due to internal changes that may
break some 3rd party plugins.
* #923 Internal interface changes
* #930 Pluggable mutators

Due to internal changes some third party plugins maybe incompatible with this release.

All history files should be deleted before upgrading.

The names of the remove conditionals mutators have changed slightly as a result of #930 and
may need to be updated in build scripts if explicitly activated.

### 1.6.9

* #922 Filter equivalent stream.empty mutants in flatMap calls
* #921 Guarantee order of mutation operators
* #919 Filter junk mutations in java records
* #922 Filter equivalent stream.empty mutants in flatMap calls
* #921 Guarantee order of mutation operators
* #919 Filter junk mutations in java records

### 1.6.8

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,11 @@ public void shouldParseCommaSeparatedListOfJVMArgs() {
@Test
public void shouldParseCommaSeparatedListOfMutationOperators() {
final ReportOptions actual = parseAddingRequiredArgs("--mutators",
ConditionalsBoundaryMutator.CONDITIONALS_BOUNDARY_MUTATOR.name() + ","
+ MathMutator.MATH_MUTATOR.name());
ConditionalsBoundaryMutator.CONDITIONALS_BOUNDARY.name() + ","
+ MathMutator.MATH.name());
assertEquals(Arrays.asList(
ConditionalsBoundaryMutator.CONDITIONALS_BOUNDARY_MUTATOR.name(),
MathMutator.MATH_MUTATOR.name()), actual.getMutators());
ConditionalsBoundaryMutator.CONDITIONALS_BOUNDARY.name(),
MathMutator.MATH.name()), actual.getMutators());
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@
import org.pitest.mutationtest.build.MutationInterceptorFactory;
import org.pitest.mutationtest.engine.Mutater;
import org.pitest.mutationtest.engine.MutationDetails;
import org.pitest.mutationtest.engine.gregor.mutators.BooleanFalseReturnValsMutator;
import org.pitest.mutationtest.engine.gregor.mutators.BooleanTrueReturnValsMutator;
import org.pitest.mutationtest.engine.gregor.mutators.EmptyObjectReturnValsMutator;
import org.pitest.mutationtest.engine.gregor.mutators.NullReturnValsMutator;
import org.pitest.mutationtest.engine.gregor.mutators.PrimitiveReturnsMutator;
import org.pitest.mutationtest.engine.gregor.mutators.returns.BooleanFalseReturnValsMutator;
import org.pitest.mutationtest.engine.gregor.mutators.returns.BooleanTrueReturnValsMutator;
import org.pitest.mutationtest.engine.gregor.mutators.returns.EmptyObjectReturnValsMutator;
import org.pitest.mutationtest.engine.gregor.mutators.returns.NullReturnValsMutator;
import org.pitest.mutationtest.engine.gregor.mutators.returns.PrimitiveReturnsMutator;
import org.pitest.plugin.Feature;
import org.pitest.sequence.Context;
import org.pitest.sequence.Match;
Expand Down Expand Up @@ -95,7 +95,7 @@ class HardCodedTrueEquivalentFilter implements MutationInterceptor {
private static final Set<String> MUTATOR_IDS = new HashSet<>();

static {
MUTATOR_IDS.add(BooleanTrueReturnValsMutator.BOOLEAN_TRUE_RETURN.getGloballyUniqueId());
MUTATOR_IDS.add(BooleanTrueReturnValsMutator.TRUE_RETURNS.getGloballyUniqueId());
}

private ClassTree currentClass;
Expand Down Expand Up @@ -159,8 +159,8 @@ class PrimitiveEquivalentFilter implements MutationInterceptor {
ZERO_CONSTANTS.add(Opcodes.FCONST_0);
ZERO_CONSTANTS.add(Opcodes.DCONST_0);

MUTATOR_IDS.add(PrimitiveReturnsMutator.PRIMITIVE_RETURN_VALS_MUTATOR.getGloballyUniqueId());
MUTATOR_IDS.add(BooleanFalseReturnValsMutator.BOOLEAN_FALSE_RETURN.getGloballyUniqueId());
MUTATOR_IDS.add(PrimitiveReturnsMutator.PRIMITIVE_RETURNS.getGloballyUniqueId());
MUTATOR_IDS.add(BooleanFalseReturnValsMutator.FALSE_RETURNS.getGloballyUniqueId());
}

private ClassTree currentClass;
Expand Down Expand Up @@ -224,8 +224,8 @@ class EmptyReturnsFilter implements MutationInterceptor {
ZERO_CONSTANTS.add(Opcodes.FCONST_0);
ZERO_CONSTANTS.add(Opcodes.DCONST_0);

MUTATOR_IDS.add(EmptyObjectReturnValsMutator.EMPTY_RETURN_VALUES.getGloballyUniqueId());
MUTATOR_IDS.add(BooleanFalseReturnValsMutator.BOOLEAN_FALSE_RETURN.getGloballyUniqueId());
MUTATOR_IDS.add(EmptyObjectReturnValsMutator.EMPTY_RETURNS.getGloballyUniqueId());
MUTATOR_IDS.add(BooleanFalseReturnValsMutator.FALSE_RETURNS.getGloballyUniqueId());
}

private ClassTree currentClass;
Expand Down Expand Up @@ -314,7 +314,7 @@ public void end() {

class NullReturnsFilter implements MutationInterceptor {

private static final String MUTATOR_ID = NullReturnValsMutator.NULL_RETURN_VALUES.getGloballyUniqueId();
private static final String MUTATOR_ID = NullReturnValsMutator.NULL_RETURNS.getGloballyUniqueId();

private ClassTree currentClass;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import org.pitest.mutationtest.engine.Location;
import org.pitest.mutationtest.engine.Mutater;
import org.pitest.mutationtest.engine.MutationDetails;
import org.pitest.mutationtest.engine.gregor.mutators.NullReturnValsMutator;
import org.pitest.mutationtest.engine.gregor.mutators.returns.NullReturnValsMutator;
import org.pitest.sequence.Context;
import org.pitest.sequence.Match;
import org.pitest.sequence.QueryParams;
Expand Down Expand Up @@ -97,7 +97,7 @@ public Collection<MutationDetails> intercept(Collection<MutationDetails> mutatio
}

private boolean isStreamEmptyMutantWithOnlyFlatMapCalls(MutationDetails mutationDetails) {
if (!mutationDetails.getMutator().equals(NullReturnValsMutator.NULL_RETURN_VALUES.getGloballyUniqueId())) {
if (!mutationDetails.getMutator().equals(NullReturnValsMutator.NULL_RETURNS.getGloballyUniqueId())) {
return false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public class ExcludedAnnotationInterceptorTest {
@Before
public void setUp() {
final ClassloaderByteArraySource source = ClassloaderByteArraySource.fromContext();
final Collection<MethodMutatorFactory> mutators = Collections.singleton((MethodMutatorFactory)VoidMethodCallMutator.VOID_METHOD_CALL_MUTATOR);
final Collection<MethodMutatorFactory> mutators = Collections.singleton((MethodMutatorFactory)VoidMethodCallMutator.VOID_METHOD_CALLS);
this.mutator = new GregorMutater(source, m -> true, mutators);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public void shouldNotFilterShortCutMutantsNotInEqualsMethods() {
@Test
public void shouldNotFilterGeneralMutantsInEqualMethods() {
final GregorMutater mutator = createMutator(
ReturnValsMutator.RETURN_VALS_MUTATOR);
ReturnValsMutator.RETURN_VALS);
final List<MutationDetails> mutations = mutator
.findMutations(ClassName.fromClass(HasNonShortCutEquals.class));
assertThat(mutations).hasSize(1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
import org.pitest.mutationtest.build.InterceptorType;
import org.pitest.mutationtest.build.MutationInterceptor;
import org.pitest.mutationtest.build.intercept.javafeatures.FilterTester;
import org.pitest.mutationtest.engine.gregor.mutators.EmptyObjectReturnValsMutator;
import org.pitest.mutationtest.engine.gregor.mutators.NullReturnValsMutator;
import org.pitest.mutationtest.engine.gregor.mutators.PrimitiveReturnsMutator;
import org.pitest.mutationtest.engine.gregor.mutators.returns.EmptyObjectReturnValsMutator;
import org.pitest.mutationtest.engine.gregor.mutators.returns.NullReturnValsMutator;
import org.pitest.mutationtest.engine.gregor.mutators.returns.PrimitiveReturnsMutator;

import java.util.ArrayList;
import java.util.Collections;
Expand All @@ -15,18 +15,18 @@
import java.util.Set;

import static org.assertj.core.api.Assertions.assertThat;
import static org.pitest.mutationtest.engine.gregor.mutators.BooleanFalseReturnValsMutator.BOOLEAN_FALSE_RETURN;
import static org.pitest.mutationtest.engine.gregor.mutators.BooleanTrueReturnValsMutator.BOOLEAN_TRUE_RETURN;
import static org.pitest.mutationtest.engine.gregor.mutators.returns.BooleanFalseReturnValsMutator.FALSE_RETURNS;
import static org.pitest.mutationtest.engine.gregor.mutators.returns.BooleanTrueReturnValsMutator.TRUE_RETURNS;

public class EquivalentReturnMutationFilterTest {

MutationInterceptor testee = new EquivalentReturnMutationFilter().createInterceptor(null);

FilterTester verifier = new FilterTester("", this.testee, PrimitiveReturnsMutator.PRIMITIVE_RETURN_VALS_MUTATOR
, EmptyObjectReturnValsMutator.EMPTY_RETURN_VALUES
, NullReturnValsMutator.NULL_RETURN_VALUES
, BOOLEAN_FALSE_RETURN
, BOOLEAN_TRUE_RETURN);
FilterTester verifier = new FilterTester("", this.testee, PrimitiveReturnsMutator.PRIMITIVE_RETURNS
, EmptyObjectReturnValsMutator.EMPTY_RETURNS
, NullReturnValsMutator.NULL_RETURNS
, FALSE_RETURNS
, TRUE_RETURNS);

@Test
public void shouldDeclareTypeAsFilter() {
Expand Down Expand Up @@ -55,19 +55,19 @@ public void filtersEquivalentPrimitiveIntMutantsInTryCatch() {

@Test
public void filtersEquivalentPrimitiveBooleanMutants() {
this.verifier.assertFiltersMutationsFromMutator(BOOLEAN_FALSE_RETURN.getGloballyUniqueId()
this.verifier.assertFiltersMutationsFromMutator(FALSE_RETURNS.getGloballyUniqueId()
, AlreadyReturnsFalse.class);
}

@Test
public void filtersEquivalentPrimitiveBooleanTrueMutants() {
this.verifier.assertFiltersMutationsFromMutator(BOOLEAN_TRUE_RETURN.getGloballyUniqueId()
this.verifier.assertFiltersMutationsFromMutator(TRUE_RETURNS.getGloballyUniqueId()
, ReturnsTrue.class);
}

@Test
public void filtersEquivalentPrimitiveBooleanTrueMutantsInTryCatch() {
this.verifier.assertFiltersMutationsFromMutator(BOOLEAN_TRUE_RETURN.getGloballyUniqueId()
this.verifier.assertFiltersMutationsFromMutator(TRUE_RETURNS.getGloballyUniqueId()
, ReturnsTrueInTryCatch.class);
}

Expand All @@ -93,7 +93,7 @@ public void filtersEquivalentBoxedBooleanMutants() {

@Test
public void filtersEquivalentBoxedBooleanTrueMutants() {
this.verifier.assertFiltersMutationsFromMutator(BOOLEAN_TRUE_RETURN.getGloballyUniqueId()
this.verifier.assertFiltersMutationsFromMutator(TRUE_RETURNS.getGloballyUniqueId()
, AlreadyReturnsBoxedTrue.class);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import org.pitest.mutationtest.build.MutationInterceptor;
import org.pitest.mutationtest.build.intercept.javafeatures.FilterTester;
import org.pitest.mutationtest.engine.gregor.mutators.NullMutateEverything;
import org.pitest.mutationtest.engine.gregor.mutators.NullReturnValsMutator;
import org.pitest.mutationtest.engine.gregor.mutators.returns.NullReturnValsMutator;

import java.util.List;
import java.util.stream.Stream;
Expand All @@ -16,7 +16,7 @@ public class NullFlatmapTest {

MutationInterceptor testee = new NullFlatMapFilterFactory().createInterceptor(null);

FilterTester verifier = new FilterTester("", this.testee, NullReturnValsMutator.NULL_RETURN_VALUES,
FilterTester verifier = new FilterTester("", this.testee, NullReturnValsMutator.NULL_RETURNS,
new NullMutateEverything());

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
import org.pitest.mutationtest.engine.MutationDetails;
import java.util.function.Predicate;

import static org.pitest.mutationtest.engine.gregor.mutators.VoidMethodCallMutator.VOID_METHOD_CALL_MUTATOR;
import static org.pitest.mutationtest.engine.gregor.mutators.VoidMethodCallMutator.VOID_METHOD_CALLS;

public class EnumConstructorTest {

EnumConstructorFilter testee = new EnumConstructorFilter();

FilterTester verifier = new FilterTester("unused", this.testee, VOID_METHOD_CALL_MUTATOR);
FilterTester verifier = new FilterTester("unused", this.testee, VOID_METHOD_CALLS);

@Test
public void filtersMutantsFromEnumConstructor() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,34 +26,34 @@ public void declaresTypeAsFilter() {

@Test
public void filtersMutationsToForEachLoopJumps() {
this.verifier = new FilterTester(PATH, this.testee, NegateConditionalsMutator.NEGATE_CONDITIONALS_MUTATOR);
this.verifier = new FilterTester(PATH, this.testee, NegateConditionalsMutator.NEGATE_CONDITIONALS);
this.verifier.assertFiltersNMutationFromSample(1, "HasForEachLoop");
}

@Test
public void filtersMutationsToHasNextAndNext() {
this.verifier = new FilterTester(PATH, this.testee, NonVoidMethodCallMutator.NON_VOID_METHOD_CALL_MUTATOR);
this.verifier = new FilterTester(PATH, this.testee, NonVoidMethodCallMutator.NON_VOID_METHOD_CALLS);
// can mutate calls to iterator, hasNext and next
this.verifier.assertFiltersNMutationFromSample(3, "HasForEachLoop");
}

@Test
public void filtersMutationsToForEachOverField() {
this.verifier = new FilterTester(PATH, this.testee, NonVoidMethodCallMutator.NON_VOID_METHOD_CALL_MUTATOR);
this.verifier = new FilterTester(PATH, this.testee, NonVoidMethodCallMutator.NON_VOID_METHOD_CALLS);
// can mutate calls to iterator, hasNext and next
this.verifier.assertFiltersNMutationFromClass(3, HasForEachLoopOverField.class);
}

@Test
public void filtersMutationsToForEachOverMethodReturn() {
this.verifier = new FilterTester(PATH, this.testee, NonVoidMethodCallMutator.NON_VOID_METHOD_CALL_MUTATOR);
this.verifier = new FilterTester(PATH, this.testee, NonVoidMethodCallMutator.NON_VOID_METHOD_CALLS);
// can mutate calls to iterator, hasNext and next
this.verifier.assertFiltersNMutationFromClass(3, HasForEachLoopOverMethodReturn.class);
}

@Test
public void filtersMutationsToForEachOverCollections() {
this.verifier = new FilterTester(PATH, this.testee, NonVoidMethodCallMutator.NON_VOID_METHOD_CALL_MUTATOR);
this.verifier = new FilterTester(PATH, this.testee, NonVoidMethodCallMutator.NON_VOID_METHOD_CALLS);
// can mutate calls to iterator, hasNext and next
this.verifier.assertFiltersNMutationFromClass(3, HasForEachLoopOverCollection.class);
}
Expand All @@ -67,7 +67,7 @@ public void filtersMutationsToForEachOverArrays() {

@Test
public void doesNotFilterMutationsToIndexedForLoopJumps() {
this.verifier = new FilterTester("forloops/{0}_{1}", this.testee, NegateConditionalsMutator.NEGATE_CONDITIONALS_MUTATOR);
this.verifier = new FilterTester("forloops/{0}_{1}", this.testee, NegateConditionalsMutator.NEGATE_CONDITIONALS);
this.verifier.assertFiltersNMutationFromSample(0, "HasAForLoop");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@

import static java.util.Arrays.asList;
import static org.junit.Assert.assertEquals;
import static org.pitest.mutationtest.engine.gregor.mutators.IncrementsMutator.INCREMENTS_MUTATOR;
import static org.pitest.mutationtest.engine.gregor.mutators.VoidMethodCallMutator.VOID_METHOD_CALL_MUTATOR;
import static org.pitest.mutationtest.engine.gregor.mutators.IncrementsMutator.INCREMENTS;
import static org.pitest.mutationtest.engine.gregor.mutators.VoidMethodCallMutator.VOID_METHOD_CALLS;

public class InlinedFinallyBlockFilterTest {

Expand All @@ -20,7 +20,7 @@ public class InlinedFinallyBlockFilterTest {
// omit aspectJ. Filter doesn't work correctly with it, but slack is picked up by the
// try with resources filter
asList("javac", "javac11", "ecj"),
VOID_METHOD_CALL_MUTATOR, INCREMENTS_MUTATOR);
VOID_METHOD_CALLS, INCREMENTS);

@Test
public void shouldDeclareTypeAsFilter() {
Expand All @@ -35,19 +35,19 @@ public void doesNotFilterWhenNoFinallyBlock() {
@Test
public void combinesMutationsInSimpleFinallyBlocks() {
verifier.assertFiltersNMutationFromClass(1, HasFinallyBlock.class);
verifier.assertCombinedMutantExists(forMutator(INCREMENTS_MUTATOR), HasFinallyBlock.class);
verifier.assertCombinedMutantExists(forMutator(INCREMENTS), HasFinallyBlock.class);
}

@Test
public void combinesMutationsInFinallyBlocksWithExceptionHandlers() {
verifier.assertFiltersNMutationFromClass(2, HasFinallyBlockAndExceptionHandler.class);
verifier.assertCombinedMutantExists(forMutator(INCREMENTS_MUTATOR), HasFinallyBlockAndExceptionHandler.class);
verifier.assertCombinedMutantExists(forMutator(INCREMENTS), HasFinallyBlockAndExceptionHandler.class);
}

@Test
public void combinesSimilarMutationsInFinallyBlocksWhenOnDifferentLines() {
verifier.assertFiltersNMutationFromClass(2, HasSimilarMutationsFinallyBlock.class);
verifier.assertCombinedMutantExists(forMutator(INCREMENTS_MUTATOR), HasSimilarMutationsFinallyBlock.class);
verifier.assertCombinedMutantExists(forMutator(INCREMENTS), HasSimilarMutationsFinallyBlock.class);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class AvoidForLoopCounterTest {

AvoidForLoopCounterFilter testee = new AvoidForLoopCounterFilter();
private static final String PATH = "forloops/{0}_{1}";
FilterTester verifier = new FilterTester(PATH, this.testee, IncrementsMutator.INCREMENTS_MUTATOR);
FilterTester verifier = new FilterTester(PATH, this.testee, IncrementsMutator.INCREMENTS);


@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ InfiniteLoopFilter testee() {

@Test
public void shouldFilterMutationsThatRemoveForLoopIncrement() {
GregorMutater mutator = createMutator(RemoveIncrementsMutator.REMOVE_INCREMENTS_MUTATOR);
GregorMutater mutator = createMutator(RemoveIncrementsMutator.REMOVE_INCREMENTS);
List<MutationDetails> mutations = mutator.findMutations(ClassName.fromClass(MutateMyForLoop.class));
assertThat(mutations).hasSize(2);

Expand All @@ -41,7 +41,7 @@ public void shouldFilterMutationsThatRemoveForLoopIncrement() {

@Test
public void shouldNotFilterMutationsInMethodsThatAppearToAlreadyHaveInfiniteLoops() {
GregorMutater mutator = createMutator(RemoveIncrementsMutator.REMOVE_INCREMENTS_MUTATOR);
GregorMutater mutator = createMutator(RemoveIncrementsMutator.REMOVE_INCREMENTS);
// our analysis incorrectly identifies some loops as infinite - must skip these
List<MutationDetails> mutations = mutator.findMutations(ClassName.fromClass(DontFilterMyAlreadyInfiniteLoop.class));
assertThat(mutations).hasSize(1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ InfiniteIteratorLoopFilter testee() {

@Test
public void shouldNotFilterMutationsInMethodsThatAppearToAlreadyHaveInfiniteLoops() {
final GregorMutater mutator = createMutator(RemoveIncrementsMutator.REMOVE_INCREMENTS_MUTATOR);
final GregorMutater mutator = createMutator(RemoveIncrementsMutator.REMOVE_INCREMENTS);
// our analysis incorrectly identifies some loops as infinite - must skip these
final List<MutationDetails> mutations = mutator.findMutations(ClassName.fromClass(DontFilterMyAlreadyInfiniteLoop.class));
assertThat(mutations).hasSize(1);
Expand All @@ -38,7 +38,7 @@ public void shouldNotFilterMutationsInMethodsThatAppearToAlreadyHaveInfiniteLoop

@Test
public void shouldFilterMutationsThatRemoveIteratorNextCalls() {
final GregorMutater mutator = createMutator(NonVoidMethodCallMutator.NON_VOID_METHOD_CALL_MUTATOR);
final GregorMutater mutator = createMutator(NonVoidMethodCallMutator.NON_VOID_METHOD_CALLS);
final List<MutationDetails> mutations = mutator.findMutations(ClassName.fromClass(MutateMyForEachLoop.class));
assertThat(mutations).hasSize(3);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
import org.pitest.testapi.execute.FindTestUnits;
import org.pitest.util.ExitCode;
import org.pitest.util.Glob;
import org.pitest.util.IsolationUtils;
import org.pitest.util.Log;
import org.pitest.util.SafeDataInputStream;
import sun.pitest.CodeCoverageStore;
Expand Down Expand Up @@ -159,7 +158,7 @@ private static List<TestUnit> discoverTests(final Configuration testPlugin,

private static Configuration createTestPlugin(
final CoverageOptions paramsFromParent) {
final ClientPluginServices plugins = new ClientPluginServices(IsolationUtils.getContextClassLoader());
final ClientPluginServices plugins = ClientPluginServices.makeForContextLoader();
final MinionSettings factory = new MinionSettings(plugins);
return factory.getTestFrameworkPlugin(paramsFromParent.getPitConfig(), ClassloaderByteArraySource.fromContext());
}
Expand Down
Loading

0 comments on commit 979a7df

Please sign in to comment.