@descryy/runtime-test-runner 0.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.
Files changed (41) hide show
  1. package/dist/collector-version.d.ts +10 -0
  2. package/dist/collector-version.d.ts.map +1 -0
  3. package/dist/collector-version.js +12 -0
  4. package/dist/collector-version.js.map +1 -0
  5. package/dist/go-test.d.ts +81 -0
  6. package/dist/go-test.d.ts.map +1 -0
  7. package/dist/go-test.js +224 -0
  8. package/dist/go-test.js.map +1 -0
  9. package/dist/graph-mapping.d.ts +44 -0
  10. package/dist/graph-mapping.d.ts.map +1 -0
  11. package/dist/graph-mapping.js +72 -0
  12. package/dist/graph-mapping.js.map +1 -0
  13. package/dist/index.d.ts +10 -0
  14. package/dist/index.d.ts.map +1 -0
  15. package/dist/index.js +6 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/jest-reporter.d.ts +72 -0
  18. package/dist/jest-reporter.d.ts.map +1 -0
  19. package/dist/jest-reporter.js +110 -0
  20. package/dist/jest-reporter.js.map +1 -0
  21. package/dist/playwright-reporter.d.ts +67 -0
  22. package/dist/playwright-reporter.d.ts.map +1 -0
  23. package/dist/playwright-reporter.js +93 -0
  24. package/dist/playwright-reporter.js.map +1 -0
  25. package/dist/reporter.d.ts +35 -0
  26. package/dist/reporter.d.ts.map +1 -0
  27. package/dist/reporter.js +74 -0
  28. package/dist/reporter.js.map +1 -0
  29. package/dist/swift-xctest.d.ts +138 -0
  30. package/dist/swift-xctest.d.ts.map +1 -0
  31. package/dist/swift-xctest.js +384 -0
  32. package/dist/swift-xctest.js.map +1 -0
  33. package/dist/test-runner-collector.d.ts +370 -0
  34. package/dist/test-runner-collector.d.ts.map +1 -0
  35. package/dist/test-runner-collector.js +1014 -0
  36. package/dist/test-runner-collector.js.map +1 -0
  37. package/dist/vitest-reporter.d.ts +76 -0
  38. package/dist/vitest-reporter.d.ts.map +1 -0
  39. package/dist/vitest-reporter.js +131 -0
  40. package/dist/vitest-reporter.js.map +1 -0
  41. package/package.json +33 -0
