Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement mutation switching #2340

Merged
merged 202 commits into from Oct 7, 2020
Merged

Implement mutation switching #2340

merged 202 commits into from Oct 7, 2020

Conversation

nicojs
Copy link
Member

@nicojs nicojs commented Jul 29, 2020

Closes #1514
Fixes #1946

nicojs and others added 30 commits May 15, 2020 10:46
Temporarily disable e2e tests while we work in the mutation switching epic.
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 2.33.0 to 2.34.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v2.34.0/packages/eslint-plugin)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
Add parsers to the instrumenter package. 

Add support for:

* Parsing `*.js`, `*.tsx`, `*.html` and `*.vue` files.
* Load custom babel config with `babel.config` format and `.babelrc` format.
Add printers for html, ts, vue and js files.
Add mutant placers.

* `switchCaseMutantPlacer`: places a mutant in a switch case
* `conditionalExpressionMutantPacer`: places a mutant in a conditional expression
Bumps [@babel/traverse](https://github.com/babel/babel/tree/HEAD/packages/babel-traverse) from 7.9.6 to 7.10.1.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.10.1/packages/babel-traverse)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
…#2218)

Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 2.33.0 to 2.34.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v2.34.0/packages/parser)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.9.6 to 7.10.1.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.10.1/packages/babel-core)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
Add transformers. Transformers are responsible for the process of generating mutants and placing them in the AST. 

