Skip to content

Latest commit

 

History

History
376 lines (305 loc) · 15.9 KB

File metadata and controls

376 lines (305 loc) · 15.9 KB
title Supported mutators
custom_edit_url https://github.com/stryker-mutator/mutation-testing-elements/edit/master/docs/supported-mutators.md

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
Math Methods

Arithmetic Operator

Original Mutated
a + b a - b
a - b a + b
a * b a / b
a / b a * b
a % b a * b

🔝 Back to Top

Array Declaration

Original Mutated
new Array(1, 2, 3, 4) new Array()
[1, 2, 3, 4] [ ]

🔝 Back to Top

Assignment Expression

Original Mutated
+= -=
-= +=
*= /=
/= *=
%= *=
<<= >>=
>>= <<=
&= |=
|= &=
??= &&=¹
  • ¹: 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

Original Mutated
true false
false true
!(a == b) a == b ¹
  • ¹: Not supported by Stryker4s

🔝 Back to Top

Checked Statement

Stryker.NET specific mutator

Original Mutated
checked(2 + 4) 2 + 4

🔝 Back to Top

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

🔝 Back to Top

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

🔝 Back to Top

Logical Operator

Original Mutated
a && b a || b
a || b a && b
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

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()

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)

🔝 Back to Top

Object literal

Original Mutated
{ foo: 'bar' } { }

🔝 Back to Top

Optional chaining

Original Mutated
foo?.bar foo.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:

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

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

🔝 Back to Top

Unary Operator

Original Mutated
+a -a
-a +a

🔝 Back to Top

Update Operator

Original Mutated
a++ a--
a-- a++
++a --a
--a ++a

🔝 Back to Top

Math Methods

Original Mutated
Acos() Acosh()
Acos() Asin()
Acos() Atan()
Acosh() Acos()
Acosh() Asinh()
Acosh() Atanh()
Asin() Asinh()
Asin() Acos()
Asin() Atan()
Asinh() Asin()
Asinh() Acosh()
Asinh() Atanh()
Atan() Atanh()
Atan() Acos()
Atan() Asin()
Atanh() Atan()
Atanh() Acosh()
Atanh() Asinh()
BitDecrement() BitIncrement()
BitIncrement() BitDecrement()
Ceiling() Floor()
Cos() Cosh()
Cos() Sin()
Cos() Tan()
Cosh() Cos()
Cosh() Sinh()
Cosh() Tanh()
Exp() Log()
Floor() Ceiling()
Log() Exp()
Log() Pow()
MaxMagnitude() MinMagnitude()
MinMagnitude() MaxMagnitude()
Pow() Log()
ReciprocalEstimate() ReciprocalSqrtEstimate()
ReciprocalSqrtEstimate() ReciprocalEstimate()
ReciprocalSqrtEstimate() Sqrt()
Sin() Sinh()
Sin() Cos()
Sin() Tan()
Sinh() Sin()
Sinh() Cosh()
Sinh() Tanh()
Tan() Tanh()
Tan() Cos()
Tan() Sin()
Tanh() Tan()
Tanh() Cosh()
Tanh() Sinh()