@@ -0,0 +1,10 @@
1
+ /**
2
+ * `Evidence.collectorVersion`'s source for every collector in this package:
3
+ * this package's own `package.json` "version", read from the artifact
4
+ * itself rather than hand-duplicated into a second string that can drift
5
+ * from what actually shipped. Same idea as `nodeVersion` elsewhere in this
6
+ * repo (`process.version`, always known, never probed) applied to a
7
+ * package instead of the Node runtime.
8
+ */
9
+ export declare const COLLECTOR_VERSION: string;
10
+ //# sourceMappingURL=collector-version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collector-version.d.ts","sourceRoot":"","sources":["../src/collector-version.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,eAAO,MAAM,iBAAiB,EAAE,MAA6E,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * `Evidence.collectorVersion`'s source for every collector in this package:
3
+ * this package's own `package.json` "version", read from the artifact
4
+ * itself rather than hand-duplicated into a second string that can drift
5
+ * from what actually shipped. Same idea as `nodeVersion` elsewhere in this
6
+ * repo (`process.version`, always known, never probed) applied to a
7
+ * package instead of the Node runtime.
8
+ */
9
+ import { createRequire } from "node:module";
10
+ const require = createRequire(import.meta.url);
11
+ export const COLLECTOR_VERSION = require("../package.json").version;
12
+ //# sourceMappingURL=collector-version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collector-version.js","sourceRoot":"","sources":["../src/collector-version.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAE/C,MAAM,CAAC,MAAM,iBAAiB,GAAY,OAAO,CAAC,iBAAiB,CAAkC,CAAC,OAAO,CAAC"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * §17's Go row (`go test` — "unbuilt... `-json` is the candidate seam and
3
+ * has not been evaluated"), closed by evaluating it: `go test -json`
4
+ * streams one NDJSON line per real event as the run happens — no report
5
+ * file, no end-of-run artifact, the same streaming-first shape every other
6
+ * runner on this seam already has.
7
+ *
8
+ * ## Why this is a standalone collector, not a `PROFILES` entry
9
+ *
10
+ * Every runner in `test-runner-collector.ts`'s `PROFILES` speaks the SAME
11
+ * envelope directly — the reporter module (or, for JUnit/.NET, the listener)
12
+ * already writes `{"type": "test:start", "data": {...}}` on the wire, and
13
+ * `createTestRunnerCollector` reads it unchanged. `go test -json` writes ITS
14
+ * OWN shape (`{"Action": "run", "Package": ..., "Test": ...}`) — Go's own
15
+ * format, not a Descry envelope, and never will be one. So this needed a
16
+ * translator on the *reading* side rather than an injected reporter, and
17
+ * bolting that into the shared pipeline would have made one runner's single
18
+ * shared read-loop branch on which format it is mid-stream. A dedicated
19
+ * collector keeps that branch from existing at all.
20
+ *
21
+ * The envelope handshake/version gate (`createEnvelopeGate`) does not apply
22
+ * here either, for the same reason `ENVELOPE_VERSION`'s own comment gives
23
+ * for why the three built-in reporters do not need it: this translator is
24
+ * TypeScript, compiled by the same `tsc -b` as `createEventTranslator`, so
25
+ * it cannot drift from it without the build itself failing.
26
+ *
27
+ * ## The container problem, Go's own shape of it
28
+ *
29
+ * A table test's `t.Run("case", ...)` subtests each get their own
30
+ * `run`/`pass`/`fail` — AND the parent `TestTable` gets its own `pass`/`fail`
31
+ * too, reporting purely whether any child failed. Forwarding it would be
32
+ * the exact defect this checklist already refused for JUnit's containers and
33
+ * node:test's `describe` blocks: one child failure counted twice. Measured
34
+ * directly (not assumed): Go emits every child's own `run` while the parent
35
+ * is still open, and the parent's result always arrives last — so parentage
36
+ * is detected by name prefix (`Parent/child`) while streaming, with no
37
+ * lookahead needed. A test with children is a container: its own eventual
38
+ * pass/fail is suppressed here, never handed to the shared translator.
39
+ *
40
+ * ## No source location, and that is disclosed rather than scraped
41
+ *
42
+ * `go test -json` carries no `file`/`line` field. The only place a location
43
+ * appears is inside a captured `Output` line's own text
44
+ * (`probe_test.go:13: message`) — exactly the "scrape formatted text" this
45
+ * codebase already refuses for `cargo test`'s TAP-shaped prose. Not done
46
+ * here either: `sourceLocation` stays null, an honest gap instead of a
47
+ * guess with a filename in it that might be a helper's, not the test's own.
48
+ */
49
+ import type { Collector } from "@descryy/runtime-contracts";
50
+ import { type NodeTestEvent, type TraceCoverage } from "./test-runner-collector.ts";
51
+ /** One line of `go test -json`'s own NDJSON, undocumented as a stable format contract but stable in shape since Go 1.10. */
52
+ export interface GoTestEvent {
53
+ readonly Action: "start" | "run" | "pause" | "cont" | "bench" | "pass" | "fail" | "skip" | "output";
54
+ readonly Package?: string;
55
+ readonly Test?: string;
56
+ readonly Elapsed?: number;
57
+ readonly Output?: string;
58
+ }
59
+ export declare function isGoTestEvent(value: unknown): value is GoTestEvent;
60
+ /**
61
+ * Go-native JSON in, shared `NodeTestEvent` envelope out (or nothing, for a
62
+ * suppressed container or a package-level line with no `Test`). Holds one
63
+ * open entry per in-flight test name, keyed exactly as Go names it
64
+ * (`Parent`, `Parent/child`), so a child's `run` event can mark its parent
65
+ * as having children before the parent's own result arrives.
66
+ */
67
+ export declare function createGoEventTranslator(): {
68
+ translate(event: GoTestEvent): NodeTestEvent | null;
69
+ };
70
+ export interface GoTestCollectorOptions {
71
+ readonly command: string;
72
+ readonly cwd: string;
73
+ /** Joins emitted Evidence back to a named service, same convention as every other collector. Omit for a standalone test run with no corresponding service. */
74
+ readonly service?: string;
75
+ }
76
+ export interface GoTestCollector extends Collector {
77
+ waitForCompletion(): Promise<void>;
78
+ traceCoverage(): TraceCoverage;
79
+ }
80
+ export declare function createGoTestCollector(options: GoTestCollectorOptions): GoTestCollector;
81
+ //# sourceMappingURL=go-test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"go-test.d.ts","sourceRoot":"","sources":["../src/go-test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAiE,MAAM,4BAA4B,CAAC;AAE3H,OAAO,EAAoC,KAAK,aAAa,EAAE,KAAK,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAEtH,4HAA4H;AAC5H,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,KAAK,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAC;IACpG,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,WAAW,CAElE;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,IAAI;IAAE,SAAS,CAAC,KAAK,EAAE,WAAW,GAAG,aAAa,GAAG,IAAI,CAAA;CAAE,CAmFjG;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,8JAA8J;IAC9J,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAmBD,MAAM,WAAW,eAAgB,SAAQ,SAAS;IAChD,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,aAAa,IAAI,aAAa,CAAC;CAChC;AAOD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,sBAAsB,GAAG,eAAe,CAqEtF"}
@@ -0,0 +1,224 @@
1
+ /**
2
+ * §17's Go row (`go test` — "unbuilt... `-json` is the candidate seam and
3
+ * has not been evaluated"), closed by evaluating it: `go test -json`
4
+ * streams one NDJSON line per real event as the run happens — no report
5
+ * file, no end-of-run artifact, the same streaming-first shape every other
6
+ * runner on this seam already has.
7
+ *
8
+ * ## Why this is a standalone collector, not a `PROFILES` entry
9
+ *
10
+ * Every runner in `test-runner-collector.ts`'s `PROFILES` speaks the SAME
11
+ * envelope directly — the reporter module (or, for JUnit/.NET, the listener)
12
+ * already writes `{"type": "test:start", "data": {...}}` on the wire, and
13
+ * `createTestRunnerCollector` reads it unchanged. `go test -json` writes ITS
14
+ * OWN shape (`{"Action": "run", "Package": ..., "Test": ...}`) — Go's own
15
+ * format, not a Descry envelope, and never will be one. So this needed a
16
+ * translator on the *reading* side rather than an injected reporter, and
17
+ * bolting that into the shared pipeline would have made one runner's single
18
+ * shared read-loop branch on which format it is mid-stream. A dedicated
19
+ * collector keeps that branch from existing at all.
20
+ *
21
+ * The envelope handshake/version gate (`createEnvelopeGate`) does not apply
22
+ * here either, for the same reason `ENVELOPE_VERSION`'s own comment gives
23
+ * for why the three built-in reporters do not need it: this translator is
24
+ * TypeScript, compiled by the same `tsc -b` as `createEventTranslator`, so
25
+ * it cannot drift from it without the build itself failing.
26
+ *
27
+ * ## The container problem, Go's own shape of it
28
+ *
29
+ * A table test's `t.Run("case", ...)` subtests each get their own
30
+ * `run`/`pass`/`fail` — AND the parent `TestTable` gets its own `pass`/`fail`
31
+ * too, reporting purely whether any child failed. Forwarding it would be
32
+ * the exact defect this checklist already refused for JUnit's containers and
33
+ * node:test's `describe` blocks: one child failure counted twice. Measured
34
+ * directly (not assumed): Go emits every child's own `run` while the parent
35
+ * is still open, and the parent's result always arrives last — so parentage
36
+ * is detected by name prefix (`Parent/child`) while streaming, with no
37
+ * lookahead needed. A test with children is a container: its own eventual
38
+ * pass/fail is suppressed here, never handed to the shared translator.
39
+ *
40
+ * ## No source location, and that is disclosed rather than scraped
41
+ *
42
+ * `go test -json` carries no `file`/`line` field. The only place a location
43
+ * appears is inside a captured `Output` line's own text
44
+ * (`probe_test.go:13: message`) — exactly the "scrape formatted text" this
45
+ * codebase already refuses for `cargo test`'s TAP-shaped prose. Not done
46
+ * here either: `sourceLocation` stays null, an honest gap instead of a
47
+ * guess with a filename in it that might be a helper's, not the test's own.
48
+ */
49
+ import { spawnProcess } from "@descryy/runtime-controller";
50
+ import { createEventTranslator, pumpLines } from "./test-runner-collector.js";
51
+ export function isGoTestEvent(value) {
52
+ return typeof value === "object" && value !== null && "Action" in value;
53
+ }
54
+ /**
55
+ * Go-native JSON in, shared `NodeTestEvent` envelope out (or nothing, for a
56
+ * suppressed container or a package-level line with no `Test`). Holds one
57
+ * open entry per in-flight test name, keyed exactly as Go names it
58
+ * (`Parent`, `Parent/child`), so a child's `run` event can mark its parent
59
+ * as having children before the parent's own result arrives.
60
+ */
61
+ export function createGoEventTranslator() {
62
+ const open = new Map();
63
+ const parentOf = (name) => {
64
+ const slash = name.lastIndexOf("/");
65
+ return slash === -1 ? null : name.slice(0, slash);
66
+ };
67
+ return {
68
+ translate(event) {
69
+ const name = event.Test;
70
+ if (name === undefined)
71
+ return null; // package-level line -- no single test to attribute it to
72
+ const qualifiedName = event.Package !== undefined ? `${event.Package}.${name}` : name;
73
+ switch (event.Action) {
74
+ case "run": {
75
+ const parent = parentOf(name);
76
+ if (parent !== null) {
77
+ const entry = open.get(parent);
78
+ if (entry !== undefined)
79
+ entry.hasChildren = true;
80
+ }
81
+ open.set(name, { hasChildren: false, output: [] });
82
+ return { type: "test:start", data: { name, qualifiedName } };
83
+ }
84
+ case "output": {
85
+ open.get(name)?.output.push(event.Output ?? "");
86
+ return null;
87
+ }
88
+ case "pass":
89
+ case "fail":
90
+ case "skip": {
91
+ const entry = open.get(name);
92
+ open.delete(name);
93
+ // A container's own result is redundant with its children's, which
94
+ // were already reported individually -- forwarding it would be the
95
+ // same double-count RT-074/RT-092 refused for JUnit and node:test.
96
+ if (entry?.hasChildren === true)
97
+ return null;
98
+ if (event.Action === "skip") {
99
+ return {
100
+ type: "test:pass",
101
+ data: {
102
+ name,
103
+ qualifiedName,
104
+ skip: true,
105
+ // Go's JSON does not distinguish an unconditional `t.Skip()`
106
+ // from a conditional precondition bail -- claiming either
107
+ // would be a guess this translator refuses to make.
108
+ skipReason: "unspecified",
109
+ },
110
+ };
111
+ }
112
+ const message = (entry?.output ?? []).join("").trim();
113
+ const durationMs = event.Elapsed !== undefined ? { duration_ms: event.Elapsed * 1000 } : {};
114
+ // `error` carries no free-form `message` field in the shared
115
+ // `NodeTestEvent` type -- only `code`/`failureType`/`cause`.
116
+ // Jest's own reporter (`jest-reporter.ts`) is not held to this
117
+ // check at all: it emits raw JSON via `console.log`, never an
118
+ // object literal typed as `NodeTestEvent`, so it can and does put
119
+ // arbitrary fields under `error`. This translator constructs a
120
+ // typed literal directly, so it uses the two real, declared
121
+ // fields instead: `failureType` names the kind, `cause` (typed
122
+ // `unknown`) carries the captured Output text verbatim.
123
+ const errorField = event.Action === "fail" ? { error: { failureType: "test", cause: message } } : {};
124
+ return {
125
+ type: event.Action === "pass" ? "test:pass" : "test:fail",
126
+ data: {
127
+ name,
128
+ qualifiedName,
129
+ details: { ...durationMs, ...errorField },
130
+ },
131
+ };
132
+ }
133
+ default:
134
+ return null;
135
+ }
136
+ },
137
+ };
138
+ }
139
+ function computeCapabilities() {
140
+ const reason = "GoTestCollector observes go test events (started/passed/failed) only -- the capability model has no field for that yet.";
141
+ const status = { availability: "unavailable", reason };
142
+ return {
143
+ domObservation: status,
144
+ consoleObservation: status,
145
+ networkObservation: status,
146
+ backendLogAccess: status,
147
+ distributedTrace: status,
148
+ sourceMapping: { availability: "unavailable", reason: "go test -json carries no file/line field; not scraped from Output text" },
149
+ stackCapture: status,
150
+ processLifecycle: status,
151
+ databaseObservation: status,
152
+ externalServiceObservation: status,
153
+ };
154
+ }
155
+ /** Splits `command` on whitespace, the same minimal tokenizer discipline `discoverRunner` uses elsewhere on this seam -- no shell quoting support, by the same declared-not-inferred reasoning. */
156
+ function splitCommand(command) {
157
+ return command.trim().split(/\s+/).filter((s) => s.length > 0);
158
+ }
159
+ export function createGoTestCollector(options) {
160
+ const capabilities = computeCapabilities();
161
+ let managed = null;
162
+ let completion = Promise.resolve();
163
+ let translator = null;
164
+ return {
165
+ collectorId: "go-test-collector",
166
+ async start(ctx) {
167
+ const tokens = splitCommand(options.command);
168
+ const baseName = (tokens[0] ?? "").split(/[\\/]/).pop() ?? "";
169
+ if (baseName !== "go" && baseName !== "go.exe") {
170
+ return { available: false, reason: `"${options.command}" does not run \`go\` -- this collector only observes \`go test\`.` };
171
+ }
172
+ const testIndex = tokens.indexOf("test");
173
+ if (testIndex === -1) {
174
+ return { available: false, reason: `"${options.command}" runs \`go\` but not \`go test\` -- this collector observes the Go test runner, not the CLI's other subcommands.` };
175
+ }
176
+ if (tokens.includes("-json")) {
177
+ return { available: false, reason: "command already includes -json -- this collector needs to own the flag to translate the stream, and a caller-supplied -json with no translator reading it would report nothing." };
178
+ }
179
+ const args = [...tokens.slice(1, testIndex + 1), "-json", ...tokens.slice(testIndex + 1)];
180
+ const processId = `go-test-${Date.now()}`;
181
+ managed = spawnProcess({ processId, command: "go", args, cwd: options.cwd });
182
+ translator = createEventTranslator(ctx.emit, options.service, processId);
183
+ const activeTranslator = translator;
184
+ const goTranslator = createGoEventTranslator();
185
+ completion = pumpLines(managed, (line) => {
186
+ if (line.trim() === "")
187
+ return;
188
+ let parsed;
189
+ try {
190
+ parsed = JSON.parse(line);
191
+ }
192
+ catch {
193
+ // `go test`'s own compiler/vet diagnostics print as plain text
194
+ // ahead of the JSON stream on a build failure -- ordinary noise,
195
+ // not a parse failure of this collector's own reporter.
196
+ return;
197
+ }
198
+ if (!isGoTestEvent(parsed))
199
+ return;
200
+ const translated = goTranslator.translate(parsed);
201
+ if (translated !== null)
202
+ activeTranslator.handle(translated);
203
+ }).then(() => {
204
+ activeTranslator.flush();
205
+ });
206
+ return { available: true };
207
+ },
208
+ async stop() {
209
+ if (managed !== null)
210
+ await managed.kill();
211
+ await completion;
212
+ },
213
+ capabilities() {
214
+ return capabilities;
215
+ },
216
+ async waitForCompletion() {
217
+ await completion;
218
+ },
219
+ traceCoverage() {
220
+ return translator?.coverage() ?? { testsObserved: 0, idsPresent: 0, notRun: 0 };
221
+ },
222
+ };
223
+ }
224
+ //# sourceMappingURL=go-test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"go-test.js","sourceRoot":"","sources":["../src/go-test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * §17's "TEST_CASE graph mapping" (RT-076): resolving an observed test's
3
+ * evidence to the real `TEST_CASE` graph node graph-correlator's
4
+ * `resolveTestCaseNode` (`@descryy/runtime-graph-correlator`) already knows
5
+ * how to find.
6
+ *
7
+ * Deliberately a thin translation, not a new abstraction: every other
8
+ * collector's evidence is resolved the same way, by a caller extracting
9
+ * the relevant fields and calling the resolver directly
10
+ * (`vertical-slice`'s own tests do exactly this for `resolveSymbolNode`).
11
+ * `resolveObservedTestCase` exists only because TEST_STARTED/PASSED/FAILED
12
+ * has two names -- `payload.name` (node:test's own, unprefixed) and
13
+ * `payload.qualifiedName` (suite-prefixed, matching the graph's own
14
+ * convention) -- and using the wrong one is a silent, plausible-looking
15
+ * miss (see `test-runner-collector.ts`'s own `SuiteStack` comment). This
16
+ * function is the one place that decision is made, so it cannot be made
17
+ * wrong at each call site independently.
18
+ *
19
+ * Does not call `EvidenceStore.attribute()` itself. That needs the
20
+ * evidence's real `evidenceId`, which only exists after `store.write()`
21
+ * has returned it -- outside this collector's own reach, same as every
22
+ * other collector's `graphNodeId: null`. The caller that already holds
23
+ * both the store and the graph `driver` (the same one `vertical-slice`'s
24
+ * tests already are) attributes; this only resolves.
25
+ */
26
+ import type { SqlDriver } from "@descryy/core";
27
+ import { type TestCaseResolution } from "@descryy/runtime-graph-correlator";
28
+ import type { Evidence } from "@descryy/runtime-contracts";
29
+ export type ObservedTestCaseResolution = TestCaseResolution | {
30
+ readonly outcome: "no-location";
31
+ readonly reason: string;
32
+ };
33
+ /**
34
+ * Refuses (returns `"no-location"`, never throws) for anything that isn't
35
+ * TEST_STARTED/PASSED/FAILED evidence with a real `sourceLocation.file` --
36
+ * the same "wrong input, refuse rather than guess" shape every resolver in
37
+ * `graph-correlator` already uses for a missing `repoRoot` or an evidence
38
+ * item outside the declared repo.
39
+ */
40
+ export declare function resolveObservedTestCase(driver: SqlDriver, evidence: Pick<Evidence, "eventType" | "payload" | "sourceLocation">, repo: string, options?: {
41
+ readonly repoRoot?: string;
42
+ readonly producerScanLimit?: number;
43
+ }): ObservedTestCaseResolution;
44
+ //# sourceMappingURL=graph-mapping.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph-mapping.d.ts","sourceRoot":"","sources":["../src/graph-mapping.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAuB,KAAK,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AACjG,OAAO,KAAK,EAAE,QAAQ,EAAoB,MAAM,4BAA4B,CAAC;AAmB7E,MAAM,MAAM,0BAA0B,GAClC,kBAAkB,GAClB;IAAE,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjE;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,SAAS,EACjB,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,WAAW,GAAG,SAAS,GAAG,gBAAgB,CAAC,EACpE,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE;IAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAAO,GAChF,0BAA0B,CA2B5B"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * §17's "TEST_CASE graph mapping" (RT-076): resolving an observed test's
3
+ * evidence to the real `TEST_CASE` graph node graph-correlator's
4
+ * `resolveTestCaseNode` (`@descryy/runtime-graph-correlator`) already knows
5
+ * how to find.
6
+ *
7
+ * Deliberately a thin translation, not a new abstraction: every other
8
+ * collector's evidence is resolved the same way, by a caller extracting
9
+ * the relevant fields and calling the resolver directly
10
+ * (`vertical-slice`'s own tests do exactly this for `resolveSymbolNode`).
11
+ * `resolveObservedTestCase` exists only because TEST_STARTED/PASSED/FAILED
12
+ * has two names -- `payload.name` (node:test's own, unprefixed) and
13
+ * `payload.qualifiedName` (suite-prefixed, matching the graph's own
14
+ * convention) -- and using the wrong one is a silent, plausible-looking
15
+ * miss (see `test-runner-collector.ts`'s own `SuiteStack` comment). This
16
+ * function is the one place that decision is made, so it cannot be made
17
+ * wrong at each call site independently.
18
+ *
19
+ * Does not call `EvidenceStore.attribute()` itself. That needs the
20
+ * evidence's real `evidenceId`, which only exists after `store.write()`
21
+ * has returned it -- outside this collector's own reach, same as every
22
+ * other collector's `graphNodeId: null`. The caller that already holds
23
+ * both the store and the graph `driver` (the same one `vertical-slice`'s
24
+ * tests already are) attributes; this only resolves.
25
+ */
26
+ import { resolveTestCaseNode } from "@descryy/runtime-graph-correlator";
27
+ /**
28
+ * **`TEST_SKIPPED` belongs here and was missing (RT-129).**
29
+ *
30
+ * RT-124's own commit message said a skipped test "resolves to the same
31
+ * `TEST_CASE` node a run test does". That was true of the payload — it
32
+ * carries `sourceLocation` and `qualifiedName` exactly like a pass — and
33
+ * false of this set, which refused it with the message a *wrong input*
34
+ * gets. The type was a counter with extra steps, which is precisely what
35
+ * the proposal argued against, and the claim was never checked against
36
+ * this line.
37
+ *
38
+ * The point of making it an event was that "the function you changed has a
39
+ * test and it is disabled" is expressible. It is not expressible if the
40
+ * evidence cannot reach a node.
41
+ */
42
+ const TEST_CASE_EVENT_TYPES = new Set(["TEST_STARTED", "TEST_PASSED", "TEST_FAILED", "TEST_SKIPPED"]);
43
+ /**
44
+ * Refuses (returns `"no-location"`, never throws) for anything that isn't
45
+ * TEST_STARTED/PASSED/FAILED evidence with a real `sourceLocation.file` --
46
+ * the same "wrong input, refuse rather than guess" shape every resolver in
47
+ * `graph-correlator` already uses for a missing `repoRoot` or an evidence
48
+ * item outside the declared repo.
49
+ */
50
+ export function resolveObservedTestCase(driver, evidence, repo, options = {}) {
51
+ if (!TEST_CASE_EVENT_TYPES.has(evidence.eventType)) {
52
+ return {
53
+ outcome: "no-location",
54
+ reason: `evidence.eventType is "${evidence.eventType}", not one of TEST_STARTED/TEST_PASSED/TEST_FAILED -- resolveObservedTestCase only knows how to map test-runner evidence.`,
55
+ };
56
+ }
57
+ const file = evidence.sourceLocation?.file ?? null;
58
+ if (file === null) {
59
+ return { outcome: "no-location", reason: "evidence.sourceLocation.file is null -- nothing to resolve a TEST_CASE node against." };
60
+ }
61
+ const payload = evidence.payload;
62
+ const qualifiedName = typeof payload.qualifiedName === "string" ? payload.qualifiedName : null;
63
+ if (qualifiedName === null) {
64
+ return {
65
+ outcome: "no-location",
66
+ reason: "evidence.payload.qualifiedName is missing or not a string -- this evidence was not produced by TestRunnerCollector's own translator.",
67
+ };
68
+ }
69
+ const line = evidence.sourceLocation?.line ?? null;
70
+ return resolveTestCaseNode(driver, { file, testName: qualifiedName, ...(line === null ? {} : { line }) }, repo, options);
71
+ }
72
+ //# sourceMappingURL=graph-mapping.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph-mapping.js","sourceRoot":"","sources":["../src/graph-mapping.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAGH,OAAO,EAAE,mBAAmB,EAA2B,MAAM,mCAAmC,CAAC;AAGjG;;;;;;;;;;;;;;GAcG;AACH,MAAM,qBAAqB,GAAkC,IAAI,GAAG,CAAC,CAAC,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,CAAC,CAAC,CAAC;AAMrI;;;;;;GAMG;AACH,MAAM,UAAU,uBAAuB,CACrC,MAAiB,EACjB,QAAoE,EACpE,IAAY,EACZ,UAA+E,EAAE;IAEjF,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QACnD,OAAO;YACL,OAAO,EAAE,aAAa;YACtB,MAAM,EAAE,0BAA0B,QAAQ,CAAC,SAAS,2HAA2H;SAChL,CAAC;IACJ,CAAC;IACD,MAAM,IAAI,GAAG,QAAQ,CAAC,cAAc,EAAE,IAAI,IAAI,IAAI,CAAC;IACnD,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAClB,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,sFAAsF,EAAE,CAAC;IACpI,CAAC;IACD,MAAM,OAAO,GAAG,QAAQ,CAAC,OAA+C,CAAC;IACzE,MAAM,aAAa,GAAG,OAAO,OAAO,CAAC,aAAa,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC;IAC/F,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;QAC3B,OAAO;YACL,OAAO,EAAE,aAAa;YACtB,MAAM,EAAE,sIAAsI;SAC/I,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,GAAG,QAAQ,CAAC,cAAc,EAAE,IAAI,IAAI,IAAI,CAAC;IACnD,OAAO,mBAAmB,CACxB,MAAM,EACN,EAAE,IAAI,EAAE,QAAQ,EAAE,aAAa,EAAE,GAAG,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EACrE,IAAI,EACJ,OAAO,CACR,CAAC;AACJ,CAAC"}
@@ -0,0 +1,10 @@
1
+ export type { TestRunnerConfiguration, TestRunnerCollectorOptions, TestRunnerCollector, RunnerDiscovery, RunnerKind, SkipReason, TraceCoverage, EnvelopeVerdict } from "./test-runner-collector.ts";
2
+ export { createTestRunnerCollector, discoverRunner, withReporterFlags, reporterFlagsFor, reporterEnvFor, createEnvelopeGate, ENVELOPE_VERSION, ENVELOPE_HANDSHAKE_TYPE } from "./test-runner-collector.ts";
3
+ export type { ObservedTestCaseResolution } from "./graph-mapping.ts";
4
+ export { resolveObservedTestCase } from "./graph-mapping.ts";
5
+ export type { SwiftTestDump, DiscoveredSwiftClass, SwiftDiscoveryResult, SwiftXCTestCollectorOptions, SwiftXCTestCollector } from "./swift-xctest.ts";
6
+ export { discoverClasses, generateLinuxMain, discoverSwiftTests, writeLinuxMain, removeGeneratedLinuxMain, createSwiftXCTestCollector, GENERATED_MARKER, } from "./swift-xctest.ts";
7
+ export type { GoTestEvent, GoTestCollectorOptions, GoTestCollector } from "./go-test.ts";
8
+ export { isGoTestEvent, createGoEventTranslator, createGoTestCollector } from "./go-test.ts";
9
+ export { COLLECTOR_VERSION } from "./collector-version.ts";
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,uBAAuB,EAAE,0BAA0B,EAAE,mBAAmB,EAAE,eAAe,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AACpM,OAAO,EAAE,yBAAyB,EAAE,cAAc,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,cAAc,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAE3M,YAAY,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAE7D,YAAY,EAAE,aAAa,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,2BAA2B,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACtJ,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,cAAc,EACd,wBAAwB,EACxB,0BAA0B,EAC1B,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAE3B,YAAY,EAAE,WAAW,EAAE,sBAAsB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACzF,OAAO,EAAE,aAAa,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAE7F,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,6 @@
1
+ export { createTestRunnerCollector, discoverRunner, withReporterFlags, reporterFlagsFor, reporterEnvFor, createEnvelopeGate, ENVELOPE_VERSION, ENVELOPE_HANDSHAKE_TYPE } from "./test-runner-collector.js";
2
+ export { resolveObservedTestCase } from "./graph-mapping.js";
3
+ export { discoverClasses, generateLinuxMain, discoverSwiftTests, writeLinuxMain, removeGeneratedLinuxMain, createSwiftXCTestCollector, GENERATED_MARKER, } from "./swift-xctest.js";
4
+ export { isGoTestEvent, createGoEventTranslator, createGoTestCollector } from "./go-test.js";
5
+ export { COLLECTOR_VERSION } from "./collector-version.js";
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAE,cAAc,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,cAAc,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAG3M,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAG7D,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,cAAc,EACd,wBAAwB,EACxB,0BAA0B,EAC1B,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,aAAa,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAE7F,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * A **Jest** custom reporter (`--reporters=<path to this file's compiled
3
+ * output>`), emitting the same NDJSON envelope `reporter.ts` emits for
4
+ * `node:test`.
5
+ *
6
+ * ## Why one envelope and three reporters, rather than three collectors
7
+ *
8
+ * The per-runner knowledge is *what its own structured API calls things*,
9
+ * and that knowledge only exists inside the runner's own process, where the
10
+ * API is. So each runner gets a reporter that speaks its API and writes the
11
+ * one shape `test-runner-collector.ts` already reads —
12
+ * `{type: "test:start"|"test:pass"|"test:fail", data: {...}}`, node:test's
13
+ * own event names, kept as the envelope because it was first and renaming
14
+ * them would churn a working translator for nothing.
15
+ *
16
+ * `createEventTranslator` therefore needed **no per-runner branch**: no
17
+ * `if (runner === "jest")` anywhere above this file, which is the same
18
+ * boundary rule the IR has. Everything Jest-specific is here.
19
+ *
20
+ * ## What Jest gives that node:test does not, and vice versa
21
+ *
22
+ * `testCaseResult.ancestorTitles` is the real `describe()` chain, so
23
+ * `qualifiedName` is exact rather than reconstructed — node:test forced
24
+ * `SuiteStack` to rebuild it from `nesting` because its events carry only
25
+ * the innermost title (RT-076). Emitting it directly is why the translator
26
+ * prefers a supplied `qualifiedName` over its own reconstruction.
27
+ *
28
+ * **Jest's own `fullName` is the same space-joined string** and is used
29
+ * here in preference to re-joining, since it is what Jest itself
30
+ * considers the test's full name. It matches `adapter-typescript`'s
31
+ * TEST_CASE convention (`[...suite, title].join(" ")`) exactly — verified
32
+ * against a real run, not assumed. Vitest's `fullName` does **not** (it
33
+ * joins with `" > "`), which is why `vitest-reporter.ts` rebuilds it and
34
+ * this one does not.
35
+ *
36
+ * **`onTestCaseStart` carries no location** — measured. Only
37
+ * `onTestCaseResult` does, and only when `--testLocationInResults` is
38
+ * passed. So TEST_STARTED for Jest has a `file` but null `line`/`column`,
39
+ * where node:test's has all three. Disclosed rather than filled in.
40
+ *
41
+ * ## `--testLocationInResults` is load-bearing, and its absence is silent
42
+ *
43
+ * Measured directly: without it, `testCaseResult.location` is `undefined`
44
+ * on every result. The collector still runs, still emits every event, and
45
+ * every one silently has no line or column — the same shape as RT-073's
46
+ * reporter-flag ordering bug, where the failure was "no error, wrong
47
+ * output". `withReporterFlags` injects it; it is not left to the caller.
48
+ */
49
+ interface JestTestCaseStartInfo {
50
+ readonly title: string;
51
+ readonly fullName: string;
52
+ readonly ancestorTitles: readonly string[];
53
+ }
54
+ interface JestTestCaseResult extends JestTestCaseStartInfo {
55
+ readonly status: string;
56
+ readonly duration: number | null;
57
+ readonly failureMessages: readonly string[];
58
+ readonly failureDetails?: readonly unknown[];
59
+ readonly location?: {
60
+ readonly line: number;
61
+ readonly column: number;
62
+ } | null;
63
+ }
64
+ interface JestTest {
65
+ readonly path: string;
66
+ }
67
+ export default class DescryJestReporter {
68
+ onTestCaseStart(test: JestTest, info: JestTestCaseStartInfo): void;
69
+ onTestCaseResult(test: JestTest, result: JestTestCaseResult): void;
70
+ }
71
+ export {};
72
+ //# sourceMappingURL=jest-reporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jest-reporter.d.ts","sourceRoot":"","sources":["../src/jest-reporter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AAEH,UAAU,qBAAqB;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5C;AAED,UAAU,kBAAmB,SAAQ,qBAAqB;IACxD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5C,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,OAAO,EAAE,CAAC;IAC7C,QAAQ,CAAC,QAAQ,CAAC,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CAC/E;AAED,UAAU,QAAQ;IAChB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAgBD,MAAM,CAAC,OAAO,OAAO,kBAAkB;IACrC,eAAe,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,qBAAqB,GAAG,IAAI;IAUlE,gBAAgB,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,kBAAkB,GAAG,IAAI;CAuCnE"}