-
Notifications
You must be signed in to change notification settings - Fork 250
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
TypeScript: Override some quality options #391
Comments
@nicojs: Is it possible to add an overriding module from tsconfig? For mutation I need Thank you |
Hi @Mrna1 , thanks for asking 😄 The easiest way is to use TS's For now it is not possible to override tsconfig options directly from Stryker. See #1437 for more info on that. |
Introducing the typescript type-checker plugin. ## Features 👽 Type check each mutant. Invalid mutants will be marked as `CompileError` in your Stryker report. 🧒 Easy to setup, only your `tsconfig.json` file is needed. 🔢 Type check is done in-memory, no side effects on disk. 🎁 Support for both single typescript projects as well as projects with project references (`--build` mode). ## Configuring You can configure the typescript checker in the `stryker.conf.js` (or `stryker.conf.json`) file. ```js // stryker.conf.json { "checkers": ["typescript"], "typescriptChecker": { "tsconfigFile": "tsconfig.json" } } ``` ### `typescriptChecker.tsconfigFile` [`string`] Default: `'tsconfig.json'` The path to your [tsconfig](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html). Project references _are supported_, `--build` mode will be enabled automatically when references are found in your tsconfig.json file. ## Implemenation The `@stryker-mutator/typescript-checker` is not using the [typescript language service api](https://github.com/Microsoft/TypeScript/wiki/Using-the-Language-Service-API), like the current [typescript transpiler](https://github.com/stryker-mutator/stryker/blob/f44008993a543dc3f38ca99516f56d315fdcb735/packages/typescript/src/transpiler/TranspilingLanguageService.ts#L23) is. Instead, it's using the [compiler API](https://github.com/microsoft/TypeScript/wiki/Using-the-Compiler-API). The language service API wasn't really designed for our use case. For example, it doesn't support project references, nor will it ever (read this somewhere, unfortunately, cannot find the source). It also took a lot of code to get working, with a pretty high number of bugs 🐛. Even in our own project, we needed separate `tsconfig.stryker.json` config files. Very annoying. The compiler API is somewhat more low-level. We're starting the compiler on `initialize()` method of the checker API. If the initial build fails, we're rejecting the promise. Each mutant is checked basically the same way as it was in the old typescript transpiler. Namely, the previous mutant is removed, the new mutant is placed and the typescript compiler runs. If it errors, the `CheckStatus.CompilError` status is reported with the error text in the `reason` field. There are some nifty tricks to be found: 1. During `initialize()` the typescript compiler starts. We're reading all files from disk synchronously and storing them in memory. After the initial build, all files should be in-memory, no further files are pulled in. * We're using the `ts.createSolutionBuilderWithWatch`. This creates a compiler with `--build` mode enabled. This seems to work for both single-project solutions as for a multi project solution with project references. This api is available since ts `3.6`, so we're throwing an error if a previous version of typescript is found. 1. The way to inform the typescript compiler that a file has changed is to "pretend" as if the file changed on disk. The file system watcher is informed in-memory of the change. This triggers a rebuild. 1. In order to still override compiler options as specified in #391, we're transforming each tsconfig.json file as it is read from disk. This way we can force the compiler options we want. The config file can also be named differently, each tsconfig file is scanned for `references` in order to make sure we're only transforming the tsconfig files that are used. 1. In order to ensure the best performance, `--noEmit` is forced. This will prevent the typescript compiler from outputting code. Unfortunately `--noEmit` is forbidden for `--build` mode, which is why `--emitDeclarationsOnly` is forced for those projects.
When transpiling typescript code, we should override some of the compiler options designed for code quality. For example: if we now mutate an if statement to
if(false)
and the user has the code quality optionallowUnreachableCode=false
the mutant will not be tested and is treated as a false positive (basically).I don't think this is what we want. If you think about it: indeed, nobody in their right mind would mutate an if statement like that and typescript is right to report a warning when done so, but at the same time, that is not what we want to test when we mutate the if-statement. We want tot see if your tests can detect the side effect of never going in the if statement.
See https://www.typescriptlang.org/docs/handbook/compiler-options.html for a list of compiler options. I think we should override the following:
allowUnreachableCode
should be truenoUnusedLocals
should be falsenoUnusedParameters
should be falseAnother way to look at it: we're mutating code, of course the code quality will be less. That doesn't mean that the mutant is invalid.
The text was updated successfully, but these errors were encountered: