@t09tanaka/test-gates 0.3.1 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -2
- package/README.md +58 -28
- package/dist/stryker.cjs +4 -4
- package/dist/stryker.d.cts +7 -5
- package/dist/stryker.d.ts +7 -5
- package/dist/stryker.js +3 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,10 +1,25 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.3.3
|
|
4
|
+
|
|
5
|
+
Documentation only; the commands and the helpers behave as in 0.3.2.
|
|
6
|
+
|
|
7
|
+
- The paths and outputs shown in the README are those of a small example written for it and of this repository's own gates.
|
|
8
|
+
|
|
9
|
+
## 0.3.2
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- `createStrykerGatesConfig` sets Stryker's `maxTestRunnerReuse` to 50 unless the project passes its own (Stryker's default is 0: one test runner process for the whole run). In a project with mutants that never end, the runner became about three times slower from the first of them on, and mutants that are killed in seconds on their own timed out. Starting a new process every 50 mutants kept the speed: a full run of about 800 mutants went from about a quarter of an hour with stray timeouts to less than half of that with none.
|
|
14
|
+
- `timeoutMS` is no longer set by the helper; Stryker's default (5000) applies again. The 30000 of 0.3.1 was the wrong fix. It rested on the idea that a restarted runner makes the next mutant slow, when in fact a runner that is not restarted stays slow. With 30000 the same full run took about three times as long and still failed, and mutants that exhaust the heap crashed the runner and were reported as `RuntimeError` instead of `Timeout`.
|
|
15
|
+
|
|
16
|
+
A project that set `timeoutMS` itself to work around stray timeouts can remove it.
|
|
17
|
+
|
|
3
18
|
## 0.3.1
|
|
4
19
|
|
|
5
20
|
### Changed
|
|
6
21
|
|
|
7
|
-
- `createStrykerGatesConfig` sets Stryker's `timeoutMS` to 30000 unless the project passes its own (Stryker's default is 5000). With `maxTimeouts` at 0 since 0.3.0, a mutant that would be killed but ran out of time fails the run. That happened on every full run in
|
|
22
|
+
- `createStrykerGatesConfig` sets Stryker's `timeoutMS` to 30000 unless the project passes its own (Stryker's default is 5000). With `maxTimeouts` at 0 since 0.3.0, a mutant that would be killed but ran out of time fails the run. That happened on every full run in projects with mutants that really never end: after each of them Stryker starts a new test runner, and the next mutant timed out while it was starting. A full run takes longer by up to 25 seconds for each mutant that hangs without tripping Stryker's loop counter.
|
|
8
23
|
|
|
9
24
|
## 0.3.0
|
|
10
25
|
|
|
@@ -35,7 +50,7 @@ A manifest that uses the new settings needs 0.2.0 or later, because 0.1.0 reject
|
|
|
35
50
|
- `test-gates check` warns when the gate run uses Vitest below 4 with the v8 provider, which does not count the skipped side of an `if` without `else`.
|
|
36
51
|
- `test-gates selfcheck` names the gates that import a gate whose spec could be left out without the gate failing.
|
|
37
52
|
- CI for this repository (lint, tests, gates, negative control, full mutation run; build and tests on Node 20).
|
|
38
|
-
- README: when the package is worth using, timeouts, allowlist mode, the Vitest v8 / istanbul measurements, cost and incremental mode, settings for Dart, and notes from
|
|
53
|
+
- README: when the package is worth using, timeouts, allowlist mode, the Vitest v8 / istanbul measurements, cost and incremental mode, settings for Dart, and notes from adopting it in several repositories.
|
|
39
54
|
|
|
40
55
|
### Changed
|
|
41
56
|
|
package/README.md
CHANGED
|
@@ -44,22 +44,22 @@ Everything below is per subproject (the directory that has a `package.json`: `ba
|
|
|
44
44
|
"$schema": "./node_modules/@t09tanaka/test-gates/schema/test-gates.schema.json",
|
|
45
45
|
"gates": [
|
|
46
46
|
{
|
|
47
|
-
"path": "src/
|
|
48
|
-
"decides": "
|
|
49
|
-
"impact": "
|
|
47
|
+
"path": "src/shipping-fee.ts",
|
|
48
|
+
"decides": "The fee for sending a parcel, by weight, and its maximum",
|
|
49
|
+
"impact": "A heavy parcel is sent for too little, or the customer pays more than the advertised maximum"
|
|
50
50
|
}
|
|
51
51
|
],
|
|
52
52
|
"candidates": [
|
|
53
53
|
{
|
|
54
|
-
"path": "src/
|
|
55
|
-
"decides": "Who
|
|
54
|
+
"path": "src/warehouse/dispatch.guard.ts",
|
|
55
|
+
"decides": "Who may release an order for dispatch",
|
|
56
56
|
"blocker": "Has decorators. The decision has to be extracted into a pure module"
|
|
57
57
|
}
|
|
58
58
|
]
|
|
59
59
|
}
|
|
60
60
|
```
|
|
61
61
|
|
|
62
|
-
- `gates`: pure modules that hold an important decision. Each one needs a spec next to it (`
|
|
62
|
+
- `gates`: pure modules that hold an important decision. Each one needs a spec next to it (`shipping-fee.spec.ts` or `shipping-fee.test.ts`), 100% on statements, branches, functions and lines, and no surviving mutant outside its allow list.
|
|
63
63
|
- `candidates`: important logic that cannot be a gate yet, with what blocks it. Nothing is enforced for these except that the path exists.
|
|
64
64
|
- `settings`: optional project conventions, see [Settings](#settings).
|
|
65
65
|
|
|
@@ -234,10 +234,10 @@ The run also fails when
|
|
|
234
234
|
|
|
235
235
|
`Timeout` counts as detected, but its count is always printed on its own (`detected N (timeout M)`). On a loaded machine mutants time out that would otherwise survive, so a timeout nobody has explained fails the run.
|
|
236
236
|
|
|
237
|
-
On failure every unallowed survivor is listed as `file:line:column / mutator / original → replacement / occurrence`, followed by a JSON fragment that can be pasted into `equivalentMutants`. The last line gives the real numbers, never a percentage:
|
|
237
|
+
On failure every unallowed survivor is listed as `file:line:column / mutator / original → replacement / occurrence`, followed by a JSON fragment that can be pasted into `equivalentMutants`. The last line gives the real numbers, never a percentage. For the gates of this repository:
|
|
238
238
|
|
|
239
239
|
```
|
|
240
|
-
test-gates mutation: OK (mutants
|
|
240
|
+
test-gates mutation: OK (mutants 1017 / detected 1017 (timeout 2) / allowed equivalent 0 / not evaluable 0 / unallowed survivors 0)
|
|
241
241
|
```
|
|
242
242
|
|
|
243
243
|
#### Timeouts
|
|
@@ -280,7 +280,9 @@ How an `expectedTimeouts` entry is judged:
|
|
|
280
280
|
|
|
281
281
|
When the run fails on a timeout, first run again with less load (`npm run test:gates:mutation -- --concurrency 1`). Add an entry only for a mutant that can never finish.
|
|
282
282
|
|
|
283
|
-
`createStrykerGatesConfig` sets Stryker's `
|
|
283
|
+
`createStrykerGatesConfig` sets Stryker's `maxTestRunnerReuse` to 50 (since 0.3.2; Stryker's own default is 0, one test runner process for the whole run). A mutant that would be killed can also time out for a reason that has nothing to do with the mutant: in a Jest project with a few mutants that never end, the test runner handled about a third as many mutants per minute from the first of them on, for the rest of the run. Mutants that are killed in seconds on their own then timed out, a different set on each full run, and the run took about a quarter of an hour. With a new process every 50 mutants the speed stayed the same to the end, nothing timed out that should not, and the run took less than half as long. Why the runner slows down was not found; the restart only cuts it short. Pass `maxTestRunnerReuse` to the helper to change it.
|
|
284
|
+
|
|
285
|
+
0.3.1 set `timeoutMS` to 30000 instead. That was the wrong fix and 0.3.2 takes it back: the longer limit let most slow mutants finish, but the same full run then took about three times as long as without it, and in another project mutants that exhaust the heap crashed the test runner before the limit and came back as `RuntimeError`, which is only counted, not failed. `timeoutMS` is Stryker's default (5000) again unless the project sets it.
|
|
284
286
|
|
|
285
287
|
### `test-gates selfcheck [--all | --first] [-- <gate command>]`
|
|
286
288
|
|
|
@@ -288,17 +290,17 @@ Negative control. For each gate, runs the gate with that gate's spec left out an
|
|
|
288
290
|
|
|
289
291
|
The spec to leave out is passed in the environment variable `TEST_GATES_EXCLUDE_SPEC`. The config helpers read it. The gate command is `jest --config jest.gates.config.*` or `vitest run --config vitest.gates.config.*`, whichever config exists; override it with `settings.gateCommand` or after `--`. `--all` (default) checks every gate in turn, `--first` only the first.
|
|
290
292
|
|
|
291
|
-
**When a gate imports another gate.** If `
|
|
293
|
+
**When a gate imports another gate.** If `delivery-price.ts` imports `shipping-fee.ts` and both are gates, the spec of `delivery-price` executes every line of `shipping-fee` as well. Leaving out `shipping-fee.spec.ts` then does not lower its coverage, and `selfcheck` fails for `shipping-fee` ("the gate passed although the spec … was left out"), naming the importing gate in a hint. The coverage floor of `shipping-fee` is being held up by somebody else's spec. Fix it in the importer's spec: mock the imported gate and assert **how it is called**, so that each spec covers only its own gate:
|
|
292
294
|
|
|
293
295
|
```ts
|
|
294
|
-
jest.mock('./
|
|
296
|
+
jest.mock('./shipping-fee');
|
|
295
297
|
// …
|
|
296
|
-
expect(
|
|
298
|
+
expect(shippingFeeCents).toHaveBeenCalledWith(weightGrams); // called with the weight, not with the price
|
|
297
299
|
```
|
|
298
300
|
|
|
299
301
|
### `test-gates lcov --file <lcov.info>`
|
|
300
302
|
|
|
301
|
-
For stacks without mutation testing (Flutter / Dart): requires `LH == LF` for every gate in an lcov tracefile. A gate without a record, or with no instrumented line, fails. Paths are compared as written in the tracefile (`lib/
|
|
303
|
+
For stacks without mutation testing (Flutter / Dart): requires `LH == LF` for every gate in an lcov tracefile. A gate without a record, or with no instrumented line, fails. Paths are compared as written in the tracefile (`lib/shipping_fee.dart`); absolute paths under the subproject are made relative.
|
|
302
304
|
|
|
303
305
|
```bash
|
|
304
306
|
flutter test --coverage && npx test-gates lcov --file coverage/lcov.info
|
|
@@ -308,7 +310,7 @@ Settings for a Dart package that uses only `lcov`:
|
|
|
308
310
|
|
|
309
311
|
```json
|
|
310
312
|
{
|
|
311
|
-
"gates": [{ "path": "lib/
|
|
313
|
+
"gates": [{ "path": "lib/shipping_fee.dart", "decides": "…", "impact": "…" }],
|
|
312
314
|
"candidates": [],
|
|
313
315
|
"settings": {
|
|
314
316
|
"gateExtensions": [".dart"],
|
|
@@ -324,19 +326,47 @@ Lines are counted from the `DA:` entries, not taken from `LH:` / `LF:`. A tracef
|
|
|
324
326
|
|
|
325
327
|
## Allowing an equivalent mutant
|
|
326
328
|
|
|
327
|
-
An equivalent mutant changes the code without changing anything observable: same return value, same exception, same side effects, for every input. Only those may be allowed, in `test-gates.json`, with the reason
|
|
329
|
+
An equivalent mutant changes the code without changing anything observable: same return value, same exception, same side effects, for every input. Only those may be allowed, in `test-gates.json`, with the reason.
|
|
330
|
+
|
|
331
|
+
An example. A gate limits a fee to a maximum:
|
|
332
|
+
|
|
333
|
+
```ts
|
|
334
|
+
let fee = Math.ceil(weightGrams / 1000) * 500;
|
|
335
|
+
if (fee > MAX_FEE_CENTS) {
|
|
336
|
+
fee = MAX_FEE_CENTS;
|
|
337
|
+
}
|
|
338
|
+
return fee;
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
The specs check every boundary, and one mutant still survives:
|
|
342
|
+
|
|
343
|
+
```
|
|
344
|
+
test-gates mutation: 1 surviving mutant(s) not in the allow list
|
|
345
|
+
- src/shipping-fee.ts:9:7 / EqualityOperator / fee > MAX_FEE_CENTS → fee >= MAX_FEE_CENTS (Survived)
|
|
346
|
+
|
|
347
|
+
Fix the test so that it detects the mutant. Only when the mutant cannot be observed from
|
|
348
|
+
outside (same return value, exception and side effects for every input), add it to
|
|
349
|
+
"equivalentMutants" of the gate in test-gates.json and fill in "reason":
|
|
350
|
+
|
|
351
|
+
src/shipping-fee.ts
|
|
352
|
+
{"mutator":"EqualityOperator","original":"fee > MAX_FEE_CENTS","replacement":"fee >= MAX_FEE_CENTS","reason":""}
|
|
353
|
+
|
|
354
|
+
test-gates mutation: FAILED (mutants 14 / detected 13 (timeout 0) / allowed equivalent 0 / not evaluable 0 / unallowed survivors 1)
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
With `>=` the only input that is treated differently is a fee equal to the maximum, and that fee is set to the value it already has. No test can tell the two apart, so the gate lists the mutant:
|
|
328
358
|
|
|
329
359
|
```json
|
|
330
360
|
{
|
|
331
|
-
"path": "src/
|
|
332
|
-
"decides": "
|
|
333
|
-
"impact": "
|
|
361
|
+
"path": "src/shipping-fee.ts",
|
|
362
|
+
"decides": "The fee for sending a parcel, by weight, and its maximum",
|
|
363
|
+
"impact": "A heavy parcel is sent for too little, or the customer pays more than the advertised maximum",
|
|
334
364
|
"equivalentMutants": [
|
|
335
365
|
{
|
|
336
|
-
"mutator": "
|
|
337
|
-
"original": "
|
|
338
|
-
"replacement": "
|
|
339
|
-
"reason": "
|
|
366
|
+
"mutator": "EqualityOperator",
|
|
367
|
+
"original": "fee > MAX_FEE_CENTS",
|
|
368
|
+
"replacement": "fee >= MAX_FEE_CENTS",
|
|
369
|
+
"reason": "A fee that is equal to the maximum is set to the maximum, which is the value it has"
|
|
340
370
|
}
|
|
341
371
|
]
|
|
342
372
|
}
|
|
@@ -390,17 +420,17 @@ Project-specific layers go into `add`:
|
|
|
390
420
|
"impureImports": {
|
|
391
421
|
"add": [
|
|
392
422
|
{
|
|
393
|
-
"pattern": "(^|/)(
|
|
394
|
-
"reason": "
|
|
423
|
+
"pattern": "(^|/)(persistence|gateways)(/|$)",
|
|
424
|
+
"reason": "talks to the database or to a remote API"
|
|
395
425
|
},
|
|
396
|
-
{ "pattern": "\\.(service|
|
|
426
|
+
{ "pattern": "\\.(service|controller)$", "reason": "class created by the DI container" }
|
|
397
427
|
]
|
|
398
428
|
},
|
|
399
429
|
"impurePaths": {
|
|
400
430
|
"add": [
|
|
401
431
|
{
|
|
402
|
-
"pattern": "\\.(service|
|
|
403
|
-
"reason": "
|
|
432
|
+
"pattern": "\\.(service|controller|module)\\.ts$",
|
|
433
|
+
"reason": "a class with decorators"
|
|
404
434
|
}
|
|
405
435
|
]
|
|
406
436
|
}
|
|
@@ -462,7 +492,7 @@ Why these choices:
|
|
|
462
492
|
- Jest measures with istanbul (`babel`), because the v8 provider does not count the untaken side of an `if` without `else`.
|
|
463
493
|
- Jest fails on a `coverageThreshold` path key that matches no file, so a typo in `test-gates.json` cannot pass. Vitest does the opposite: a glob or path key in `thresholds` that matches nothing passes. The Vitest helper therefore narrows `coverage.include` to the gates and uses `perFile`.
|
|
464
494
|
- Stryker never fails on its own score (`break: null`). The verdict comes from `test-gates mutation`, which knows the allow list.
|
|
465
|
-
- The Stryker helper also sets defaults that can be overridden: `coverageAnalysis: 'perTest'`, `incremental` with its file under `reports/`, and `
|
|
495
|
+
- The Stryker helper also sets defaults that can be overridden: `coverageAnalysis: 'perTest'`, `incremental` with its file under `reports/`, and `maxTestRunnerReuse: 50` (see [Timeouts](#timeouts)).
|
|
466
496
|
|
|
467
497
|
`loadGates(dir)` returns the validated manifest: `gates` (each with its resolved `spec`), `candidates` and the resolved `settings`. It throws when the manifest has any problem.
|
|
468
498
|
|
package/dist/stryker.cjs
CHANGED
|
@@ -30,7 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/stryker.ts
|
|
31
31
|
var stryker_exports = {};
|
|
32
32
|
__export(stryker_exports, {
|
|
33
|
-
|
|
33
|
+
DEFAULT_MAX_TEST_RUNNER_REUSE: () => DEFAULT_MAX_TEST_RUNNER_REUSE,
|
|
34
34
|
createStrykerGatesConfig: () => createStrykerGatesConfig
|
|
35
35
|
});
|
|
36
36
|
module.exports = __toCommonJS(stryker_exports);
|
|
@@ -602,7 +602,7 @@ function resolveRootDir(rootDir) {
|
|
|
602
602
|
|
|
603
603
|
// src/stryker.ts
|
|
604
604
|
var WEAKENING_OPTIONS = ["ignoreStatic", "ignorers"];
|
|
605
|
-
var
|
|
605
|
+
var DEFAULT_MAX_TEST_RUNNER_REUSE = 50;
|
|
606
606
|
function createStrykerGatesConfig(options = {}) {
|
|
607
607
|
const { rootDir: rootDirOption, ...overrides } = options;
|
|
608
608
|
for (const option of WEAKENING_OPTIONS) {
|
|
@@ -627,7 +627,7 @@ function createStrykerGatesConfig(options = {}) {
|
|
|
627
627
|
incremental: true,
|
|
628
628
|
incrementalFile: "reports/stryker-incremental.json",
|
|
629
629
|
tempDirName: ".stryker-tmp",
|
|
630
|
-
|
|
630
|
+
maxTestRunnerReuse: DEFAULT_MAX_TEST_RUNNER_REUSE,
|
|
631
631
|
clearTextReporter: { logTests: false, reportTests: false },
|
|
632
632
|
...overrides,
|
|
633
633
|
mutate: manifest.gates.map((gate) => gate.path),
|
|
@@ -638,6 +638,6 @@ function createStrykerGatesConfig(options = {}) {
|
|
|
638
638
|
}
|
|
639
639
|
// Annotate the CommonJS export names for ESM import in node:
|
|
640
640
|
0 && (module.exports = {
|
|
641
|
-
|
|
641
|
+
DEFAULT_MAX_TEST_RUNNER_REUSE,
|
|
642
642
|
createStrykerGatesConfig
|
|
643
643
|
});
|
package/dist/stryker.d.cts
CHANGED
|
@@ -5,11 +5,13 @@ interface StrykerGatesOptions {
|
|
|
5
5
|
[option: string]: unknown;
|
|
6
6
|
}
|
|
7
7
|
/**
|
|
8
|
-
* Stryker's own default is
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
* Stryker's own default is 0: one test runner process for the whole run. Measured on a Jest
|
|
9
|
+
* project with a few mutants that never end (`Hit limit reached`): from the first of them on
|
|
10
|
+
* the runner handled about a third as many mutants per minute for the rest of the run, and
|
|
11
|
+
* mutants that are killed in seconds on their own ran out of time. With a new process every 50
|
|
12
|
+
* mutants the speed stayed the same to the end.
|
|
11
13
|
*/
|
|
12
|
-
declare const
|
|
14
|
+
declare const DEFAULT_MAX_TEST_RUNNER_REUSE = 50;
|
|
13
15
|
/**
|
|
14
16
|
* Stryker config for the gates: mutate exactly the gates, never fail on the score
|
|
15
17
|
* (`thresholds.break: null`), and write the JSON report that `test-gates mutation` judges.
|
|
@@ -19,4 +21,4 @@ declare const DEFAULT_TIMEOUT_MS = 30000;
|
|
|
19
21
|
*/
|
|
20
22
|
declare function createStrykerGatesConfig(options?: StrykerGatesOptions): Record<string, unknown>;
|
|
21
23
|
|
|
22
|
-
export {
|
|
24
|
+
export { DEFAULT_MAX_TEST_RUNNER_REUSE, type StrykerGatesOptions, createStrykerGatesConfig };
|
package/dist/stryker.d.ts
CHANGED
|
@@ -5,11 +5,13 @@ interface StrykerGatesOptions {
|
|
|
5
5
|
[option: string]: unknown;
|
|
6
6
|
}
|
|
7
7
|
/**
|
|
8
|
-
* Stryker's own default is
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
* Stryker's own default is 0: one test runner process for the whole run. Measured on a Jest
|
|
9
|
+
* project with a few mutants that never end (`Hit limit reached`): from the first of them on
|
|
10
|
+
* the runner handled about a third as many mutants per minute for the rest of the run, and
|
|
11
|
+
* mutants that are killed in seconds on their own ran out of time. With a new process every 50
|
|
12
|
+
* mutants the speed stayed the same to the end.
|
|
11
13
|
*/
|
|
12
|
-
declare const
|
|
14
|
+
declare const DEFAULT_MAX_TEST_RUNNER_REUSE = 50;
|
|
13
15
|
/**
|
|
14
16
|
* Stryker config for the gates: mutate exactly the gates, never fail on the score
|
|
15
17
|
* (`thresholds.break: null`), and write the JSON report that `test-gates mutation` judges.
|
|
@@ -19,4 +21,4 @@ declare const DEFAULT_TIMEOUT_MS = 30000;
|
|
|
19
21
|
*/
|
|
20
22
|
declare function createStrykerGatesConfig(options?: StrykerGatesOptions): Record<string, unknown>;
|
|
21
23
|
|
|
22
|
-
export {
|
|
24
|
+
export { DEFAULT_MAX_TEST_RUNNER_REUSE, type StrykerGatesOptions, createStrykerGatesConfig };
|
package/dist/stryker.js
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
|
|
8
8
|
// src/stryker.ts
|
|
9
9
|
var WEAKENING_OPTIONS = ["ignoreStatic", "ignorers"];
|
|
10
|
-
var
|
|
10
|
+
var DEFAULT_MAX_TEST_RUNNER_REUSE = 50;
|
|
11
11
|
function createStrykerGatesConfig(options = {}) {
|
|
12
12
|
const { rootDir: rootDirOption, ...overrides } = options;
|
|
13
13
|
for (const option of WEAKENING_OPTIONS) {
|
|
@@ -32,7 +32,7 @@ function createStrykerGatesConfig(options = {}) {
|
|
|
32
32
|
incremental: true,
|
|
33
33
|
incrementalFile: "reports/stryker-incremental.json",
|
|
34
34
|
tempDirName: ".stryker-tmp",
|
|
35
|
-
|
|
35
|
+
maxTestRunnerReuse: DEFAULT_MAX_TEST_RUNNER_REUSE,
|
|
36
36
|
clearTextReporter: { logTests: false, reportTests: false },
|
|
37
37
|
...overrides,
|
|
38
38
|
mutate: manifest.gates.map((gate) => gate.path),
|
|
@@ -42,6 +42,6 @@ function createStrykerGatesConfig(options = {}) {
|
|
|
42
42
|
};
|
|
43
43
|
}
|
|
44
44
|
export {
|
|
45
|
-
|
|
45
|
+
DEFAULT_MAX_TEST_RUNNER_REUSE,
|
|
46
46
|
createStrykerGatesConfig
|
|
47
47
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@t09tanaka/test-gates",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"description": "Test gates for the code that must not be wrong: per-file 100% coverage as the floor, mutation testing with a per-mutant allow list as the real check.",
|
|
5
5
|
"author": "t09tanaka",
|
|
6
6
|
"license": "MIT",
|