testing-conventions 0.0.44 → 0.0.46
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/dist/bin/index.js +32 -0
- package/dist/bin/index.js.map +1 -0
- package/dist/mutation/main.d.ts +1 -0
- package/dist/mutation/main.js +10 -0
- package/dist/mutation/main.js.map +1 -0
- package/dist/mutation/mutation-cli.d.ts +10 -0
- package/dist/mutation/mutation-cli.js +24 -0
- package/dist/mutation/mutation-cli.js.map +1 -0
- package/dist/mutation/normalize-status.d.ts +9 -0
- package/dist/mutation/normalize-status.js +25 -0
- package/dist/mutation/normalize-status.js.map +1 -0
- package/dist/mutation/parse-args.d.ts +14 -0
- package/dist/mutation/parse-args.js +26 -0
- package/dist/mutation/parse-args.js.map +1 -0
- package/dist/mutation/run-stryker.d.ts +18 -0
- package/dist/mutation/run-stryker.js +32 -0
- package/dist/mutation/run-stryker.js.map +1 -0
- package/dist/mutation/to-normalized.d.ts +28 -0
- package/dist/mutation/to-normalized.js +27 -0
- package/dist/mutation/to-normalized.js.map +1 -0
- package/package.json +8 -7
- package/dist/bin.js +0 -21
- package/dist/bin.js.map +0 -1
- /package/dist/{bin.d.ts → bin/index.d.ts} +0 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
import { main } from 'bin-shim';
|
|
4
|
+
// The TypeScript `unit mutation` arm runs Stryker through the bundled Node adapter (#246): the
|
|
5
|
+
// rust binary spawns `node` on it, but a Rust binary can't reliably locate a JS file in the npm
|
|
6
|
+
// tree. The Node launcher — which knows its own `dist/` — hands the binary the adapter's path as
|
|
7
|
+
// an explicit `--ts-mutation-adapter` CLI argument, appended only to a `unit mutation` invocation
|
|
8
|
+
// (the only command that reads it). The binary errors clearly if the arm runs without it.
|
|
9
|
+
const args = process.argv.slice(2);
|
|
10
|
+
const isUnitMutation = args[0] === 'unit' && args[1] === 'mutation';
|
|
11
|
+
const adapter = fileURLToPath(new URL('../mutation/main.js', import.meta.url));
|
|
12
|
+
const argv = isUnitMutation ? [...args, '--ts-mutation-adapter', adapter] : args;
|
|
13
|
+
main({
|
|
14
|
+
scope: 'testing-conventions',
|
|
15
|
+
binaryName: 'testing-conventions',
|
|
16
|
+
from: import.meta.url,
|
|
17
|
+
argv,
|
|
18
|
+
platformPackage: '@{scope}/{triple}',
|
|
19
|
+
triples: {
|
|
20
|
+
'linux-x64': 'x86_64-unknown-linux-gnu',
|
|
21
|
+
'linux-arm64': 'aarch64-unknown-linux-gnu',
|
|
22
|
+
'darwin-x64': 'x86_64-apple-darwin',
|
|
23
|
+
'darwin-arm64': 'aarch64-apple-darwin',
|
|
24
|
+
'win32-x64': 'x86_64-pc-windows-msvc',
|
|
25
|
+
},
|
|
26
|
+
})
|
|
27
|
+
.then((code) => process.exit(code))
|
|
28
|
+
.catch((err) => {
|
|
29
|
+
process.stderr.write(`${err.message}\n`);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
});
|
|
32
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/bin/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAEhC,+FAA+F;AAC/F,gGAAgG;AAChG,iGAAiG;AACjG,kGAAkG;AAClG,0FAA0F;AAC1F,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACnC,MAAM,cAAc,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC;AACpE,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,qBAAqB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC/E,MAAM,IAAI,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,EAAE,uBAAuB,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAEjF,IAAI,CAAC;IACH,KAAK,EAAE,qBAAqB;IAC5B,UAAU,EAAE,qBAAqB;IACjC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG;IACrB,IAAI;IACJ,eAAe,EAAE,mBAAmB;IACpC,OAAO,EAAE;QACP,WAAW,EAAE,0BAA0B;QACvC,aAAa,EAAE,2BAA2B;QAC1C,YAAY,EAAE,qBAAqB;QACnC,cAAc,EAAE,sBAAsB;QACtC,WAAW,EAAE,wBAAwB;KACtC;CACF,CAAC;KACC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;KAClC,KAAK,CAAC,CAAC,GAAU,EAAE,EAAE;IACpB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC;IACzC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { mutationCLI } from './mutation-cli.js';
|
|
2
|
+
// The executable the rust binary spawns for the TS mutation arm (#246): `dist/mutation/main.js`
|
|
3
|
+
// runs `mutationCLI` over the process arguments and maps a failed run onto a non-zero exit code.
|
|
4
|
+
// Kept separate from `mutation-cli.ts` so the orchestration stays a pure, importable function with
|
|
5
|
+
// no process side effects (and each stays fully covered).
|
|
6
|
+
mutationCLI(process.argv.slice(2)).catch((err) => {
|
|
7
|
+
process.stderr.write(`${err.message}\n`);
|
|
8
|
+
process.exitCode = 1;
|
|
9
|
+
});
|
|
10
|
+
//# sourceMappingURL=main.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/mutation/main.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,gGAAgG;AAChG,iGAAiG;AACjG,mGAAmG;AACnG,0DAA0D;AAC1D,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAU,EAAE,EAAE;IACtD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC;IACzC,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The TypeScript mutation adapter (#239 / #246). The rust binary spawns the built executable
|
|
3
|
+
* (`main.ts` → `dist/mutation/main.js`) on the TS arm — its path comes from the launcher's
|
|
4
|
+
* `--ts-mutation-adapter` argument, so the binary never hunts the filesystem for it. This runs
|
|
5
|
+
* Stryker through the Node API and emits the normalized results as JSON. `--out <path>` writes
|
|
6
|
+
* them to a file (the rule passes a temp file, so Stryker's own stdout logging can't corrupt
|
|
7
|
+
* them); without it, the JSON goes to stdout. `--mutate <a,b,...>` scopes the run to those Stryker
|
|
8
|
+
* mutate patterns. Rejects on a failed run; `main.ts` maps that onto a non-zero exit code.
|
|
9
|
+
*/
|
|
10
|
+
export declare function mutationCLI(argv: string[]): Promise<void>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { writeFile } from 'node:fs/promises';
|
|
2
|
+
import { parseArgs } from './parse-args.js';
|
|
3
|
+
import { runStryker } from './run-stryker.js';
|
|
4
|
+
/**
|
|
5
|
+
* The TypeScript mutation adapter (#239 / #246). The rust binary spawns the built executable
|
|
6
|
+
* (`main.ts` → `dist/mutation/main.js`) on the TS arm — its path comes from the launcher's
|
|
7
|
+
* `--ts-mutation-adapter` argument, so the binary never hunts the filesystem for it. This runs
|
|
8
|
+
* Stryker through the Node API and emits the normalized results as JSON. `--out <path>` writes
|
|
9
|
+
* them to a file (the rule passes a temp file, so Stryker's own stdout logging can't corrupt
|
|
10
|
+
* them); without it, the JSON goes to stdout. `--mutate <a,b,...>` scopes the run to those Stryker
|
|
11
|
+
* mutate patterns. Rejects on a failed run; `main.ts` maps that onto a non-zero exit code.
|
|
12
|
+
*/
|
|
13
|
+
export async function mutationCLI(argv) {
|
|
14
|
+
const { mutate, out } = parseArgs(argv);
|
|
15
|
+
const results = await runStryker(mutate === undefined ? {} : { mutate });
|
|
16
|
+
const json = `${JSON.stringify(results)}\n`;
|
|
17
|
+
if (out === undefined) {
|
|
18
|
+
process.stdout.write(json);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
await writeFile(out, json);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=mutation-cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mutation-cli.js","sourceRoot":"","sources":["../../src/mutation/mutation-cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAAc;IAC9C,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IACxC,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;IACzE,MAAM,IAAI,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC;IAC5C,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACtB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;SAAM,CAAC;QACN,MAAM,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC7B,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { MutantStatus } from '@stryker-mutator/api/core';
|
|
2
|
+
/** The normalized status vocabulary shared with the Rust core (`snake_case` on the wire). */
|
|
3
|
+
export type NormalizedStatus = 'survived' | 'killed' | 'no_coverage' | 'timeout' | 'compile_error' | 'runtime_error';
|
|
4
|
+
/**
|
|
5
|
+
* Map a Stryker `MutantStatus` onto the normalized vocabulary, or `null` for the two
|
|
6
|
+
* non-outcomes the gate doesn't model: `Ignored` (excluded by config) and `Pending` (never
|
|
7
|
+
* ran). Every other Stryker status has a 1:1 normalized counterpart.
|
|
8
|
+
*/
|
|
9
|
+
export declare function normalizeStatus(status: MutantStatus): NormalizedStatus | null;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Map a Stryker `MutantStatus` onto the normalized vocabulary, or `null` for the two
|
|
3
|
+
* non-outcomes the gate doesn't model: `Ignored` (excluded by config) and `Pending` (never
|
|
4
|
+
* ran). Every other Stryker status has a 1:1 normalized counterpart.
|
|
5
|
+
*/
|
|
6
|
+
export function normalizeStatus(status) {
|
|
7
|
+
switch (status) {
|
|
8
|
+
case 'Survived':
|
|
9
|
+
return 'survived';
|
|
10
|
+
case 'Killed':
|
|
11
|
+
return 'killed';
|
|
12
|
+
case 'NoCoverage':
|
|
13
|
+
return 'no_coverage';
|
|
14
|
+
case 'Timeout':
|
|
15
|
+
return 'timeout';
|
|
16
|
+
case 'CompileError':
|
|
17
|
+
return 'compile_error';
|
|
18
|
+
case 'RuntimeError':
|
|
19
|
+
return 'runtime_error';
|
|
20
|
+
case 'Ignored':
|
|
21
|
+
case 'Pending':
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=normalize-status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize-status.js","sourceRoot":"","sources":["../../src/mutation/normalize-status.ts"],"names":[],"mappings":"AAWA;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,MAAoB;IAClD,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,UAAU;YACb,OAAO,UAAU,CAAC;QACpB,KAAK,QAAQ;YACX,OAAO,QAAQ,CAAC;QAClB,KAAK,YAAY;YACf,OAAO,aAAa,CAAC;QACvB,KAAK,SAAS;YACZ,OAAO,SAAS,CAAC;QACnB,KAAK,cAAc;YACjB,OAAO,eAAe,CAAC;QACzB,KAAK,cAAc;YACjB,OAAO,eAAe,CAAC;QACzB,KAAK,SAAS,CAAC;QACf,KAAK,SAAS;YACZ,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** The CLI arguments the TypeScript mutation adapter understands. */
|
|
2
|
+
export interface AdapterArgs {
|
|
3
|
+
/** Stryker `mutate` patterns (`--mutate a,b,...`), or `undefined` for the default set. */
|
|
4
|
+
mutate?: string[];
|
|
5
|
+
/** File to write the normalized-results JSON to (`--out <path>`); stdout when absent. */
|
|
6
|
+
out?: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Parse the adapter's CLI arguments with Node's built-in `util.parseArgs`: `--out <path>` (where
|
|
10
|
+
* to write the normalized JSON — the rule passes a temp file so Stryker's own stdout logging can't
|
|
11
|
+
* corrupt the results) and `--mutate <a,b,...>` (Stryker mutate patterns, comma-split into a list).
|
|
12
|
+
* Both are optional; the rust binary supplies the argv, so it stays a fixed, controlled shape.
|
|
13
|
+
*/
|
|
14
|
+
export declare function parseArgs(argv: string[]): AdapterArgs;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { parseArgs as parseNodeArgs } from 'node:util';
|
|
2
|
+
/**
|
|
3
|
+
* Parse the adapter's CLI arguments with Node's built-in `util.parseArgs`: `--out <path>` (where
|
|
4
|
+
* to write the normalized JSON — the rule passes a temp file so Stryker's own stdout logging can't
|
|
5
|
+
* corrupt the results) and `--mutate <a,b,...>` (Stryker mutate patterns, comma-split into a list).
|
|
6
|
+
* Both are optional; the rust binary supplies the argv, so it stays a fixed, controlled shape.
|
|
7
|
+
*/
|
|
8
|
+
export function parseArgs(argv) {
|
|
9
|
+
const { values } = parseNodeArgs({
|
|
10
|
+
args: argv,
|
|
11
|
+
options: {
|
|
12
|
+
mutate: { type: 'string' },
|
|
13
|
+
out: { type: 'string' },
|
|
14
|
+
},
|
|
15
|
+
allowPositionals: true,
|
|
16
|
+
});
|
|
17
|
+
const result = {};
|
|
18
|
+
if (values.mutate !== undefined) {
|
|
19
|
+
result.mutate = values.mutate.split(',');
|
|
20
|
+
}
|
|
21
|
+
if (values.out !== undefined) {
|
|
22
|
+
result.out = values.out;
|
|
23
|
+
}
|
|
24
|
+
return result;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=parse-args.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-args.js","sourceRoot":"","sources":["../../src/mutation/parse-args.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,IAAI,aAAa,EAAE,MAAM,WAAW,CAAC;AAUvD;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CAAC,IAAc;IACtC,MAAM,EAAE,MAAM,EAAE,GAAG,aAAa,CAAC;QAC/B,IAAI,EAAE,IAAI;QACV,OAAO,EAAE;YACP,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YAC1B,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;SACxB;QACD,gBAAgB,EAAE,IAAI;KACvB,CAAC,CAAC;IAEH,MAAM,MAAM,GAAgB,EAAE,CAAC;IAC/B,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAChC,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3C,CAAC;IACD,IAAI,MAAM,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;QAC7B,MAAM,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC;IAC1B,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type NormalizedMutant } from './to-normalized.js';
|
|
2
|
+
/** Options for {@link runStryker}. */
|
|
3
|
+
export interface RunStrykerOptions {
|
|
4
|
+
/**
|
|
5
|
+
* Stryker `mutate` patterns to scope the run to (e.g. `<file>:<start>-<end>` ranges for a
|
|
6
|
+
* diff-scoped gate). Omitted ⇒ Stryker's configured/default `mutate` set.
|
|
7
|
+
*/
|
|
8
|
+
mutate?: string[];
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Run Stryker over the project in the current working directory via its Node API (#239) and
|
|
12
|
+
* return the normalized results. Selects the **bundled** vitest runner explicitly by path (so
|
|
13
|
+
* the unit-scoped runner is always used rather than Stryker's default `npm test` command
|
|
14
|
+
* runner, #240, and resolves regardless of the project's location); results come from
|
|
15
|
+
* `runMutationTest()` directly, so there is no report file. Because this runs inside the npm
|
|
16
|
+
* package, `@stryker-mutator/core` resolves natively.
|
|
17
|
+
*/
|
|
18
|
+
export declare function runStryker(options?: RunStrykerOptions): Promise<NormalizedMutant[]>;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
2
|
+
import { Stryker } from '@stryker-mutator/core';
|
|
3
|
+
import { toNormalized } from './to-normalized.js';
|
|
4
|
+
// The bundled vitest runner plugin's absolute path. Stryker discovers plugins relative to the
|
|
5
|
+
// *project* under test, not to where it was imported from — so when the rule runs the engine
|
|
6
|
+
// over a consumer project, our bundled `@stryker-mutator/vitest-runner` isn't on that search
|
|
7
|
+
// path. Passing its resolved path as an explicit plugin makes Stryker load our copy regardless
|
|
8
|
+
// of the project's location (#246). `vitest` itself stays the consumer's (the runner's peer).
|
|
9
|
+
const vitestRunnerPlugin = createRequire(import.meta.url).resolve('@stryker-mutator/vitest-runner');
|
|
10
|
+
/**
|
|
11
|
+
* Run Stryker over the project in the current working directory via its Node API (#239) and
|
|
12
|
+
* return the normalized results. Selects the **bundled** vitest runner explicitly by path (so
|
|
13
|
+
* the unit-scoped runner is always used rather than Stryker's default `npm test` command
|
|
14
|
+
* runner, #240, and resolves regardless of the project's location); results come from
|
|
15
|
+
* `runMutationTest()` directly, so there is no report file. Because this runs inside the npm
|
|
16
|
+
* package, `@stryker-mutator/core` resolves natively.
|
|
17
|
+
*/
|
|
18
|
+
export async function runStryker(options = {}) {
|
|
19
|
+
const cliOptions = {
|
|
20
|
+
testRunner: 'vitest',
|
|
21
|
+
plugins: [vitestRunnerPlugin],
|
|
22
|
+
// Results come from runMutationTest()'s return value, so no file/stdout reporter is needed.
|
|
23
|
+
reporters: [],
|
|
24
|
+
...(options.mutate ? { mutate: options.mutate } : {}),
|
|
25
|
+
};
|
|
26
|
+
const results = await new Stryker(cliOptions).runMutationTest();
|
|
27
|
+
const projectRoot = process.cwd();
|
|
28
|
+
return results
|
|
29
|
+
.map((result) => toNormalized(result, projectRoot))
|
|
30
|
+
.filter((mutant) => mutant !== null);
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=run-stryker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-stryker.js","sourceRoot":"","sources":["../../src/mutation/run-stryker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAGhD,OAAO,EAAE,YAAY,EAAyB,MAAM,oBAAoB,CAAC;AAWzE,8FAA8F;AAC9F,6FAA6F;AAC7F,6FAA6F;AAC7F,+FAA+F;AAC/F,8FAA8F;AAC9F,MAAM,kBAAkB,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,gCAAgC,CAAC,CAAC;AAEpG;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,UAA6B,EAAE;IAC9D,MAAM,UAAU,GAA0B;QACxC,UAAU,EAAE,QAAQ;QACpB,OAAO,EAAE,CAAC,kBAAkB,CAAC;QAC7B,4FAA4F;QAC5F,SAAS,EAAE,EAAE;QACb,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACtD,CAAC;IACF,MAAM,OAAO,GAAG,MAAM,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC,eAAe,EAAE,CAAC;IAChE,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAClC,OAAO,OAAO;SACX,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;SAClD,MAAM,CAAC,CAAC,MAAM,EAA8B,EAAE,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC;AACrE,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { MutantResult } from '@stryker-mutator/api/core';
|
|
2
|
+
import { type NormalizedStatus } from './normalize-status.js';
|
|
3
|
+
/**
|
|
4
|
+
* One mutant in the normalized result set — the engine-agnostic shape the Rust core reads
|
|
5
|
+
* (`mutation::NormalizedMutant`). The adapter emits an array of these so the core never sees
|
|
6
|
+
* a Stryker-specific report.
|
|
7
|
+
*/
|
|
8
|
+
export interface NormalizedMutant {
|
|
9
|
+
/** Project-relative, `/`-separated path of the mutated file. */
|
|
10
|
+
file: string;
|
|
11
|
+
/** 1-based line the mutant starts on. */
|
|
12
|
+
line: number;
|
|
13
|
+
/** The outcome, normalized across engines. */
|
|
14
|
+
status: NormalizedStatus;
|
|
15
|
+
/** Stryker's mutator name (e.g. `ConditionalExpression`). */
|
|
16
|
+
mutator: string;
|
|
17
|
+
/** The replacement text, when Stryker reports one. */
|
|
18
|
+
replacement?: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Map one Stryker `MutantResult` to a {@link NormalizedMutant}, or `null` when its status is
|
|
22
|
+
* one the gate ignores (see {@link normalizeStatus}).
|
|
23
|
+
*
|
|
24
|
+
* Stryker reports `fileName` as an absolute path, but the gate keys on project-relative,
|
|
25
|
+
* `/`-separated paths (so exemptions and the `--base` diff match), so it's made relative to
|
|
26
|
+
* `projectRoot` and separators are normalized.
|
|
27
|
+
*/
|
|
28
|
+
export declare function toNormalized(result: MutantResult, projectRoot: string): NormalizedMutant | null;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { isAbsolute, relative, sep } from 'node:path';
|
|
2
|
+
import { normalizeStatus } from './normalize-status.js';
|
|
3
|
+
/**
|
|
4
|
+
* Map one Stryker `MutantResult` to a {@link NormalizedMutant}, or `null` when its status is
|
|
5
|
+
* one the gate ignores (see {@link normalizeStatus}).
|
|
6
|
+
*
|
|
7
|
+
* Stryker reports `fileName` as an absolute path, but the gate keys on project-relative,
|
|
8
|
+
* `/`-separated paths (so exemptions and the `--base` diff match), so it's made relative to
|
|
9
|
+
* `projectRoot` and separators are normalized.
|
|
10
|
+
*/
|
|
11
|
+
export function toNormalized(result, projectRoot) {
|
|
12
|
+
const status = normalizeStatus(result.status);
|
|
13
|
+
if (status === null) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
const file = (isAbsolute(result.fileName) ? relative(projectRoot, result.fileName) : result.fileName)
|
|
17
|
+
.split(sep)
|
|
18
|
+
.join('/');
|
|
19
|
+
return {
|
|
20
|
+
file,
|
|
21
|
+
line: result.location.start.line,
|
|
22
|
+
status,
|
|
23
|
+
mutator: result.mutatorName,
|
|
24
|
+
...(result.replacement === undefined ? {} : { replacement: result.replacement }),
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=to-normalized.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"to-normalized.js","sourceRoot":"","sources":["../../src/mutation/to-normalized.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAGtD,OAAO,EAAE,eAAe,EAAyB,MAAM,uBAAuB,CAAC;AAoB/E;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,MAAoB,EAAE,WAAmB;IACpE,MAAM,MAAM,GAAG,eAAe,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC9C,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACpB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC;SAClG,KAAK,CAAC,GAAG,CAAC;SACV,IAAI,CAAC,GAAG,CAAC,CAAC;IACb,OAAO;QACL,IAAI;QACJ,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI;QAChC,MAAM;QACN,OAAO,EAAE,MAAM,CAAC,WAAW;QAC3B,GAAG,CAAC,MAAM,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC;KACjF,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "testing-conventions",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.46",
|
|
4
4
|
"description": "Enforce testing conventions in libraries (Python, TypeScript, and Rust).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": "https://github.com/thekevinscott/testing-conventions",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"bin": {
|
|
9
|
-
"testing-conventions": "dist/bin.js"
|
|
9
|
+
"testing-conventions": "dist/bin/index.js"
|
|
10
10
|
},
|
|
11
11
|
"exports": {
|
|
12
12
|
".": {
|
|
@@ -43,13 +43,14 @@
|
|
|
43
43
|
}
|
|
44
44
|
},
|
|
45
45
|
"optionalDependencies": {
|
|
46
|
-
"@testing-conventions/x86_64-unknown-linux-gnu": "0.0.
|
|
47
|
-
"@testing-conventions/aarch64-unknown-linux-gnu": "0.0.
|
|
48
|
-
"@testing-conventions/x86_64-apple-darwin": "0.0.
|
|
49
|
-
"@testing-conventions/aarch64-apple-darwin": "0.0.
|
|
50
|
-
"@testing-conventions/x86_64-pc-windows-msvc": "0.0.
|
|
46
|
+
"@testing-conventions/x86_64-unknown-linux-gnu": "0.0.46",
|
|
47
|
+
"@testing-conventions/aarch64-unknown-linux-gnu": "0.0.46",
|
|
48
|
+
"@testing-conventions/x86_64-apple-darwin": "0.0.46",
|
|
49
|
+
"@testing-conventions/aarch64-apple-darwin": "0.0.46",
|
|
50
|
+
"@testing-conventions/x86_64-pc-windows-msvc": "0.0.46"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
|
+
"@stryker-mutator/api": "^9.6.0",
|
|
53
54
|
"@types/node": "^22.9.0",
|
|
54
55
|
"@typescript-eslint/eslint-plugin": "^8.15.0",
|
|
55
56
|
"@typescript-eslint/parser": "^8.15.0",
|
package/dist/bin.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { main } from 'bin-shim';
|
|
3
|
-
main({
|
|
4
|
-
scope: 'testing-conventions',
|
|
5
|
-
binaryName: 'testing-conventions',
|
|
6
|
-
from: import.meta.url,
|
|
7
|
-
platformPackage: '@{scope}/{triple}',
|
|
8
|
-
triples: {
|
|
9
|
-
'linux-x64': 'x86_64-unknown-linux-gnu',
|
|
10
|
-
'linux-arm64': 'aarch64-unknown-linux-gnu',
|
|
11
|
-
'darwin-x64': 'x86_64-apple-darwin',
|
|
12
|
-
'darwin-arm64': 'aarch64-apple-darwin',
|
|
13
|
-
'win32-x64': 'x86_64-pc-windows-msvc',
|
|
14
|
-
},
|
|
15
|
-
})
|
|
16
|
-
.then((code) => process.exit(code))
|
|
17
|
-
.catch((err) => {
|
|
18
|
-
process.stderr.write(`${err.message}\n`);
|
|
19
|
-
process.exit(1);
|
|
20
|
-
});
|
|
21
|
-
//# sourceMappingURL=bin.js.map
|
package/dist/bin.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAEhC,IAAI,CAAC;IACH,KAAK,EAAE,qBAAqB;IAC5B,UAAU,EAAE,qBAAqB;IACjC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG;IACrB,eAAe,EAAE,mBAAmB;IACpC,OAAO,EAAE;QACP,WAAW,EAAE,0BAA0B;QACvC,aAAa,EAAE,2BAA2B;QAC1C,YAAY,EAAE,qBAAqB;QACnC,cAAc,EAAE,sBAAsB;QACtC,WAAW,EAAE,wBAAwB;KACtC;CACF,CAAC;KACC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;KAClC,KAAK,CAAC,CAAC,GAAU,EAAE,EAAE;IACpB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC;IACzC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
File without changes
|