@systemfsoftware/stryker-js 13.0.0 → 14.0.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 +66 -0
- package/README.md +30 -0
- package/dist/Run.schema-DErVOVSj.d.mts +24 -0
- package/dist/Run.schema-DuaneDGd.mjs +57 -0
- package/dist/RunEnvironment.service-C8nNTyKa.d.mts +2927 -0
- package/dist/config.d.mts +4 -4
- package/dist/config.mjs +1 -1
- package/dist/events.d.mts +2 -2
- package/dist/events.mjs +2 -2
- package/dist/{index-C09A80iv.d.mts → index-C5FRZ4Ni.d.mts} +1694 -3074
- package/dist/index.d.mts +622 -101
- package/dist/index.mjs +1104 -26
- package/dist/main.mjs +49090 -30399
- package/dist/merge-config-DCQE_2cC.mjs +1473 -0
- package/dist/{merge-config-X_AxYxMY.d.mts → merge-config-IXgoKiix.d.mts} +4 -4
- package/dist/promises.d.mts +3 -3
- package/dist/promises.mjs +1 -1
- package/dist/run-stages-CGUzIzPZ.mjs +20687 -0
- package/package.json +15 -14
- package/dist/Run.schema-Bj7b_FMA.mjs +0 -269
- package/dist/Run.schema-BlvpjFjJ.d.mts +0 -325
- package/dist/RunEnvironment.service-BJAsZsdn.d.mts +0 -524
- package/dist/dist-BscHZmXN.mjs +0 -8089
- package/dist/merge-config-DA_v1hGx.mjs +0 -63
- package/dist/run-stages.cell-BN__EOCk.mjs +0 -8789
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,71 @@
|
|
|
1
1
|
# @systemfsoftware/stryker-js
|
|
2
2
|
|
|
3
|
+
## 14.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- The incremental cache now reuses a verdict only when nothing that could change it has changed: the covering tests and every module they import, the run inputs (lockfile and configuration), and the mutant-set policy. Moving code or releasing a new version no longer throws the cache away. Incremental reports written by earlier versions are discarded once.
|
|
8
|
+
|
|
9
|
+
A mutant whose covering tests did not run is retried once, then reported as `RuntimeError` with reason `no covering test executed`.
|
|
10
|
+
|
|
11
|
+
The new `mutator.mutantSetPolicy` option defaults to `'default'`. Under it, mutants in logging, telemetry, timing, and configuration-default calls, redundant relational variants, and replacements identical to the original are reported as `Ignored` with a named rule instead of being run. Set `mutator.mutantSetPolicy: 'full'` to keep the previous mutant set.
|
|
12
|
+
|
|
13
|
+
### Minor Changes
|
|
14
|
+
|
|
15
|
+
- The new `annotate` command prints GitHub workflow annotations at the location of every survivor of the finished report, so a run's survivors show up on the changed lines of a pull request.
|
|
16
|
+
|
|
17
|
+
- The new `compare` command names every mutant whose status differs between a baseline report and a fresh one, leaving out the mutant ids passed with `--noise`.
|
|
18
|
+
|
|
19
|
+
- `stryker feedback <id> --useful|--not-useful [--reason <text>]` appends one `feedback` stream line for a surfaced survivor to reports/mutation/feedback.jsonl.
|
|
20
|
+
|
|
21
|
+
- The new `gate` command fails when a run leaves survivors that are missing from a committed baseline of accepted survivors, lists them with how to accept them, and `--update-baseline` rewrites the baseline from the finished report.
|
|
22
|
+
|
|
23
|
+
- `stryker mcp` serves the finished mutation report to MCP clients over stdio, with tools `list_survivors`, `show_mutant`, `rerun_mutant`, and `report_usefulness`.
|
|
24
|
+
|
|
25
|
+
- Serving the Mutation Server Protocol over stdio and sockets lets editors and agents configure, discover, and mutation-test a project through framed JSON-RPC, with one run at a time, a loopback-only default listener, and named errors for an unusable bind.
|
|
26
|
+
|
|
27
|
+
- Every run now also writes a reproducer for each mutant: a unified diff against the original source, so a verdict can be re-checked locally without hunting for which mutation produced it.
|
|
28
|
+
|
|
29
|
+
- Naming mutant ids on the run command re-runs exactly those mutants, restricting the mutated files to their ids' files with verdict reuse left on and reporting each selected mutant's status, covering tests, killing test, and reproducer command, while the trace names the new rerun span for that path.
|
|
30
|
+
|
|
31
|
+
- The new `sarif` reporter writes a SARIF 2.1.0 log beside the JSON report with one result per capped survivor, each carrying its mutant id in `partialFingerprints` so code scanning can track it.
|
|
32
|
+
|
|
33
|
+
- The new `--since <ref>` option mutates only the lines changed since the merge base with `<ref>`, and falls back to a full run when the Stryker config, a test-runner config, the package manifest, or the lockfile changed.
|
|
34
|
+
|
|
35
|
+
- The clear-text report adds a `Static mutants:` line with how many mutants are static and their share of the total mutant cost.
|
|
36
|
+
|
|
37
|
+
- The new `surfacing` option (default `{ perLine: 1, perFile: 7 }`) caps how many survivors are listed per line and per file, while every survivor still counts toward the score.
|
|
38
|
+
|
|
39
|
+
- With `--incremental`, an unchanged project now skips the initial test run; that run otherwise executes the suite twice to find flaky tests, and a verdict that depends on a flaky test, or any static mutant while a test is flaky, is re-tested instead of reused.
|
|
40
|
+
|
|
41
|
+
### Patch Changes
|
|
42
|
+
|
|
43
|
+
- With checkers configured, a mutant is sent to a test runner as soon as its own check group passes instead of waiting for earlier groups, so `mutant` events can arrive out of plan order while the final report keeps plan order.
|
|
44
|
+
|
|
45
|
+
- Incremental runs no longer hold a test runner while the checkpoint is rewritten after every mutant; the checkpoint is written in the background at most once per second, and an interrupted run still keeps every mutant it finished.
|
|
46
|
+
|
|
47
|
+
- Fixed a rare hang where a run stopped making progress while a test runner or checker worker waited for a message that had already arrived. The message now always wakes the worker waiting for it.
|
|
48
|
+
|
|
49
|
+
- Repeating an incremental run with no source change now reuses every verdict in a project that defines no ignore patterns of its own: a run's own reports are no longer treated as changed inputs, and options that cannot change a verdict no longer invalidate reuse — neither the ones that only select which mutants and tests run (a git ref scope, a single mutant id) nor reporting and logging options such as reporters, colors, thresholds, surfacing or log levels.
|
|
50
|
+
|
|
51
|
+
- A re-tested mutant now runs the test file of its previous killing test first, and mutation reports keep naming the right killing test after tests are added or reordered.
|
|
52
|
+
|
|
53
|
+
- Incremental runs now reuse verdicts written under a different `incrementalFile`, `incrementalSources`, `tempDirName` or `cleanTempDir`, so a shard can reuse the verdicts another shard recorded for a file that moved between shards.
|
|
54
|
+
|
|
55
|
+
- Changing only the version in a package manifest that tests import no longer invalidates the incremental verdicts of those tests, so releasing a package keeps its cached mutation results.
|
|
56
|
+
|
|
57
|
+
## 13.1.0
|
|
58
|
+
|
|
59
|
+
### Minor Changes
|
|
60
|
+
|
|
61
|
+
- The `stryker` CLI now continues a caller's trace: when `TRACEPARENT` (and optionally `TRACESTATE`) is set in its environment, the `stryker.cli.run` span and everything beneath it join that trace as a child of the carried span, following the OpenTelemetry environment-carrier specification. An absent or malformed `TRACEPARENT` leaves the run on its own root trace, as before.
|
|
62
|
+
|
|
63
|
+
### Patch Changes
|
|
64
|
+
|
|
65
|
+
- The packages now depend on `@systemfsoftware/effect-cell-types` 11.
|
|
66
|
+
|
|
67
|
+
- Every tagged error now has a one-line message built from its fields, so a failure names the file, mutant, plugin, worker or exit code involved instead of an empty message. The errors' tags, fields and encoded forms are unchanged.
|
|
68
|
+
|
|
3
69
|
## 13.0.0
|
|
4
70
|
|
|
5
71
|
### Major Changes
|
package/README.md
CHANGED
|
@@ -144,6 +144,12 @@ pnpm exec stryker run [options]
|
|
|
144
144
|
# Mutate specific files only
|
|
145
145
|
pnpm exec stryker run --mutate "src/auth/*.ts"
|
|
146
146
|
|
|
147
|
+
# Scope the run to lines changed since a git ref
|
|
148
|
+
pnpm exec stryker run --since origin/main
|
|
149
|
+
|
|
150
|
+
# Re-run named mutants from the previous report
|
|
151
|
+
pnpm exec stryker run --mutant <id,...>
|
|
152
|
+
|
|
147
153
|
# Re-test only surviving mutants from prior run
|
|
148
154
|
pnpm exec stryker run --survivors
|
|
149
155
|
|
|
@@ -155,8 +161,24 @@ pnpm exec stryker run --concurrency 4
|
|
|
155
161
|
|
|
156
162
|
# Merge partial mutation reports from parallel CI shards
|
|
157
163
|
pnpm exec stryker merge-reports --parts reports/shards --out reports/mutation
|
|
164
|
+
|
|
165
|
+
# Fail on survivors absent from a committed baseline
|
|
166
|
+
pnpm exec stryker gate --baseline .stryker-baseline.json
|
|
167
|
+
|
|
168
|
+
# Name every mutant whose status differs between two reports
|
|
169
|
+
pnpm exec stryker compare --baseline reports/mutation-report.json --fresh reports/fresh.json
|
|
170
|
+
|
|
171
|
+
# Annotate a pull request at each surfaced survivor
|
|
172
|
+
pnpm exec stryker annotate --baseline .stryker-baseline.json
|
|
173
|
+
|
|
174
|
+
# Judge one surfaced survivor, or drive runs from an editor or an agent
|
|
175
|
+
pnpm exec stryker feedback <id> --not-useful --reason "logging only"
|
|
176
|
+
pnpm exec stryker serve stdio
|
|
177
|
+
pnpm exec stryker mcp
|
|
158
178
|
```
|
|
159
179
|
|
|
180
|
+
`stryker run --since <ref>` takes the merge base of `<ref>` and the working tree, diffs it at `--unified=0`, and intersects the changed lines with `mutate`; it falls back to a full run when the Stryker config, a test-runner config, `package.json`, or the lockfile changed. `stryker run --mutant <id,...>` admits each id against the previous report (`reports/mutation/mutation.json`), restricts the run to those mutants' files, and emits each one's status, covering tests, killing test, and a `stryker run --mutant <id>` reproducer. `stryker gate` exits non-zero on survivors missing from its baseline, `stryker compare` exits `1` on a status mismatch after subtracting a `--noise` file, and `stryker annotate` prints GitHub workflow commands at each surfaced survivor. `stryker serve stdio|socket` speaks the Mutation Server Protocol and `stryker mcp` serves MCP over stdio.
|
|
181
|
+
|
|
160
182
|
## Output Modes
|
|
161
183
|
|
|
162
184
|
Human output is the default, whether or not `stdout` is a terminal. A machine consumer opts into the NDJSON event stream explicitly:
|
|
@@ -168,6 +190,14 @@ STRYKER_MODE=machine pnpm exec stryker run # the same, named by environment
|
|
|
168
190
|
|
|
169
191
|
`--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
192
|
|
|
193
|
+
## Reporters, Sidecars, and Verdict Reuse
|
|
194
|
+
|
|
195
|
+
`reporters` defaults to `['clear-text', 'progress', 'html']`. Add `sarif` to also write `reports/mutation/mutation.sarif` (SARIF 2.1.0, named from `jsonReporter.fileName`): each survivor is a `warning` result, each no-coverage mutant a `note`, the fingerprint is the mutant's content id, and the log is capped at 5,000 results. Every run writes `reports/mutation/reproducers.json`: one entry per mutant in the report, holding its mutated-lines diff and the `stryker run --mutant <id>` command that reproduces it.
|
|
196
|
+
|
|
197
|
+
The incremental cache is keyed by content: a mutant's id, the import-closure digest of its covering tests, the run inputs, the verdict-semantics version, and the mutant-set policy. Nothing in the key names a shard, branch, report path, or machine, so verdicts from different runs union and are reused wherever their inputs match. `incrementalSources` accepts globs of further incremental reports to union beside `incrementalFile`, which is how a sharded CI workspace reuses the reports it restored from other shards. Each run's stream carries a `reuse` line with the reused, ran, and per-reason refused counts, and an unchanged project reuses its persisted initial test run instead of repeating it.
|
|
198
|
+
|
|
199
|
+
`mutator.mutantSetPolicy` defaults to `'default'`, which suppresses the mutants a rule proves redundant — a relational replacement outside the sufficient set, a conditional that collapses to a literal, a replacement equal to the original code, or a duplicate already planted at the site — and records the rule id in the mutant's report entry. Set `mutator: { mutantSetPolicy: 'full' }` to keep every variant. `surfacing` (`{ perLine: 1, perFile: 7 }`) caps how many survivors reach the review surfaces and SARIF, without changing what the engine computes.
|
|
200
|
+
|
|
171
201
|
## Programmatic API
|
|
172
202
|
|
|
173
203
|
### Effect 4 Native Interface
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { a as mod_d_exports$6 } from "./index-C5FRZ4Ni.mjs";
|
|
2
|
+
import * as S from "effect/Schema";
|
|
3
|
+
//#region src/Run.schema.d.ts
|
|
4
|
+
declare const TypeId: '~stryker/mutation-run/StageError';
|
|
5
|
+
declare const StageError_base: S.Class<StageError, S.TaggedStruct<"StageError", {
|
|
6
|
+
readonly stage: S.Literals<readonly ["prepare", "instrument", "dryRun", "dryRunNoTests", "mutationTest"]>;
|
|
7
|
+
readonly reason: S.String;
|
|
8
|
+
readonly cause: S.optional<S.Defect>;
|
|
9
|
+
readonly command: S.optional<S.String>;
|
|
10
|
+
}>, import("effect/Cause").YieldableError>;
|
|
11
|
+
declare class StageError extends StageError_base {
|
|
12
|
+
readonly [TypeId]: "~stryker/mutation-run/StageError";
|
|
13
|
+
get exitClass(): mod_d_exports$6.ExitClass;
|
|
14
|
+
get message(): string;
|
|
15
|
+
}
|
|
16
|
+
declare const PrepareError_base: S.Class<PrepareError, S.TaggedStruct<"PrepareError", {
|
|
17
|
+
readonly stage: S.Literal<"prepare">;
|
|
18
|
+
readonly reason: S.String;
|
|
19
|
+
}>, import("effect/Cause").YieldableError>;
|
|
20
|
+
declare class PrepareError extends PrepareError_base {
|
|
21
|
+
get message(): string;
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
24
|
+
export { StageError as n, PrepareError as t };
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import * as S from "effect/Schema";
|
|
2
|
+
import * as Match from "effect/Match";
|
|
3
|
+
//#region src/Run.schema.ts
|
|
4
|
+
const TypeId = "~stryker/mutation-run/StageError";
|
|
5
|
+
var StageError = class extends S.TaggedError(TypeId)("StageError", {
|
|
6
|
+
stage: S.Literals([
|
|
7
|
+
"prepare",
|
|
8
|
+
"instrument",
|
|
9
|
+
"dryRun",
|
|
10
|
+
"dryRunNoTests",
|
|
11
|
+
"mutationTest"
|
|
12
|
+
]),
|
|
13
|
+
reason: S.String,
|
|
14
|
+
cause: S.optional(S.Defect()),
|
|
15
|
+
command: S.optional(S.String)
|
|
16
|
+
}) {
|
|
17
|
+
[TypeId] = TypeId;
|
|
18
|
+
get exitClass() {
|
|
19
|
+
return STAGE_PRESENTATION[this.stage].exitClass;
|
|
20
|
+
}
|
|
21
|
+
get message() {
|
|
22
|
+
const failure = `${STAGE_PRESENTATION[this.stage].label} failed: ${this.reason}`;
|
|
23
|
+
return Match.value(this.command).pipe(Match.when(Match.nonEmptyString, (present) => `${failure} (command: ${present})`), Match.orElse(() => failure));
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
const STAGE_PRESENTATION = {
|
|
27
|
+
prepare: {
|
|
28
|
+
label: "Prepare",
|
|
29
|
+
exitClass: "ConfigError"
|
|
30
|
+
},
|
|
31
|
+
instrument: {
|
|
32
|
+
label: "Instrument",
|
|
33
|
+
exitClass: "RuntimeError"
|
|
34
|
+
},
|
|
35
|
+
dryRun: {
|
|
36
|
+
label: "Dry run",
|
|
37
|
+
exitClass: "RuntimeError"
|
|
38
|
+
},
|
|
39
|
+
dryRunNoTests: {
|
|
40
|
+
label: "Dry run",
|
|
41
|
+
exitClass: "ConfigError"
|
|
42
|
+
},
|
|
43
|
+
mutationTest: {
|
|
44
|
+
label: "Mutation testing",
|
|
45
|
+
exitClass: "RuntimeError"
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
var PrepareError = class extends S.TaggedError()("PrepareError", {
|
|
49
|
+
stage: S.Literal("prepare"),
|
|
50
|
+
reason: S.String
|
|
51
|
+
}) {
|
|
52
|
+
get message() {
|
|
53
|
+
return this.reason;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
//#endregion
|
|
57
|
+
export { StageError as n, PrepareError as t };
|