Skip to content

stryker-mutator/weapon-regex

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

746 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

Mutation testing badge Build Status GitHub Pages

Weapon regeX Logo

Weapon regeX

Weapon regeX mutates regular expressions for use in mutation testing. It has been designed from the ground up to support Stryker Mutator. Weapon regeX is available for both JavaScript and Scala and is used in Stryker4s and StrykerJS flavors of Stryker. The JavaScript version of the library is generated from Scala using Scala.js. The generated mutant regular expressions cover human errors, such as edge cases and typos. A list of provided mutators is given below. For an introduction to mutation testing, see Stryker's website.

The current supported versions for Scala are: 2.12, 2.13 and 3.

Getting started

In case you want to incorporate Weapon-regeX into your project.

Scala

Add Weapon regeX to your build.sbt Maven Central:

libraryDependencies += "io.stryker-mutator" %% "weapon-regex" % weaponRegexVersion

Mutate!

import weaponregex.WeaponRegeX

WeaponRegeX.mutate("^abc(d+|[xyz])$") match {
    case Right(mutants) => mutants map (_.pattern)
    case Left(e)        => throw new RuntimeException(e)
}
// res0: Seq[String] = List(
//   "abc(d+|[xyz])$",
//   "^abc(d+|[xyz])",
//   "\\Aabc(d+|[xyz])$",
//   "^abc(?:d+|[xyz])$",
//   "^abc(d|[xyz])$",
//   "^abc(d{0,}|[xyz])$",
//   "^abc(d{2,}|[xyz])$",
//   "^abc(d{1}|[xyz])$",
//   "^abc(d+?|[xyz])$",
//   "^abc(d+|[^xyz])$",
//   "^abc(d+|[yz])$",
//   "^abc(d+|[xz])$",
//   "^abc(d+|[xy])$",
//   "^abc(d+|[\\w\\W])$",
//   "^abc(d+|[xyz])\\z"
// )

JavaScript

Install Weapon regeX with npm.

npm install weapon-regex

Mutate!

import wrx from 'weapon-regex';

let mutants = wrx.mutate('^abc(d+|[xyz])$');

mutants.forEach((mutant) => {
    console.log(mutant.pattern);
});

Note: as of 1.0.0 weapon-regex uses ES Modules.

Try it!

API

Scala

The mutate function has the following signature:

import weaponregex.model.mutation._
import weaponregex.mutator.BuiltinMutators
import weaponregex.parser.{ParserFlavor, ParserFlavorJVM}

def mutate(
              pattern       : String,
              mutators      : Seq[TokenMutator] = BuiltinMutators.all,
              mutationLevels: Seq[Int] = null,
              flavor        : ParserFlavor = ParserFlavorJVM
          ): Either[String, Seq[Mutant]] = ???

With the mutators argument you can give a select list of mutators that should be used in the mutation process. If omitted, all built-in mutators will be used. This list will be filtered depending on the mutationLevels argument.

A list of mutationLevels can also be passed to the function. The mutators will be filtered based on the levels in the list. If omitted, no filtering takes place.

The flavor argument allows setting the parser flavor that will be used to parse the pattern. Currently, we support a ParserFlavorJVM and ParserFlavorJS. By default in Scala the JVM flavor is used.

This function will return a Right with Seq[Mutant] if it can be parsed, or a Left with the error message otherwise.

JavaScript

The mutate function can be called with regular expression flags and an options object to control which mutators and which parser flavor should be used in the mutation process:

import wrx from 'weapon-regex';

let mutants = wrx.mutate('^abc(d+|[xyz])$', 'u', {
    mutators: Array.from(wrx.mutators.values()),
    mutationLevels: [1, 2, 3],
    flavor: wrx.ParserFlavorJS,
});

Both options can be omitted, and have the same functionality as the options described in the Scala API section. By default in JS the JS parser flavor is used. You can get a map of mutators from the mutators attribute of the library. It is a Map<string, Mutator> from string (mutator name) to a mutator object.

This function will return a JavaScript Array of Mutant if it can be parsed, or throw an exception otherwise.

Supported mutators

All the supported mutators and at which mutation level they appear are shown in the table below.

Name 1 2 3
BOLRemoval โœ… โœ… โœ…
EOLRemoval โœ… โœ… โœ…
BOL2BOI โœ… โœ…
EOL2EOI โœ… โœ…
CharClassNegation โœ…
CharClassChildRemoval โœ… โœ…
CharClassAnyChar โœ… โœ…
CharClassRangeModification โœ…
PredefCharClassNegation โœ…
PredefCharClassNullification โœ… โœ…
PredefCharClassAnyChar โœ… โœ…
UnicodeCharClassNegation โœ…
QuantifierRemoval โœ…
QuantifierNChange โœ… โœ…
QuantifierNOrMoreModification โœ… โœ…
QuantifierNOrMoreChange โœ… โœ…
QuantifierNMModification โœ… โœ…
QuantifierShortModification โœ… โœ…
QuantifierShortChange โœ… โœ…
QuantifierReluctantAddition โœ…
GroupToNCGroup โœ… โœ…
LookaroundNegation โœ… โœ… โœ…

