@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.
- package/dist/collector-version.d.ts +10 -0
- package/dist/collector-version.d.ts.map +1 -0
- package/dist/collector-version.js +12 -0
- package/dist/collector-version.js.map +1 -0
- package/dist/go-test.d.ts +81 -0
- package/dist/go-test.d.ts.map +1 -0
- package/dist/go-test.js +224 -0
- package/dist/go-test.js.map +1 -0
- package/dist/graph-mapping.d.ts +44 -0
- package/dist/graph-mapping.d.ts.map +1 -0
- package/dist/graph-mapping.js +72 -0
- package/dist/graph-mapping.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/jest-reporter.d.ts +72 -0
- package/dist/jest-reporter.d.ts.map +1 -0
- package/dist/jest-reporter.js +110 -0
- package/dist/jest-reporter.js.map +1 -0
- package/dist/playwright-reporter.d.ts +67 -0
- package/dist/playwright-reporter.d.ts.map +1 -0
- package/dist/playwright-reporter.js +93 -0
- package/dist/playwright-reporter.js.map +1 -0
- package/dist/reporter.d.ts +35 -0
- package/dist/reporter.d.ts.map +1 -0
- package/dist/reporter.js +74 -0
- package/dist/reporter.js.map +1 -0
- package/dist/swift-xctest.d.ts +138 -0
- package/dist/swift-xctest.d.ts.map +1 -0
- package/dist/swift-xctest.js +384 -0
- package/dist/swift-xctest.js.map +1 -0
- package/dist/test-runner-collector.d.ts +370 -0
- package/dist/test-runner-collector.d.ts.map +1 -0
- package/dist/test-runner-collector.js +1014 -0
- package/dist/test-runner-collector.js.map +1 -0
- package/dist/vitest-reporter.d.ts +76 -0
- package/dist/vitest-reporter.d.ts.map +1 -0
- package/dist/vitest-reporter.js +131 -0
- package/dist/vitest-reporter.js.map +1 -0
- 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"}
|
package/dist/go-test.js
ADDED
|
@@ -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"}
|
package/dist/index.d.ts
ADDED
|
@@ -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"}
|