{"id":18867888,"url":"https://github.com/stryker-mutator/weapon-regex","last_synced_at":"2025-08-20T22:30:54.548Z","repository":{"id":38081647,"uuid":"330975279","full_name":"stryker-mutator/weapon-regex","owner":"stryker-mutator","description":"Mutating your regular expressions! For Scala and JS.","archived":false,"fork":false,"pushed_at":"2024-10-29T12:05:37.000Z","size":1842,"stargazers_count":9,"open_issues_count":0,"forks_count":3,"subscribers_count":5,"default_branch":"main","last_synced_at":"2024-10-29T14:35:10.641Z","etag":null,"topics":["hacktoberfest","javascript","regular-expression","scala","scalajs","testing-framework","testing-tool","typescript"],"latest_commit_sha":null,"homepage":"https://stryker-mutator.io/weapon-regex/","language":"Scala","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/stryker-mutator.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-01-19T12:39:05.000Z","updated_at":"2024-10-29T12:05:39.000Z","dependencies_parsed_at":"2023-02-16T23:46:18.905Z","dependency_job_id":"a78cd33e-5b0b-4db0-bb33-70e142494937","html_url":"https://github.com/stryker-mutator/weapon-regex","commit_stats":{"total_commits":241,"total_committers":13,"mean_commits":18.53846153846154,"dds":0.6431535269709543,"last_synced_commit":"6db3bd178f847a5e0b142513094d16ff79bbb275"},"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stryker-mutator%2Fweapon-regex","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stryker-mutator%2Fweapon-regex/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stryker-mutator%2Fweapon-regex/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stryker-mutator%2Fweapon-regex/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stryker-mutator","download_url":"https://codeload.github.com/stryker-mutator/weapon-regex/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230462906,"owners_count":18229864,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["hacktoberfest","javascript","regular-expression","scala","scalajs","testing-framework","testing-tool","typescript"],"created_at":"2024-11-08T05:11:44.988Z","updated_at":"2024-12-19T16:10:39.601Z","avatar_url":"https://github.com/stryker-mutator.png","language":"Scala","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Mutation testing badge](https://img.shields.io/endpoint?style=flat\u0026url=https%3A%2F%2Fbadge-api.stryker-mutator.io%2Fgithub.com%2Fstryker-mutator%2Fweapon-regex%2Fmain)](https://dashboard.stryker-mutator.io/reports/github.com/stryker-mutator/weapon-regex/main)\n[![Build Status](https://github.com/stryker-mutator/weapon-regex/workflows/Scala%20CI/badge.svg)](https://github.com/stryker-mutator/weapon-regex/actions?query=workflow%3AScala%20CI+branch%3Amain)\n[![GitHub Pages](https://img.shields.io/static/v1?label=GitHub%20Pages\u0026message=Try%20it!\u0026color=blue\u0026logo=github)](https://stryker-mutator.github.io/weapon-regex/)\n\n\u003cimg src=\"images/WeaponRegeX_logo.svg\" width=\"25%\" alt=\"Weapon regeX Logo\"\u003e\n\n# Weapon regeX\n\nWeapon regeX mutates regular expressions for use in mutation testing. It has been designed from the ground up\nto support [Stryker Mutator](https://github.com/stryker-mutator). Weapon regeX is available for both\nJavaScript and Scala and is used in [Stryker4s](https://github.com/stryker-mutator/stryker4s) and\n[StrykerJS](https://github.com/stryker-mutator/stryker-js) flavors of Stryker.\nThe JavaScript version of the library is generated from Scala using [Scala.js](https://www.scala-js.org/).\nThe generated mutant regular expressions cover human errors, such as edge cases and typos. A list of provided mutators\nis given below.\nFor an introduction to mutation testing, see [Stryker's website](https://stryker-mutator.io/).\n\nThe current supported versions for Scala are: `2.12`, `2.13` and `3`.\n\n# Getting started\n\nIn case you want to incorporate Weapon-regeX into your project.\n\n## Scala\n\nAdd Weapon regeX to\nyour `build.sbt` [![Maven Central](https://img.shields.io/maven-central/v/io.stryker-mutator/weapon-regex_3.svg?label=Maven%20Central\u0026colorB=brightgreen)](https://search.maven.org/artifact/io.stryker-mutator/weapon-regex_3):\n\n```scala\nlibraryDependencies += \"io.stryker-mutator\" %% \"weapon-regex\" % weaponRegexVersion\n```\n\nMutate!\n\n```scala\nimport weaponregex.WeaponRegeX\n\nWeaponRegeX.mutate(\"^abc(d+|[xyz])$\") match {\n    case Right(mutants) =\u003e mutants map (_.pattern)\n    case Left(e)        =\u003e throw new RuntimeException(e)\n}\n// res0: Seq[String] = List(\n//   \"abc(d+|[xyz])$\",\n//   \"^abc(d+|[xyz])\",\n//   \"\\\\Aabc(d+|[xyz])$\",\n//   \"^abc(?:d+|[xyz])$\",\n//   \"^abc(d|[xyz])$\",\n//   \"^abc(d{0,}|[xyz])$\",\n//   \"^abc(d{2,}|[xyz])$\",\n//   \"^abc(d{1}|[xyz])$\",\n//   \"^abc(d+?|[xyz])$\",\n//   \"^abc(d+|[^xyz])$\",\n//   \"^abc(d+|[yz])$\",\n//   \"^abc(d+|[xz])$\",\n//   \"^abc(d+|[xy])$\",\n//   \"^abc(d+|[\\\\w\\\\W])$\",\n//   \"^abc(d+|[xyz])\\\\z\"\n// )\n```\n\n## JavaScript\n\nInstall Weapon regeX with `npm`.\n\n```bash\nnpm install weapon-regex\n```\n\nMutate!\n\n```javascript\nimport wrx from 'weapon-regex';\n\nlet mutants = wrx.mutate('^abc(d+|[xyz])$');\n\nmutants.forEach((mutant) =\u003e {\n    console.log(mutant.pattern);\n});\n```\n\nNote: as of 1.0.0 weapon-regex uses ES Modules.\n\n[![Try it!](https://img.shields.io/static/v1?label=RunKit\u0026message=Try%20it!\u0026color=F55FA6\u0026logo=runkit)](https://npm.runkit.com/weapon-regex)\n\n# API\n\n## Scala\n\nThe `mutate` function has the following signature:\n\n```scala\nimport weaponregex.model.mutation._\nimport weaponregex.mutator.BuiltinMutators\nimport weaponregex.parser.{ParserFlavor, ParserFlavorJVM}\n\ndef mutate(\n              pattern       : String,\n              mutators      : Seq[TokenMutator] = BuiltinMutators.all,\n              mutationLevels: Seq[Int] = null,\n              flavor        : ParserFlavor = ParserFlavorJVM\n          ): Either[String, Seq[Mutant]] = ???\n```\n\nWith the `mutators` argument you can give a select list of mutators that should be used in\nthe mutation process. If omitted, all built-in mutators will be used. This list will be filtered\ndepending on the `mutationLevels` argument.\n\nA list of `mutationLevels` can also be passed to the function. The mutators will be filtered\nbased on the levels in the list. If omitted, no filtering takes place.\n\nThe `flavor` argument allows setting the parser flavor that will be used to parse the pattern.\nCurrently, we support a `ParserFlavorJVM` and `ParserFlavorJS`. By default in Scala the JVM flavor is used.\n\nThis function will return a `Right` with `Seq[Mutant]` if it can be parsed, or a `Left` with the error message\notherwise.\n\n## JavaScript\n\nThe `mutate` function can be called with regular expression flags and an options object to control which mutators and\nwhich parser flavor should be used in the mutation process:\n\n```js\nimport wrx from 'weapon-regex';\n\nlet mutants = wrx.mutate('^abc(d+|[xyz])$', 'u', {\n    mutators: Array.from(wrx.mutators.values()),\n    mutationLevels: [1, 2, 3],\n    flavor: wrx.ParserFlavorJS,\n});\n```\n\nBoth options can be omitted, and have the same functionality as the options described in the Scala\nAPI section. By default in JS the JS parser flavor is used. You can get a map of mutators from the `mutators` attribute\nof the library. It is\na `Map\u003cstring, Mutator\u003e` from string (mutator name) to a mutator object.\n\nThis function will return a JavaScript Array of `Mutant` if it can be parsed, or throw an exception otherwise.\n\n# Supported mutators\n\nAll the supported mutators and at which mutation level they appear are shown in the table below.\n\n| Name                                                            | 1 | 2 | 3 |\n|-----------------------------------------------------------------|---|---|---|\n| [BOLRemoval](#bolremoval)                                       | ✅ | ✅ | ✅ |\n| [EOLRemoval](#eolremoval)                                       | ✅ | ✅ | ✅ |\n| [BOL2BOI](#bol2boi)                                             |   | ✅ | ✅ |\n| [EOL2EOI](#eol2eoi)                                             |   | ✅ | ✅ |\n| [CharClassNegation](#charclassnegation)                         | ✅ |\n| [CharClassChildRemoval](#charclasschildremoval)                 |   | ✅ | ✅ |\n| [CharClassAnyChar](#charclassanychar)                           |   | ✅ | ✅ |\n| [CharClassRangeModification](#charclassrangemodification)       |   |   | ✅ |\n| [PredefCharClassNegation](#predefcharclassnegation)             | ✅ |\n| [PredefCharClassNullification](#predefcharclassnullification)   |   | ✅ | ✅ |\n| [PredefCharClassAnyChar](#predefcharclassanychar)               |   | ✅ | ✅ |\n| [UnicodeCharClassNegation](#unicodecharclassnegation)           | ✅ |\n| [QuantifierRemoval](#quantifierremoval)                         | ✅ |\n| [QuantifierNChange](#quantifiernchange)                         |   | ✅ | ✅ |\n| [QuantifierNOrMoreModification](#quantifiernormoremodification) |   | ✅ | ✅ |\n| [QuantifierNOrMoreChange](#quantifiernormorechange)             |   | ✅ | ✅ |\n| [QuantifierNMModification](#quantifiernmmodification)           |   | ✅ | ✅ |\n| [QuantifierShortModification](#quantifiershortmodification)     |   | ✅ | ✅ |\n| [QuantifierShortChange](#quantifiershortchange)                 |   | ✅ | ✅ |\n| [QuantifierReluctantAddition](#quantifierreluctantaddition)     |   |   | ✅ |\n| [GroupToNCGroup](#grouptoncgroup)                               |   | ✅ | ✅ |\n| [LookaroundNegation](#lookaroundnegation)                       | ✅ | ✅ | ✅ |\n\n## Boundary Mutators\n\n### BOLRemoval\n\nRemove the beginning of line character `^`.\n\n| Original | Mutated |\n|----------|---------|\n| `^abc`   | `abc`   |\n\n[Back to table 🔝](#supported-mutators)\n\n### EOLRemoval\n\nRemove the end of line character `$`.\n\n| Original | Mutated |\n|----------|---------|\n| `abc$`   | `abc`   |\n\n[Back to table 🔝](#supported-mutators)\n\n### BOL2BOI\n\nChange the beginning of line character `^` to a beginning of input character `\\A`.\n\n| Original | Mutated |\n|----------|---------|\n| `^abc`   | `\\Aabc` |\n\n[Back to table 🔝](#supported-mutators)\n\n### EOL2EOI\n\nChange the end of line character `^` to a end of input character `\\z`.\n\n| Original | Mutated |\n|----------|---------|\n| `abc$`   | `abc\\z` |\n\n[Back to table 🔝](#supported-mutators)\n\n## Character class mutators\n\n### CharClassNegation\n\nFlips the sign of a character class.\n\n| Original | Mutated  |\n|----------|----------|\n| `[abc]`  | `[^abc]` |\n| `[^abc]` | `[abc]`  |\n\n[Back to table 🔝](#supported-mutators)\n\n### CharClassChildRemoval\n\nRemove a child of a character class.\n\n| Original | Mutated |\n|----------|---------|\n| `[abc]`  | `[bc]`  |\n| `[abc]`  | `[ac]`  |\n| `[abc]`  | `[ab]`  |\n\n[Back to table 🔝](#supported-mutators)\n\n### CharClassAnyChar\n\nChange a character class to a character class which matches any character.\n\n| Original | Mutated  |\n|----------|----------|\n| `[abc]`  | `[\\w\\W]` |\n\n[Back to table 🔝](#supported-mutators)\n\n### CharClassRangeModification\n\nChange the high and low of a range by one in both directions if possible.\n\n| Original | Mutated |\n|----------|---------|\n| `[b-y]`  | `[a-y]` |\n| `[b-y]`  | `[c-y]` |\n| `[b-y]`  | `[b-z]` |\n| `[b-y]`  | `[b-x]` |\n\n[Back to table 🔝](#supported-mutators)\n\n## Predefined character class mutators\n\n### PredefCharClassNegation\n\nFlips the sign of a predefined character class. All the predefined character classes are shown in the table below.\n\n| Original | Mutated |\n|----------|---------|\n| `\\d`     | `\\D`    |\n| `\\D`     | `\\d`    |\n| `\\s`     | `\\S`    |\n| `\\S`     | `\\s`    |\n| `\\w`     | `\\W`    |\n| `\\W`     | `\\w`    |\n\n[Back to table 🔝](#supported-mutators)\n\n### PredefCharClassNullification\n\nRemove the backslash from a predefined character class such as `\\w`.\n\n| Original | Mutated |\n|----------|---------|\n| `\\d`     | `d`     |\n| `\\D`     | `D`     |\n| `\\s`     | `s`     |\n| `\\S`     | `S`     |\n| `\\w`     | `w`     |\n| `\\W`     | `W`     |\n\n[Back to table 🔝](#supported-mutators)\n\n### PredefCharClassAnyChar\n\nChange a predefined character class to a character class containing the predefined one and its\nnegation.\n\n| Original | Mutated  |\n|----------|----------|\n| `\\d`     | `[\\d\\D]` |\n| `\\D`     | `[\\D\\d]` |\n| `\\s`     | `[\\s\\S]` |\n| `\\S`     | `[\\S\\s]` |\n| `\\w`     | `[\\w\\W]` |\n| `\\W`     | `[\\W\\w]` |\n\n[Back to table 🔝](#supported-mutators)\n\n### UnicodeCharClassNegation\n\nFlips the sign of a Unicode character class.\n\n| Original    | Mutated     |\n|-------------|-------------|\n| `\\p{Alpha}` | `\\P{Alpha}` |\n| `\\P{Alpha}` | `\\p{Alpha}` |\n\n[Back to table 🔝](#supported-mutators)\n\n## Quantifier mutators\n\n### QuantifierRemoval\n\nRemove a quantifier. This is done for all possible quantifiers, even ranges, and the reluctant\nand possessive variants.\n\n| Original    | Mutated |\n|-------------|---------|\n| `abc?`      | `abc`   |\n| `abc*`      | `abc`   |\n| `abc+`      | `abc`   |\n| `abc{1,3}`  | `abc`   |\n| `abc??`     | `abc`   |\n| `abc*?`     | `abc`   |\n| `abc+?`     | `abc`   |\n| `abc{1,3}?` | `abc`   |\n| `abc?+`     | `abc`   |\n| `abc*+`     | `abc`   |\n| `abc++`     | `abc`   |\n| `abc{1,3}+` | `abc`   |\n\n[Back to table 🔝](#supported-mutators)\n\n### QuantifierNChange\n\nChange the fixed amount quantifier to a couple of range variants.\n\n| Original | Mutated    |\n|----------|------------|\n| `abc{9}` | `abc{0,9}` |\n| `abc{9}` | `abc{9,}`  |\n\n[Back to table 🔝](#supported-mutators)\n\n### QuantifierNOrMoreModification\n\nChange the `n` to infinity range quantifier to a couple of variants where the low of the range is\nincremented and decremented by one.\n\n| Original  | Mutated    |\n|-----------|------------|\n| `abc{9,}` | `abc{8,}`  |\n| `abc{9,}` | `abc{10,}` |\n\n[Back to table 🔝](#supported-mutators)\n\n### QuantifierNOrMoreChange\n\nTurn an `n` or more range quantifier into a fixed number quantifier.\n\n| Original  | Mutated  |\n|-----------|----------|\n| `abc{9,}` | `abc{9}` |\n\n[Back to table 🔝](#supported-mutators)\n\n### QuantifierNMModification\n\nAlter the `n` to `m` range quantifier by decrementing or incrementing the high and low of the\nrange by one.\n\n| Original   | Mutated     |\n|------------|-------------|\n| `abc{3,9}` | `abc{2,9}`  |\n| `abc{3,9}` | `abc{4,9}`  |\n| `abc{3,9}` | `abc{3,8}`  |\n| `abc{3,9}` | `abc{3,10}` |\n\n[Back to table 🔝](#supported-mutators)\n\n### QuantifierShortModification\n\nTreat the shorthand quantifiers (`?`, `*`, `+`) as their corresponding range quantifier\nvariant (`{0,1}`, `{0,}`, `{1,}`), and applies the same mutations as mentioned in the mutators\nabove.\n\n| Original | Mutated    |\n|----------|------------|\n| `abc?`   | `abc{1,1}` |\n| `abc?`   | `abc{0,0}` |\n| `abc?`   | `abc{0,2}` |\n| `abc*`   | `abc{1,}`  |\n| `abc+`   | `abc{0,}`  |\n| `abc+`   | `abc{2,}`  |\n\n[Back to table 🔝](#supported-mutators)\n\n### QuantifierShortChange\n\nChange the shorthand quantifiers `*` and `+` to their fixed range quantifier variant.\n\n| Original | Mutated  |\n|----------|----------|\n| `abc*`   | `abc{0}` |\n| `abc+`   | `abc{1}` |\n\n[Back to table 🔝](#supported-mutators)\n\n### QuantifierReluctantAddition\n\nChange greedy quantifiers to reluctant quantifiers.\n\n| Original    | Mutated      |\n|-------------|--------------|\n| `abc?`      | `abc??`      |\n| `abc*`      | `abc*?`      |\n| `abc+`      | `abc+?`      |\n| `abc{9}`    | `abc{9}?`    |\n| `abc{9,}`   | `abc{9,}?`   |\n| `abc{9,13}` | `abc{9,13}?` |\n\n[Back to table 🔝](#supported-mutators)\n\n## Group-related construct mutators\n\n### GroupToNCGroup\n\nChange a normal group to a non-capturing group.\n\n| Original | Mutated   |\n|----------|-----------|\n| `(abc)`  | `(?:abc)` |\n\n[Back to table 🔝](#supported-mutators)\n\n### LookaroundNegation\n\nFlips the sign of a lookaround (lookahead, lookbehind) construct.\n\n| Original   | Mutated    |\n|------------|------------|\n| `(?=abc)`  | `(?!abc)`  |\n| `(?!abc)`  | `(?=abc)`  |\n| `(?\u003c=abc)` | `(?\u003c!abc)` |\n| `(?\u003c!abc)` | `(?\u003c=abc)` |\n\n[Back to table 🔝](#supported-mutators)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstryker-mutator%2Fweapon-regex","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstryker-mutator%2Fweapon-regex","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstryker-mutator%2Fweapon-regex/lists"}