Boundary Mutators

BOLRemoval

Remove the beginning of line character ^.

Original Mutated
^abc abc

Back to table ๐Ÿ”

EOLRemoval

Remove the end of line character $.

Original Mutated
abc$ abc

Back to table ๐Ÿ”

BOL2BOI

Change the beginning of line character ^ to a beginning of input character \A.

Original Mutated
^abc \Aabc

Back to table ๐Ÿ”

EOL2EOI

Change the end of line character ^ to a end of input character \z.

Original Mutated
abc$ abc\z

Back to table ๐Ÿ”

Character class mutators

CharClassNegation

Flips the sign of a character class.

Original Mutated
[abc] [^abc]
[^abc] [abc]

Back to table ๐Ÿ”

CharClassChildRemoval

Remove a child of a character class.

Original Mutated
[abc] [bc]
[abc] [ac]
[abc] [ab]

Back to table ๐Ÿ”

CharClassAnyChar

Change a character class to a character class which matches any character.

Original Mutated
[abc] [\w\W]

Back to table ๐Ÿ”

CharClassRangeModification

Change the high and low of a range by one in both directions if possible.

Original Mutated
[b-y] [a-y]
[b-y] [c-y]
[b-y] [b-z]
[b-y] [b-x]

Back to table ๐Ÿ”

Predefined character class mutators

PredefCharClassNegation

Flips the sign of a predefined character class. All the predefined character classes are shown in the table below.

Original Mutated
\d \D
\D \d
\s \S
\S \s
\w \W
\W \w

Back to table ๐Ÿ”

PredefCharClassNullification

Remove the backslash from a predefined character class such as \w.

Original Mutated
\d d
\D D
\s s
\S S
\w w
\W W

Back to table ๐Ÿ”

PredefCharClassAnyChar

Change a predefined character class to a character class containing the predefined one and its negation.

Original Mutated
\d [\d\D]
\D [\D\d]
\s [\s\S]
\S [\S\s]
\w [\w\W]
\W [\W\w]

Back to table ๐Ÿ”

UnicodeCharClassNegation

Flips the sign of a Unicode character class.

Original Mutated
\p{Alpha} \P{Alpha}
\P{Alpha} \p{Alpha}

Back to table ๐Ÿ”

Quantifier mutators

QuantifierRemoval

Remove a quantifier. This is done for all possible quantifiers, even ranges, and the reluctant and possessive variants.

Original Mutated
abc? abc
abc* abc
abc+ abc
abc{1,3} abc
abc?? abc
abc*? abc
abc+? abc
abc{1,3}? abc
abc?+ abc
abc*+ abc
abc++ abc
abc{1,3}+ abc

Back to table ๐Ÿ”

QuantifierNChange

Change the fixed amount quantifier to a couple of range variants.

Original Mutated
abc{9} abc{0,9}
abc{9} abc{9,}

Back to table ๐Ÿ”

QuantifierNOrMoreModification

Change the n to infinity range quantifier to a couple of variants where the low of the range is incremented and decremented by one.

Original Mutated
abc{9,} abc{8,}
abc{9,} abc{10,}

Back to table ๐Ÿ”

QuantifierNOrMoreChange

Turn an n or more range quantifier into a fixed number quantifier.

Original Mutated
abc{9,} abc{9}

Back to table ๐Ÿ”

QuantifierNMModification

Alter the n to m range quantifier by decrementing or incrementing the high and low of the range by one.

Original Mutated
abc{3,9} abc{2,9}
abc{3,9} abc{4,9}
abc{3,9} abc{3,8}
abc{3,9} abc{3,10}

Back to table ๐Ÿ”

QuantifierShortModification

Treat the shorthand quantifiers (?, *, +) as their corresponding range quantifier variant ({0,1}, {0,}, {1,}), and applies the same mutations as mentioned in the mutators above.

Original Mutated
abc? abc{1,1}
abc? abc{0,0}
abc? abc{0,2}
abc* abc{1,}
abc+ abc{0,}
abc+ abc{2,}

Back to table ๐Ÿ”

QuantifierShortChange

Change the shorthand quantifiers * and + to their fixed range quantifier variant.

Original Mutated
abc* abc{0}
abc+ abc{1}

Back to table ๐Ÿ”

QuantifierReluctantAddition

Change greedy quantifiers to reluctant quantifiers.

Original Mutated
abc? abc??
abc* abc*?
abc+ abc+?
abc{9} abc{9}?
abc{9,} abc{9,}?
abc{9,13} abc{9,13}?

Back to table ๐Ÿ”

Group-related construct mutators

GroupToNCGroup

Change a normal group to a non-capturing group.

Original Mutated
(abc) (?:abc)

Back to table ๐Ÿ”

LookaroundNegation

Flips the sign of a lookaround (lookahead, lookbehind) construct.

Original Mutated
(?=abc) (?!abc)
(?!abc) (?=abc)
(?<=abc) (?<!abc)
(?<!abc) (?<=abc)

Back to table ๐Ÿ”

โšก