All Stryker versions support a variety of different mutators. We've aligned on a standard naming scheme so it is easy to switch and compare implementations. The difference in support is listed below.
Supportโ
Arithmetic Operatorโ
Mutant operator | Original | Mutated |
---|
AdditionNegation | a + b | a - b |
SubtractionNegation | a - b | a + b |
MultiplicationNegation | a * b | a / b |
DivisionNegation | a / b | a * b |
RemainderToMultiplication | a % b | a * b |
๐ Back to Top
Array Declarationโ
Mutant operator | Original | Mutated |
---|
ArrayConstructorItemsRemoval | new Array(1, 2, 3, 4) | new Array() |
ArrayLiteralItemsRemoval | [1, 2, 3, 4] | [ ] |
๐ Back to Top
Assignment Expressionโ
Mutant operator | Original | Mutated |
---|
AdditionAssignmentNegation | += | -= |
SubtractionAssignmentNegation | -= | += |
MultiplicationAssignmentNegation | *= | /= |
DivisionAssignmentNegation | /= | *= |
RemainderAssignmentToMultiplicationAssignment | %= | *= |
LeftShiftAssignmentNegation | <<= | >>= |
RightShiftAssignmentNegation | >>= | <<= |
BitwiseAndAssignmentNegation | &= | |= |
BitwiseOrAssignmentNegation | |= | &= |
NullCoalescingAssignmentToAndAssignment | ??= | &&= ยน |
- ยน: Only supported by Stryker-JS
๐ Back to Top
Block Statementโ
This group has one mutant operator, the BlockRemoval
mutant operator. This mutant operator removes the content of every block statement. For example the code:
function saySomething() {
console.log('Hello world!');
}
becomes:
function saySomething() {}
๐ Back to Top
Boolean Literalโ
Mutant operator | Original | Mutated |
---|
TrueNegation | true | false |
FalseNegation | false | true |
NotRemoval | !(a == b) | a == b ยน |
- ยน: Not supported by Stryker4s
๐ Back to Top
Checked Statementโ
Stryker.NET specific mutator
Mutant operator | Original | Mutated |
---|
CheckedRemoval | checked(2 + 4) | 2 + 4 |
๐ Back to Top
Conditional Expressionโ
Mutant Operator | Original | Mutated |
---|
LessThanToFalse | for (var i = 0; i < 10; i++) { } | for (var i = 0; false; i++) { } ยน |
GreaterThanToFalse | while (a > b) { } | while (false) { } |
GreaterThanToFalse | do { } while (a > b); | do { } while (false); |
GreaterThanToTrue | if (a > b) { } | if (true) { } |
GreaterThanToFalse | if (a > b) { } | if (false) { } |
GreaterThanToTrue | var x = a > b ? 1 : 2; | var x = true ? 1 : 2; ยน |
GreaterThanToFalse | var x = a > b ? 1 : 2; | var x = false ? 1 : 2; ยน |
- ยน: Not supported by Stryker4s
๐ Back to Top
Equality Operatorโ
Mutant operator | Original | Mutated |
---|
LessThanBoundary | a < b | a <= b |
LessThanNegation | a < b | a >= b |
LessThanEqualBoundary | a <= b | a < b |
LessThanEqualNegation | a <= b | a > b |
GreaterThanBoundary | a > b | a >= b |
GreaterThanNegation | a > b | a <= b |
GreaterThanEqualBoundary | a >= b | a > b |
GreaterThanEqualNegation | a >= b | a < b |
EqualityNegation | a == b | a != b |
InequalityNegation | a != b | a == b |
StrictEqualityNegation | a === b | a !== b ยน |
StrictInequalityNegation | a !== b | a === b ยน |
- ยน: Only supported on StrykerJS and Stryker4s
๐ Back to Top
Logical Operatorโ
Mutant operator | Original | Mutated |
---|
AndNegation | a && b | a || b |
OrNegation | a || b | a && b |
NullCoalescingToAnd | a ?? b | a && b |
๐ Back to Top
Method Expressionโ
Due to differences in language syntax, method expressions are implemented differently in each Stryker framework:
StrykerJSโ
Mutant operator | Original | Mutated |
---|
EndsWithToStartsWith | endsWith() | startsWith() |
StartsWithToEndsWith | startsWith() | endsWith() |
TrimToTrimEnd | trim() | trimEnd() |
TrimToTrimStart | trimEnd() | trimStart() |
TrimToTrimEnd | trimStart() | trimEnd() |
SubstrRemoval | substr() | |
SubstringRemoval | substring() | |
UpperCaseToLowerCase | toUpperCase() | toLowerCase() |
LowerCaseToUpperCase | toLowerCase() | toUpperCase() |
LocalLowerCaseToLocalUpperCase | toLocalLowerCase() | toLocalUpperCase() |
LocalUpperCaseToLocalLowerCase | toLocalUpperCase() | toLocalLowerCase() |
SortRemoval | sort() | |
SomeToEvery | some() | every() |
EveryToSome | every() | some() |
ReverseRemoval | reverse() | |
FilterRemoval | filter() | |
SliceRemoval | slice() | |
CharAtRemoval | charAt() | |
MinToMax | min() | max() |
MaxToMin | max() | min() |
Stryker.NETโ
Mutant operator | Original | Mutated |
---|
DistinctRemoval | Distinct() | |
ReverseRemoval | Reverse() | |
OrderByRemoval | OrderBy() | |
OrderByDescendingRemoval | OrderByDescending() | |
SingleOrDefaultToFirstOrDefault | SingleOrDefault() | FirstOrDefault() |
FirstOrDefaultToSingleOrDefault | FirstOrDefault() | SingleOrDefault() |
FirstToLast | First() | Last() |
LastToFirst | Last() | First() |
AllToAny | All() | Any() |
AnyToAll | Any() | All() |
SkipToTake | Skip() | Take() |
TakeToSkip | Take() | Skip() |
SkipWhileToTakeWhile | SkipWhile() | TakeWhile() |
TakeWhileToSkipWhile | TakeWhile() | SkipWhile() |
MinToMax | Min() | Max() |
MaxToMin | Max() | Min() |
SumToCount | Sum() | Count() |
CountToSum | Count() | Sum() |
Stryker4sโ
Mutant operator | Original | Mutated |
---|
FilterNegation | a.filter(b) | a.filterNot(b) |
FilterNotNegation | a.filterNot(b) | a.filter(b) |
ExistsToForAll | a.exists(b) | a.forall(b) |
ForAllToExists | a.forall(b) | a.exists(b) |
TakeToDrop | a.take(b) | a.drop(b) |
DropToTake | a.drop(b) | a.take(b) |
TakeRightNegation | a.takeRight(b) | a.dropRight(b) |
DropRightNegation | a.dropRight(b) | a.takeRight(b) |
TakeWhileToDropWile | a.takeWhile(b) | a.dropWhile(b) |
DropWhileToTakeWhile | a.dropWhile(b) | a.takeWhile(b) |
IsEmptyNegation | a.isEmpty | a.nonEmpty |
IsNonEmptyNegation | a.nonEmpty | a.isEmpty |
IndexOfToLastIndexOf | a.indexOf | a.lastIndexOf(b) |
LastIndexOfToIndexOf | a.lastIndexOf(b) | a.indexOf(b) |
MaxToMin | a.max | a.min |
MinToMax | a.min | a.max |
MaxByToMinBy | a.maxBy(b) | a.minBy(b) |
MinByToMaxBy | a.minBy(b) | a.maxBy(b) |
๐ Back to Top
Object literalโ
Mutant operator | Original | Mutated |
---|
ObjectPropertiesRemoval | { foo: 'bar' } | { } |
๐ Back to Top
Optional chainingโ
StrykerJS specific mutator
Mutant operator | Original | Mutated |
---|
OptionalMemberToRequired | foo?.bar | foo.bar |
OptionalComputedToRequired | foo?.[1] | foo[1] |
OptionalCallToRequired | foo?.() | foo() |
๐ Back to Top
Regular expressions are parsed and mutated separately. This is done by recognizing new Regex("...")
call signatures in each language. Scala and JavaScript also have shorthand syntax, /regex/
and "regex".r
respectively, which are mutated as well.
StrykerJS and Stryker4s use the awesome โ weapon-regex to mutate their regular expressions. All Level 1 mutations are generated.
Strings and literals identified to a regex are mutated in the following way:
Original | Mutated |
---|
^abc | abc |
abc$ | abc |
[abc] | [^abc] |
[^abc] | [abc] |
\d | \D |
\D | \d |
\s | \S |
\S | \s |
\w | \W |
\W | \w |
a? | a |
a* | a |
a+ | a |
a{1,3} | a |
a*? | a |
a+? | a |
a{1,3}? | a |
a?+ | a |
a*+ | a |
a++ | a |
a{1,3}+ | a |
(?=abc) | (?!abc) |
(?!abc) | (?=abc) |
(?<=abc) | (?<!abc) |
(?<!abc) | (?<=abc) |
\p{Alpha} | \P{Alpha} ยน |
\P{Alpha} | \p{Alpha} ยน |
\P{Alpha} | \p{Alpha} ยน |
ยน JVM only.
๐ Back to Top
String Literalโ
Mutant operator | Original | Mutated |
---|
FilledStringToEmpty | "foo" (filled string) | "" (empty string) |
EmptyStringToFilled | "" (empty string) | "Stryker was here!" |
FilledInterpolatedStringToEmpty | s"foo ${bar}" (string interpolation) | s"" ยน |
FilledInterpolatedStringToEmpty | `foo ${bar}` | `` |
ยน For Stryker4s, only works with string interpolation and not other types of interpolation (like Scalameta quasiquotes) to avoid compile errors
๐ Back to Top
Unary Operatorโ
Mutant operator | Original | Mutated |
---|
PlusNegation | +a | -a |
MinusNegation | -a | +a |
๐ Back to Top
Update Operatorโ
Mutant operator | Original | Mutated |
---|
PostfixIncrementNegation | a++ | a-- |
PostfixDecrementNegation | a-- | a++ |
PrefixIncrementNegation | ++a | --a |
PrefixDecrementNegation | --a | ++a |
๐ Back to Top