Skip to main content

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โ€‹

MutatorStrykerJSStryker.NETStryker4s
Arithmetic Operatorโœ…โœ…โŒ
Array Declarationโœ…โœ…โŒ
Assignment ExpressionโŒโœ…n/a
Block Statementโœ…โœ…โŒ
Boolean Literalโœ…โœ…๏ธโœ…
Checked Statementn/aโœ…n/a
Conditional Expressionโœ…โœ…โœ…
Equality Operatorโœ…โœ…โœ…
Logical Operatorโœ…โœ…โœ…
Method Expressionโœ…โœ…โœ…
Object literalโœ…n/an/a
Optional chainingโœ…โŒn/a
Regexโœ…โœ…โœ…
String Literalโœ…โœ…โœ…
Unary Operatorโœ…โœ…โŒ
Update Operatorโœ…โœ…n/a

Arithmetic Operatorโ€‹

OriginalMutated
a + ba - b
a - ba + b
a * ba / b
a / ba * b
a % ba * b

๐Ÿ” Back to Top

Array Declarationโ€‹

OriginalMutated
new Array(1, 2, 3, 4)new Array()
[1, 2, 3, 4][ ]

๐Ÿ” Back to Top

Assignment Expressionโ€‹

OriginalMutated
+=-=
-=+=
*=/=
/=*=
%=*=
<<=>>=
>>=<<=
&=|=
|=&=
??=&&=ยน
  • ยน: Only supported by Stryker-JS

๐Ÿ” Back to Top

Block Statementโ€‹

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โ€‹

OriginalMutated
truefalse
falsetrue
!(a == b)a == b ยน
  • ยน: Not supported by Stryker4s

๐Ÿ” Back to Top

Checked Statementโ€‹

Stryker.NET specific mutator

OriginalMutated
checked(2 + 4)2 + 4

๐Ÿ” Back to Top

Conditional Expressionโ€‹

OriginalMutated
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

๐Ÿ” Back to Top

Equality Operatorโ€‹

OriginalMutated
a < ba <= b
a < ba >= b
a <= ba < b
a <= ba > b
a > ba >= b
a > ba <= b
a >= ba > b
a >= ba < b
a == ba != b
a != ba == b
a === ba !== b ยน
a !== ba === b ยน
  • ยน: Only supported on StrykerJS and Stryker4s

๐Ÿ” Back to Top

Logical Operatorโ€‹

OriginalMutated
a && ba || b
a || ba && b
a ?? ba && b

๐Ÿ” Back to Top

Method Expressionโ€‹

Due to differences in language syntax, method expressions are implemented differently in each Stryker framework:

StrykerJSโ€‹

OriginalMutated
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โ€‹

OriginalMutated
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โ€‹

OriginalMutated
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.isEmptya.nonEmpty
a.nonEmptya.isEmpty
a.indexOfa.lastIndexOf(b)
a.lastIndexOf(b)a.indexOf(b)
a.maxa.min
a.mina.max
a.maxBy(b)a.minBy(b)
a.minBy(b)a.maxBy(b)

๐Ÿ” Back to Top

Object literalโ€‹

OriginalMutated
{ foo: 'bar' }{ }

๐Ÿ” Back to Top

Optional chainingโ€‹

OriginalMutated
foo?.barfoo.bar
foo?.[1]foo[1]
foo?.()foo()

๐Ÿ” Back to Top

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:

OriginalMutated
^abcabc
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โ€‹

OriginalMutated
"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

๐Ÿ” Back to Top

Unary Operatorโ€‹

OriginalMutated
+a-a
-a+a

๐Ÿ” Back to Top

Update Operatorโ€‹

OriginalMutated
a++a--
a--a++
++a--a
--a++a

๐Ÿ” Back to Top