* `htmlTransformer`: Capable of transforming html AST
* `babelTransformer`: Capable of transforming babel AST (JS and TS)
Bumps [flatted](https://github.com/WebReflection/flatted) from 2.0.2 to 3.0.2.
- [Release notes](https://github.com/WebReflection/flatted/releases)
- [Commits](WebReflection/flatted@v2.0.2...v3.0.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
Bumps [@babel/parser](https://github.com/babel/babel/tree/HEAD/packages/babel-parser) from 7.9.6 to 7.10.2.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.10.2/packages/babel-parser)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
Implement `Instrumenter` class, responsible for:
* Parsing code to an AST
* Mutant generation based on AST
* Transforming the code to incorporate the mutants in mutation switches
* Printing AST back to code
Adds `Checker` plugin type, to be used in #1514 (and can later be used to filter mutants in #1980).

The idea is that, before mutation testing (or even before files are instrumented), we initialize the checker. It can be used as a sanity check. The `TypescriptChecker` can use this to load all files and compile once (with `--no-emit`) to make sure errors don't occur under normal circumstances. 

The `check` method is called one-by-one on each mutant. A checker can decide to assign any of a `CheckStatus`. If it `Passed` it proceeds to the next checker, or if it was the last checker it will be run in a test runner. If another status is assigned, it will stop processing that mutant and report it as done.
Removes some calls to deprecated Jasmine APIs.

| Old | New |
|--|--|
| `throwOnExpectationFailure` | `jasmine.Env.configure( { oneFailurePerSpec: true } )` |
| `stopOnSpecFailure` | `jasmine.Env.configure( { failFast: true } )`  | 
| `jasmine.addReporter` | `jasmine.env.addReporter` |
| `jasmine.clearReporters` | `jasmine.env.clearReporters` |
Add `id` property to `Mutant` api
Update instrumenter syntax with latest design of test runner api.

* `__mutationCoverage__` -> `__mutantCoverage__`
* `activeMutant` --> `__activeMutant__`
Adds a new test runner API to Stryker. Differences with the old API:

1. Explicit difference between a `dryRun` (initial test run) and a `mutantRun`
   1. A mutantRun result has an `activeMutant` field indicating which mutant should be activated by the runner
   2.  The result types are also explicit. A `MutantRunResult` now reports back the status as `Killed` or `Survived` instead of letting Stryker make that decision. 
2. Code coverage interfaces are replaced with the simpler `MutantCoverage` interface.
3. The `MutantRunOptions` now has a `testFilter`, which replaces the old `TestFramework` API.

Add small improvements

* Add an `id` field to a `TestResult` and using that id for the filtering instead of the cumbersome `TestSelection` interface we introduced to handle string identifiers (names)
* `TestResult`, `DryRunResult` and `MutantRunResult` to be implemented using [discrimitated unions](https://www.typescriptlang.org/docs/handbook/advanced-types.html#discriminated-unions). This removes a lot of the optional fields. For example, `errorMessage` is now a required field on an `ErrorDryRunResult`.
* Defined `errorMessage` and `failureMessage` to be a `string`, instead of a `string[]`. If runners want to report more messages, they will have to concatenate themselves.
* A `MutantRunResult` no longer has to report back all tests that have run. Instead, it only reports the id of the test that killed the mutant (if the status is indeed `killed`).
* A `MutantRunResult` no longer has to report back all tests that have run. Instead, it only reports the id of the test that killed the mutant (if the status is indeed `killed`).
* Added a `toMutantRunResult` helper function that takes in a `dryRunResult` and can convert it to a `mutantRunResult`.

The new API is published under `TestRunner2`, as well as a separate plugin type. Later we will remove the old test runner API and rename this new one to `TestRunner` proper.
Bumps [karma](https://github.com/karma-runner/karma) from 5.0.9 to 5.1.0.
- [Release notes](https://github.com/karma-runner/karma/releases)
- [Changelog](https://github.com/karma-runner/karma/blob/master/CHANGELOG.md)
- [Commits](karma-runner/karma@v5.0.9...v5.1.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
nicojs and others added 27 commits September 25, 2020 19:26
* fix(core): fix "too many open files"

Fixes "too many open files" issue by limitting the number of concurrent file IO to 256

* One liner await

* fix unit test

* test(input-file): don't rely on os ordering

* Remove `.only`

* deterministic order of mutants
add deprecation warning for function based config

BREAKING CHANGE: exporting a function from stryker.conf.js is deprecated. Please export your config as an object instead, or use a stryker.conf.json file.

Co-authored-by: Nico Jansen <jansennico@gmail.com>
Only add the JS header for files that have mutants. For example: don't add it in *.d.ts files.
Bumps [eslint](https://github.com/eslint/eslint) from 7.9.0 to 7.10.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/master/CHANGELOG.md)
- [Commits](eslint/eslint@v7.9.0...v7.10.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
Correctly report the initial test run timing. For example:

> `INFO DryRunExecutor Initial test run succeeded. Ran 502 tests in 2 seconds (net 2295 ms, overhead 572 ms)`

Co-authored-by: root <root@SimonL03.corp.infosupport.com>
Co-authored-by: Nico Jansen <jansennico@gmail.com>
Support shebang (i.e. `#!/usr/bin/env node`) in javascript files.
Add support for `--maxTestRunnerReuse` compiler flag (and equivalent in stryker.conf.json). With it, you can specify the maximum number that a test runner can be reused before the process is killed and a new one is created. The default is `0`, which means no maximum, just keep reusing.

There are 2 use cases for this setting.

1. You have a memory leak in your tests that cannot be fixed (for example, a plugin in jest). You run with `--maxTestRunnerReuse 20`.
2. Your environment is dirty after running one time and you cannot do anything about it. You run with `--maxTestRunnerReuse 1`.
* Upgrade angular core to v9.
* Update stryker.conf.json
Bumps [sinon](https://github.com/sinonjs/sinon) from 9.0.3 to 9.1.0.
- [Release notes](https://github.com/sinonjs/sinon/releases)
- [Changelog](https://github.com/sinonjs/sinon/blob/master/CHANGELOG.md)
- [Commits](sinonjs/sinon@v9.0.3...v9.1.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
Bumps [flatted](https://github.com/WebReflection/flatted) from 3.0.5 to 3.1.0.
- [Release notes](https://github.com/WebReflection/flatted/releases)
- [Commits](WebReflection/flatted@v3.0.5...v3.1.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
Add a `MutantPlacer` for `SwitchCase` nodes. It places the mutants in the `consequence` part of the switch case. This can dramatically improve the performance of instrumenting large switch-case statements.

This:

```js
switch(foo){
  case 'bar':
    console.log('bar');
    break;
  case 'baz':
    console.log('baz');
    break;

}
```

Is now instrumented as:

```js
switch (foo) {
  case stryMutAct_9fa48(1) ? \\"\\" : (stryCov_9fa48(1), 'bar'):
    if (stryMutAct_9fa48(0)) {} else {
      stryCov_9fa48(0);
      console.log(stryMutAct_9fa48(2) ? \\"\\" : (stryCov_9fa48(2), 'bar'));
      break;
    }

  case stryMutAct_9fa48(4) ? \\"\\" : (stryCov_9fa48(4), 'baz'):
    if (stryMutAct_9fa48(3)) {} else {
      stryCov_9fa48(3);
      console.log(stryMutAct_9fa48(5) ? \\"\\" : (stryCov_9fa48(5), 'baz'));
      break;
    }
}
```

While previously the entire `SwitchCaseExpression` was duplicated for each empty switch case mutation.
Add support to configure `mutator.excludedMutations`. This was already supported in Stryker@<3, but not yet in Stryker4 beta.

Instead of not generating the mutants, it generates them without placing them in the code. They get reported as `ignored` in your mutation testing report.

![image](https://user-images.githubusercontent.com/1828233/94722119-2142dc00-0357-11eb-839c-a4aef430dcea.png)

Also, add error message, ignore reason, and "killed by" test name in the "show more" modal dialog.

![image](https://user-images.githubusercontent.com/1828233/94722368-8565a000-0357-11eb-9a2d-05be1ac0d161.png)
* Update the vuejs, react, angular and vue presets for the 4.0 release.
* Remove `@stryker-mutator/core` from presets
Don't mutate `TSTypeParameterInstantiation` like `React.useState<true>()`
@nicojs nicojs marked this pull request as ready for review October 7, 2020 06:34
@nicojs nicojs merged commit 212c268 into master Oct 7, 2020
@nicojs nicojs deleted the epic/mutation-switching branch March 9, 2021 15:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

PerTest option issue - SyntaxError: Unexpected identifier Implement mutation switching 👽🔀
6 participants