Supported mutators
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โ
Mutator | StrykerJS | Stryker.NET | Stryker4s |
---|---|---|---|
Arithmetic Operator | โ | โ | โ |
Array Declaration | โ | โ | โ |
Assignment Expression | โ | โ | n/a |
Block Statement | โ | โ | โ |
Boolean Literal | โ | โ | ๏ธโ |
Checked Statement | n/a | โ | n/a |
Conditional Expression | โ | โ | โ |
Equality Operator | โ | โ | โ |
Logical Operator | โ | โ | โ |
Method Expression | โ | โ | โ |
Object literal | โ | n/a | n/a |
Optional chaining | โ | โ | n/a |
Regex | โ | โ | โ |
String Literal | โ | โ | โ |
Unary Operator | โ | โ | โ |
Update Operator | โ | โ | n/a |
Arithmetic Operatorโ
Original | Mutated |
---|---|
a + b | a - b |
a - b | a + b |
a * b | a / b |
a / b | a * b |
a % b | a * b |
Array Declarationโ
Original | Mutated |
---|---|
new Array(1, 2, 3, 4) | new Array() |
[1, 2, 3, 4] | [ ] |
Assignment Expressionโ
Original | Mutated |
---|---|
+= | -= |
-= | += |
*= | /= |
/= | *= |
%= | *= |
<<= | >>= |
>>= | <<= |
&= | |= |
|= | &= |
??= | &&= ยน |
- ยน: Only supported by Stryker-JS
Block Statementโ
Removes the content of every block statement. For example the code:
function saySomething() {
console.log('Hello world!');
}
becomes:
function saySomething() {}
Boolean Literalโ
Original | Mutated |
---|---|
true | false |
false | true |
!(a == b) | a == b ยน |
- ยน: Not supported by Stryker4s
Checked Statementโ
Stryker.NET specific mutator
Original | Mutated |
---|---|
checked(2 + 4) | 2 + 4 |
Conditional Expressionโ
Original | Mutated |
---|---|
for (var i = 0; i < 10; i++) { } | for (var i = 0; false; i++) { } ยน |
while (a > b) { } | while (false) { } |
do { } while (a > b); | do { } while (false); |
if (a > b) { } | if (true) { } |
if (a > b) { } | if (false) { } |
var x = a > b ? 1 : 2; | var x = true ? 1 : 2; ยน |
var x = a > b ? 1 : 2; | var x = false ? 1 : 2; ยน |
- ยน: Not supported by Stryker4s
Equality Operatorโ
Original | Mutated |
---|---|
a < b | a <= b |
a < b | a >= b |
a <= b | a < b |
a <= b | a > b |
a > b | a >= b |
a > b | a <= b |
a >= b | a > b |
a >= b | a < b |
a == b | a != b |
a != b | a == b |
a === b | a !== b ยน |
a !== b | a === b ยน |
- ยน: Only supported on StrykerJS and Stryker4s
Logical Operatorโ
Original | Mutated |
---|---|
a && b | a || b |
a || b | a && b |
a ?? b | a && b |
Method Expressionโ
Due to differences in language syntax, method expressions are implemented differently in each Stryker framework:
StrykerJSโ
Original | Mutated |
---|---|
endsWith() | startsWith() |
startsWith() | endsWith() |
trim() | |
trimEnd() | trimStart() |
trimStart() | trimEnd() |
substr() | |
substring() | |
toUpperCase() | toLowerCase() |
toLowerCase() | toUpperCase() |
toLocalLowerCase() | toLocalUpperCase() |
toLocalUpperCase() | toLocalLowerCase() |
sort() | |
some() | every() |
every() | some() |
reverse() | |
filter() | |
slice() | |
charAt() | |
min() | max() |
max() | min() |
Stryker.NETโ
Original | Mutated |
---|---|
Distinct() | |
Reverse() | |
OrderBy() | |
OrderByDescending() | |
SingleOrDefault() | FirstOrDefault() |
FirstOrDefault() | SingleOrDefault() |
First() | Last() |
Last() | First() |
All() | Any() |
Any() | All() |
Skip() | Take() |
Take() | Skip() |
SkipWhile() | TakeWhile() |
TakeWhile() | SkipWhile() |
Min() | Max() |
Max() | Min() |
Sum() | Count() |
Count() | Sum() |
Stryker4sโ
Original | Mutated |
---|---|
a.filter(b) | a.filterNot(b) |
a.filterNot(b) | a.filter(b) |
a.exists(b) | a.forall(b) |
a.forall(b) | a.exists(b) |
a.take(b) | a.drop(b) |
a.drop(b) | a.take(b) |
a.takeRight(b) | a.dropRight(b) |
a.dropRight(b) | a.takeRight(b) |
a.takeWhile(b) | a.dropWhile(b) |
a.dropWhile(b) | a.takeWhile(b) |
a.isEmpty | a.nonEmpty |
a.nonEmpty | a.isEmpty |
a.indexOf | a.lastIndexOf(b) |
a.lastIndexOf(b) | a.indexOf(b) |
a.max | a.min |
a.min | a.max |
a.maxBy(b) | a.minBy(b) |
a.minBy(b) | a.maxBy(b) |
Object literalโ
Original | Mutated |
---|---|
{ foo: 'bar' } | { } |
Optional chainingโ
Original | Mutated |
---|---|
foo?.bar | foo.bar |
foo?.[1] | foo[1] |
foo?.() | foo() |
Regexโ
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.
String Literalโ
Original | Mutated |
---|---|
"foo" (non-empty string) | "" (empty string) |
"" (empty string) | "Stryker was here!" |
s"foo ${bar}" (string interpolation) | s"" ยน |
ยน For Stryker4s, only works with string interpolation and not other types of interpolation (like Scalameta quasiquotes) to avoid compile errors
Unary Operatorโ
Original | Mutated |
---|---|
+a | -a |
-a | +a |
Update Operatorโ
Original | Mutated |
---|---|
a++ | a-- |
a-- | a++ |
++a | --a |
--a | ++a |