@systemfsoftware/stryker-js 12.0.0 → 12.1.0
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 +30 -0
- package/README.md +31 -9
- package/dist/{Run.schema-BxsyHwHr.mjs → Run.schema-BaK_pxuK.mjs} +16 -3
- package/dist/{Run.schema-D43Nx5kI.d.mts → Run.schema-BnUKGQjA.d.mts} +4 -2
- package/dist/{RunEnvironment.service-pCzdC0Sy.d.mts → RunEnvironment.service-BaTBH0mI.d.mts} +3 -3
- package/dist/config.d.mts +2 -2
- package/dist/events.d.mts +1 -1
- package/dist/events.mjs +1 -1
- package/dist/{index-f-U3oZaJ.d.mts → index-CKd1sAni.d.mts} +926 -913
- package/dist/index.d.mts +19 -12
- package/dist/index.mjs +6 -3
- package/dist/main.mjs +11311 -40154
- package/dist/promises.d.mts +2 -2
- package/dist/promises.mjs +1 -1
- package/dist/{run-stages.cell-MyhsNxH2.mjs → run-stages.cell-RwTUyNX9.mjs} +177 -268
- package/dist/{stryker-config.schema-GS_4_5gX.d.mts → stryker-config.schema-VVxHqsAv.d.mts} +1 -1
- package/package.json +9 -8
- package/dist/dist-DKhCurgc.mjs +0 -1524
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
# @systemfsoftware/stryker-js
|
|
2
2
|
|
|
3
|
+
## 12.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- A piped `stdout` now gets human output, exactly like a terminal. Machine consumers ask for the NDJSON event stream explicitly, with `--json` or `STRYKER_MODE=machine`; `--format text` names the human format, and passing it together with `--json` is a usage error (exit 2). Under `--json`, `stdout` carries wire records and nothing else, while progress status lines and log output stay on `stderr`.
|
|
8
|
+
|
|
9
|
+
Every run also writes those wire records to `reports/mutation-stream.jsonl` in human mode too, so a job that shows a readable log still produces the artifact `stryker merge-reports` rebuilds a shard's report from.
|
|
10
|
+
|
|
11
|
+
If a script or CI step read NDJSON from a piped run without requesting it, pass `--json` (or set `STRYKER_MODE=machine`) there.
|
|
12
|
+
|
|
13
|
+
Custom `RunEventDrain` implementations must accept a required `toStdout` argument in `drainFramed`; pass-throughs can ignore it.
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- A run whose selected files produce no mutants, for example because no loaded framework claims them, now runs every test in the dry run and finishes with an empty report. With `testRunner: 'vm'` or `'vitest'` it used to fail with "No tests were executed", because the dry run only looked for tests related to those files. The dry run now relates tests only to the files that carry mutants.
|
|
18
|
+
|
|
19
|
+
- A run whose `mutate` patterns match no file now finishes successfully instead of stopping with an instrument error. It performs the dry run, writes a mutation report with no files, and passes regardless of `thresholds.break`, the same as upstream StrykerJS. A sharded run whose shard receives no file no longer fails.
|
|
20
|
+
|
|
21
|
+
`stryker merge-reports` shows `n/a` for a package whose report has no tested mutant, instead of a score of `0.00`.
|
|
22
|
+
|
|
23
|
+
Errors reported for the prepare, dry-run, and mutation-testing stages now carry their reason as the error message, so a printed cause no longer shows up as a bare error name.
|
|
24
|
+
|
|
25
|
+
- `stryker merge-reports` now rebuilds a package's partial report from the mutants recorded in its stream part when the run ended before writing its final report. Earlier versions recognized none of the recorded mutants and reported the package as having no report.
|
|
26
|
+
|
|
27
|
+
- Mutation runs with `testRunner: 'vm'` finish in about half the time, with the same verdicts. The engine checks mutant groups on every checker process at once, stops the checkers as soon as checking ends, hands their share of `concurrency` to the test runners, and shares a Node compile cache with every worker it starts. The Vitest runner starts the next isolated worker thread while the current test file runs, so each file still gets a fresh thread but no longer waits for one to boot. On a 319-mutant TypeScript project with the TypeScript checker, a run went from 24.9 s to 12.6 s.
|
|
28
|
+
|
|
29
|
+
- `testRunner: 'vm'` runs Vitest itself on Vitest's isolated `threads` pool instead of an in-process reimplementation, and stays the default `testRunner`. It reports the same test ids, outcomes and per-mutant verdicts as `testRunner: 'vitest'`, so a project whose Vitest config enables browser mode is refused at startup with a message naming `testRunner: 'vitest'`.
|
|
30
|
+
|
|
31
|
+
Stryker no longer discovers test files for `vm`: Vitest selects them from your config, as it does for `testRunner: 'vitest'`. A run that loads no test files fails the dry run naming `testFiles`.
|
|
32
|
+
|
|
3
33
|
## 12.0.0
|
|
4
34
|
|
|
5
35
|
### Major Changes
|
package/README.md
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
The modern mutation testing framework for JavaScript and TypeScript.
|
|
4
4
|
A ground-up, breaking-change fork of `@stryker-mutator/core` built with Effect 4:
|
|
5
|
-
provides the `stryker` executable,
|
|
6
|
-
|
|
5
|
+
provides the `stryker` executable, the `vm` and `vitest` test runners, and the
|
|
6
|
+
typed `./config` authoring surface.
|
|
7
7
|
|
|
8
8
|
## Install
|
|
9
9
|
|
|
@@ -54,10 +54,13 @@ pnpm exec stryker run
|
|
|
54
54
|
|
|
55
55
|
## Zero-Plugin Built-in Runners
|
|
56
56
|
|
|
57
|
-
The `vm` runner is the default
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
57
|
+
The `vm` runner is the default and needs no plugin packages: `testRunner: 'vm'`
|
|
58
|
+
runs Vitest itself, on Vitest's isolated `threads` pool, through the project's
|
|
59
|
+
own `vitest` install (`vitest` must be installed). With no `testFiles`
|
|
60
|
+
configured, Vitest selects the test files from your config, exactly as
|
|
61
|
+
`vitest run` does. The runner reports the same test ids, outcomes and
|
|
62
|
+
per-mutant verdicts as `vitest run`. Set `testFiles` explicitly, or pick one of
|
|
63
|
+
the runners below, to take control.
|
|
61
64
|
|
|
62
65
|
### 1. Shell Command Runner (`testRunner: 'command'`)
|
|
63
66
|
|
|
@@ -75,9 +78,13 @@ export default defineConfig({
|
|
|
75
78
|
})
|
|
76
79
|
```
|
|
77
80
|
|
|
78
|
-
### 2.
|
|
81
|
+
### 2. The `vm` Runner (`testRunner: 'vm'`)
|
|
79
82
|
|
|
80
|
-
Runs Vitest
|
|
83
|
+
Runs the Vitest runner on Vitest's isolated `threads` pool. Each test file keeps
|
|
84
|
+
Vitest's own per-file isolation, and module mocking, snapshots, environments,
|
|
85
|
+
setup files, projects and custom transforms behave as they do under
|
|
86
|
+
`vitest run`. A Vitest config that enables browser mode is refused with an
|
|
87
|
+
error naming `testRunner: 'vitest'`; pick the `vitest` runner for those.
|
|
81
88
|
|
|
82
89
|
```ts
|
|
83
90
|
import { defineConfig } from '@systemfsoftware/stryker-js/config'
|
|
@@ -89,6 +96,10 @@ export default defineConfig({
|
|
|
89
96
|
})
|
|
90
97
|
```
|
|
91
98
|
|
|
99
|
+
Suites that need Vitest's `forks` pool (for example `process.chdir`, or native
|
|
100
|
+
addons that are not thread-safe) use `testRunner: 'vitest'` with the
|
|
101
|
+
`@systemfsoftware/stryker-js-vitest-runner` plugin instead.
|
|
102
|
+
|
|
92
103
|
## Configuration API (`@systemfsoftware/stryker-js/config`)
|
|
93
104
|
|
|
94
105
|
The `./config` subpath exports the typed configuration authoring surface, including the `StrykerConfig` type naming the partial options a config file writes: a config annotated `const config: StrykerConfig = defineConfig({ ... })` typechecks and loads.
|
|
@@ -143,9 +154,20 @@ pnpm exec stryker run --incremental
|
|
|
143
154
|
pnpm exec stryker run --concurrency 4
|
|
144
155
|
|
|
145
156
|
# Merge partial mutation reports from parallel CI shards
|
|
146
|
-
pnpm exec stryker merge-reports --
|
|
157
|
+
pnpm exec stryker merge-reports --parts reports/shards --out reports/mutation
|
|
147
158
|
```
|
|
148
159
|
|
|
160
|
+
## Output Modes
|
|
161
|
+
|
|
162
|
+
Human output is the default, whether or not `stdout` is a terminal. A machine consumer opts into the NDJSON event stream explicitly:
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
pnpm exec stryker run --json # wire records on stdout, diagnostics on stderr
|
|
166
|
+
STRYKER_MODE=machine pnpm exec stryker run # the same, named by environment
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
`--format text` names the human format explicitly; `--json` together with `--format text` is a usage error (exit 2). Under `--json`, `stdout` carries wire records and nothing else — progress lines and log output stay on `stderr`. Every run also writes the same records to `reports/mutation-stream.jsonl` (`--progressStreamFile`) in both modes, which is the artifact `stryker merge-reports` rebuilds a shard's partial report from.
|
|
170
|
+
|
|
149
171
|
## Programmatic API
|
|
150
172
|
|
|
151
173
|
### Effect 4 Native Interface
|
|
@@ -7233,6 +7233,10 @@ const Percentage = S.Finite.pipe(S.check(S.isBetween({
|
|
|
7233
7233
|
minimum: 0,
|
|
7234
7234
|
maximum: 100
|
|
7235
7235
|
})));
|
|
7236
|
+
const MutationScore = S.TaggedUnion({
|
|
7237
|
+
Scored: { percentage: Percentage },
|
|
7238
|
+
Unscored: {}
|
|
7239
|
+
});
|
|
7236
7240
|
var Metrics = class Metrics extends S.Class("Metrics")({
|
|
7237
7241
|
pending: NonNegativeInt,
|
|
7238
7242
|
killed: NonNegativeInt,
|
|
@@ -7262,10 +7266,10 @@ var Metrics = class Metrics extends S.Class("Metrics")({
|
|
|
7262
7266
|
return this.totalValid + this.totalInvalid + this.ignored + this.pending;
|
|
7263
7267
|
}
|
|
7264
7268
|
get mutationScore() {
|
|
7265
|
-
return
|
|
7269
|
+
return scoreOf(this.totalDetected, this.totalValid);
|
|
7266
7270
|
}
|
|
7267
7271
|
get mutationScoreBasedOnCoveredCode() {
|
|
7268
|
-
return
|
|
7272
|
+
return scoreOf(this.totalDetected, this.totalCovered);
|
|
7269
7273
|
}
|
|
7270
7274
|
static fromMutants(mutants) {
|
|
7271
7275
|
return Metrics.make({
|
|
@@ -7281,6 +7285,10 @@ var Metrics = class Metrics extends S.Class("Metrics")({
|
|
|
7281
7285
|
}
|
|
7282
7286
|
};
|
|
7283
7287
|
const metricCountOf = (mutants, status) => mutants.filter((mutant) => mutant.status === status).length;
|
|
7288
|
+
const scoreOf = (detected, counted) => Boolean$1$1.match(counted > 0, {
|
|
7289
|
+
onTrue: () => MutationScore.cases.Scored.make({ percentage: detected / counted * 100 }),
|
|
7290
|
+
onFalse: () => MutationScore.cases.Unscored.make({})
|
|
7291
|
+
});
|
|
7284
7292
|
const MetricsSchema = Metrics;
|
|
7285
7293
|
const MetricsResultSchema = S.Struct({
|
|
7286
7294
|
name: S.String,
|
|
@@ -7890,6 +7898,7 @@ var Report_exports = /* @__PURE__ */ __exportAll$1({
|
|
|
7890
7898
|
MetricsResultSchema: () => MetricsResultSchema,
|
|
7891
7899
|
MetricsSchema: () => MetricsSchema,
|
|
7892
7900
|
MutantResultSchema: () => MutantResultSchema,
|
|
7901
|
+
MutationScore: () => MutationScore,
|
|
7893
7902
|
MutationTestResultSchema: () => MutationTestResultSchema,
|
|
7894
7903
|
NonNegativeFinite: () => NonNegativeFinite,
|
|
7895
7904
|
NonNegativeInt: () => NonNegativeInt,
|
|
@@ -8256,6 +8265,10 @@ const STAGE_PRESENTATION = {
|
|
|
8256
8265
|
var PrepareError = class extends S.TaggedError()("PrepareError", {
|
|
8257
8266
|
stage: S.Literal("prepare"),
|
|
8258
8267
|
reason: S.String
|
|
8259
|
-
}) {
|
|
8268
|
+
}) {
|
|
8269
|
+
get message() {
|
|
8270
|
+
return this.reason;
|
|
8271
|
+
}
|
|
8272
|
+
};
|
|
8260
8273
|
//#endregion
|
|
8261
8274
|
export { Plugin_exports as A, RunReadError as C, VerdictReached as D, SkippedReported as E, ErrorText_exports as F, Format_exports as I, Instrument_exports as L, Reporter_exports as M, TestRunner_exports as N, Checker_exports as O, Trace_exports as P, Mutant_exports as R, RunPhase as S, SkippedFileRow as T, PluginsReported as _, FormatRegistryRow as a, RunFailed as b, Heartbeat as c, MutationRunPlan as d, OutputMode as f, PluginFailureReason as g, PlanMutationRunCommand as h, FormatRegistryResolved as i, Report_exports as j, Options_exports as k, HelpRendered as l, PlanKnown as m, StageError as n, FrameworkContributionRow as o, PhaseEntered as p, FormatClaimShadowingRow as r, FrameworkModuleRow as s, PrepareError as t, ModeSignal as u, RunDecodeError as v, RunStarted as w, RunMutantTested as x, RunEvent as y };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as mod_d_exports$4, r as mod_d_exports$3 } from "./index-
|
|
1
|
+
import { i as mod_d_exports$4, r as mod_d_exports$3 } from "./index-CKd1sAni.mjs";
|
|
2
2
|
import * as S from "effect/Schema";
|
|
3
3
|
//#region src/run-event.schema.d.ts
|
|
4
4
|
declare const RunPhase: S.Literals<readonly ["prepare", "instrument", "dry-run", "mutation-test"]>;
|
|
@@ -240,6 +240,8 @@ declare const PrepareError_base: S.Class<PrepareError, S.TaggedStruct<"PrepareEr
|
|
|
240
240
|
readonly stage: S.Literal<"prepare">;
|
|
241
241
|
readonly reason: S.String;
|
|
242
242
|
}>, import("effect/Cause").YieldableError>;
|
|
243
|
-
declare class PrepareError extends PrepareError_base {
|
|
243
|
+
declare class PrepareError extends PrepareError_base {
|
|
244
|
+
get message(): string;
|
|
245
|
+
}
|
|
244
246
|
//#endregion
|
|
245
247
|
export { VerdictReached as A, RunReadError as C, SkippedReported as D, SkippedFileRow as E, VerdictCounts as O, RunPhase as S, RunTerminalEvent as T, PluginsReported as _, FormatRegistryRow as a, RunFailed as b, Heartbeat as c, MutationRunPlan as d, OutputMode as f, PluginFailureReason as g, PlanMutationRunCommand as h, FormatRegistryResolved as i, VerdictThresholds as j, VerdictMutant as k, HelpRendered as l, PlanKnown as m, StageError as n, FrameworkContributionRow as o, PhaseEntered as p, FormatClaimShadowingRow as r, FrameworkModuleRow as s, PrepareError as t, ModeSignal as u, RunDecodeError as v, RunStarted as w, RunMutantTested as x, RunEvent as y };
|
package/dist/{RunEnvironment.service-pCzdC0Sy.d.mts → RunEnvironment.service-BaTBH0mI.d.mts}
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as mod_d_exports$5, c as mod_d_exports$2, d as Ignorer, i as mod_d_exports$4, l as mod_d_exports$3$1, n as mod_d_exports$2$1, o as mod_d_exports$6, r as mod_d_exports$3, s as mod_d_exports$1, t as mod_d_exports, u as Framework } from "./index-
|
|
2
|
-
import { A as VerdictReached, D as SkippedReported, _ as PluginsReported, b as RunFailed, c as Heartbeat, i as FormatRegistryResolved, l as HelpRendered, m as PlanKnown, p as PhaseEntered, w as RunStarted, x as RunMutantTested, y as RunEvent } from "./Run.schema-
|
|
1
|
+
import { a as mod_d_exports$5, c as mod_d_exports$2, d as Ignorer, i as mod_d_exports$4, l as mod_d_exports$3$1, n as mod_d_exports$2$1, o as mod_d_exports$6, r as mod_d_exports$3, s as mod_d_exports$1, t as mod_d_exports, u as Framework } from "./index-CKd1sAni.mjs";
|
|
2
|
+
import { A as VerdictReached, D as SkippedReported, _ as PluginsReported, b as RunFailed, c as Heartbeat, i as FormatRegistryResolved, l as HelpRendered, m as PlanKnown, p as PhaseEntered, w as RunStarted, x as RunMutantTested, y as RunEvent } from "./Run.schema-BnUKGQjA.mjs";
|
|
3
3
|
import { Cell, Handle, Sandwich, Workflow } from "@systemfsoftware/effect-cell-types";
|
|
4
4
|
import "effect/Option";
|
|
5
5
|
import "effect/Result";
|
|
@@ -125,7 +125,7 @@ interface ResolvedModeInput {
|
|
|
125
125
|
}
|
|
126
126
|
//#endregion
|
|
127
127
|
//#region src/run-event-stream.service.d.ts
|
|
128
|
-
type FramedDrain = (framed: Stream.Stream<string, never, never
|
|
128
|
+
type FramedDrain = (framed: Stream.Stream<string, never, never>, toStdout: boolean) => Effect$1.Effect<void, never, never>;
|
|
129
129
|
interface RunEventDrainShape {
|
|
130
130
|
readonly drainFramed: FramedDrain;
|
|
131
131
|
readonly setProgressStreamFile: (fileName: string) => Effect$1.Effect<void, never, never>;
|
package/dist/config.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { n as mod_d_exports$2 } from "./index-
|
|
2
|
-
import { a as StrykerConfig, i as Primitive, n as Immutable, o as StrykerConfigExport, r as ImmutablePrimitive, s as StrykerConfigFn, t as ConfigEnv } from "./stryker-config.schema-
|
|
1
|
+
import { n as mod_d_exports$2 } from "./index-CKd1sAni.mjs";
|
|
2
|
+
import { a as StrykerConfig, i as Primitive, n as Immutable, o as StrykerConfigExport, r as ImmutablePrimitive, s as StrykerConfigFn, t as ConfigEnv } from "./stryker-config.schema-VVxHqsAv.mjs";
|
|
3
3
|
//#region src/config/define-config.d.ts
|
|
4
4
|
export declare function defineConfig(config: StrykerConfig): StrykerConfig;
|
|
5
5
|
export declare function defineConfig(config: Promise<StrykerConfig>): Promise<StrykerConfig>;
|
package/dist/events.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { A as VerdictReached, C as RunReadError, D as SkippedReported, E as SkippedFileRow, O as VerdictCounts, S as RunPhase, _ as PluginsReported, a as FormatRegistryRow, b as RunFailed, c as Heartbeat, d as MutationRunPlan, f as OutputMode, g as PluginFailureReason, h as PlanMutationRunCommand, i as FormatRegistryResolved, j as VerdictThresholds, k as VerdictMutant, l as HelpRendered, m as PlanKnown, n as StageError, o as FrameworkContributionRow, p as PhaseEntered, r as FormatClaimShadowingRow, s as FrameworkModuleRow, t as PrepareError, u as ModeSignal, v as RunDecodeError, w as RunStarted, x as RunMutantTested, y as RunEvent } from "./Run.schema-
|
|
1
|
+
import { A as VerdictReached, C as RunReadError, D as SkippedReported, E as SkippedFileRow, O as VerdictCounts, S as RunPhase, _ as PluginsReported, a as FormatRegistryRow, b as RunFailed, c as Heartbeat, d as MutationRunPlan, f as OutputMode, g as PluginFailureReason, h as PlanMutationRunCommand, i as FormatRegistryResolved, j as VerdictThresholds, k as VerdictMutant, l as HelpRendered, m as PlanKnown, n as StageError, o as FrameworkContributionRow, p as PhaseEntered, r as FormatClaimShadowingRow, s as FrameworkModuleRow, t as PrepareError, u as ModeSignal, v as RunDecodeError, w as RunStarted, x as RunMutantTested, y as RunEvent } from "./Run.schema-BnUKGQjA.mjs";
|
|
2
2
|
export { FormatClaimShadowingRow, FormatRegistryResolved, FormatRegistryRow, FrameworkContributionRow, FrameworkModuleRow, Heartbeat, HelpRendered, ModeSignal, MutationRunPlan, OutputMode, PhaseEntered, PlanKnown, PlanMutationRunCommand, PluginFailureReason, PluginsReported, PrepareError, RunDecodeError, RunEvent, RunFailed, RunMutantTested, RunPhase, RunReadError, RunStarted, SkippedFileRow, SkippedReported, StageError, type VerdictCounts, type VerdictMutant, VerdictReached, type VerdictThresholds };
|
package/dist/events.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { C as RunReadError, D as VerdictReached, E as SkippedReported, S as RunPhase, T as SkippedFileRow, _ as PluginsReported, a as FormatRegistryRow, b as RunFailed, c as Heartbeat, d as MutationRunPlan, f as OutputMode, g as PluginFailureReason, h as PlanMutationRunCommand, i as FormatRegistryResolved, l as HelpRendered, m as PlanKnown, n as StageError, o as FrameworkContributionRow, p as PhaseEntered, r as FormatClaimShadowingRow, s as FrameworkModuleRow, t as PrepareError, u as ModeSignal, v as RunDecodeError, w as RunStarted, x as RunMutantTested, y as RunEvent } from "./Run.schema-
|
|
1
|
+
import { C as RunReadError, D as VerdictReached, E as SkippedReported, S as RunPhase, T as SkippedFileRow, _ as PluginsReported, a as FormatRegistryRow, b as RunFailed, c as Heartbeat, d as MutationRunPlan, f as OutputMode, g as PluginFailureReason, h as PlanMutationRunCommand, i as FormatRegistryResolved, l as HelpRendered, m as PlanKnown, n as StageError, o as FrameworkContributionRow, p as PhaseEntered, r as FormatClaimShadowingRow, s as FrameworkModuleRow, t as PrepareError, u as ModeSignal, v as RunDecodeError, w as RunStarted, x as RunMutantTested, y as RunEvent } from "./Run.schema-BaK_pxuK.mjs";
|
|
2
2
|
export { FormatClaimShadowingRow, FormatRegistryResolved, FormatRegistryRow, FrameworkContributionRow, FrameworkModuleRow, Heartbeat, HelpRendered, ModeSignal, MutationRunPlan, OutputMode, PhaseEntered, PlanKnown, PlanMutationRunCommand, PluginFailureReason, PluginsReported, PrepareError, RunDecodeError, RunEvent, RunFailed, RunMutantTested, RunPhase, RunReadError, RunStarted, SkippedFileRow, SkippedReported, StageError, VerdictReached };
|