@descryy/runtime-test-runner 0.2.1 → 0.4.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/LICENSE +6 -0
- package/dist/collector-version.d.ts +2 -6
- package/dist/collector-version.d.ts.map +1 -1
- package/dist/collector-version.js +2 -6
- package/dist/collector-version.js.map +1 -1
- package/dist/go-test.d.ts +24 -50
- package/dist/go-test.d.ts.map +1 -1
- package/dist/go-test.js +30 -68
- package/dist/go-test.js.map +1 -1
- package/dist/graph-mapping.d.ts +10 -28
- package/dist/graph-mapping.d.ts.map +1 -1
- package/dist/graph-mapping.js +16 -43
- package/dist/graph-mapping.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/jest-reporter.d.ts +20 -46
- package/dist/jest-reporter.d.ts.map +1 -1
- package/dist/jest-reporter.js +28 -71
- package/dist/jest-reporter.js.map +1 -1
- package/dist/playwright-reporter.d.ts +16 -34
- package/dist/playwright-reporter.d.ts.map +1 -1
- package/dist/playwright-reporter.js +22 -51
- package/dist/playwright-reporter.js.map +1 -1
- package/dist/reporter.d.ts +7 -19
- package/dist/reporter.d.ts.map +1 -1
- package/dist/reporter.js +18 -52
- package/dist/reporter.js.map +1 -1
- package/dist/swift-xctest.d.ts +40 -94
- package/dist/swift-xctest.d.ts.map +1 -1
- package/dist/swift-xctest.js +47 -105
- package/dist/swift-xctest.js.map +1 -1
- package/dist/test-runner-collector.d.ts +139 -2
- package/dist/test-runner-collector.d.ts.map +1 -1
- package/dist/test-runner-collector.js +322 -42
- package/dist/test-runner-collector.js.map +1 -1
- package/dist/vitest-reporter.d.ts +19 -43
- package/dist/vitest-reporter.d.ts.map +1 -1
- package/dist/vitest-reporter.js +30 -82
- package/dist/vitest-reporter.js.map +1 -1
- package/package.json +11 -6
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
* state, not derivation.
|
|
34
34
|
*
|
|
35
35
|
* **Discovery is declared, never inferred** (RT-032's own precedent):
|
|
36
|
-
* `discoverRunner` refuses a command that names none of the
|
|
36
|
+
* `discoverRunner` refuses a command that names none of the eleven runners
|
|
37
37
|
* it observes, rather than sniffing `package.json`/lockfiles to guess which
|
|
38
38
|
* runner a project uses. Also refuses a command that already carries its
|
|
39
39
|
* own `--test-reporter` — safely co-existing with an unknown pre-existing
|
|
@@ -42,6 +42,28 @@
|
|
|
42
42
|
* to get right blindly; a caller who wants both gets an honest refusal
|
|
43
43
|
* naming why, not a best-effort guess.
|
|
44
44
|
*
|
|
45
|
+
* **unittest is the one profile with no reporter API to speak the envelope
|
|
46
|
+
* at all** (B4's own root-cause note: "a disclosed gap, not a missing
|
|
47
|
+
* capability" was the wrong ruling once a real user's declared command
|
|
48
|
+
* turned out to be exactly this one). `python -m unittest` has no plugin
|
|
49
|
+
* flag, no custom-runner flag, nothing argv can point at an installed
|
|
50
|
+
* module the way every other profile's reporter is loaded — so it is the
|
|
51
|
+
* one runner whose events are parsed from its own human-readable `-v`
|
|
52
|
+
* stdout/stderr text (`createUnittestResultParser`, below) rather than
|
|
53
|
+
* translated from NDJSON through the shared envelope gate. `start()`
|
|
54
|
+
* branches on `discovery.kind === "unittest"` for exactly this reason, a
|
|
55
|
+
* disclosed, narrow exception to "no per-runner branch below this line" —
|
|
56
|
+
* everything the parser produces still feeds the same `NodeTestEvent`
|
|
57
|
+
* shape and the same `createEventTranslator`, so a `TEST_CASE` result from
|
|
58
|
+
* unittest is indistinguishable downstream from one any other runner
|
|
59
|
+
* produced. What it cannot produce: a real `sourceLocation` (unittest's
|
|
60
|
+
* per-test line carries a qualified name, never a file/line — that only
|
|
61
|
+
* appears in the traceback section printed after every test has already
|
|
62
|
+
* finished, and matching one back to the right earlier result with
|
|
63
|
+
* confidence is exactly the inference precision-over-recall forbids), so
|
|
64
|
+
* every unittest result carries a null `sourceLocation` rather than one
|
|
65
|
+
* derived from prose.
|
|
66
|
+
*
|
|
45
67
|
* **Trace capture (RT-074): declared, via `TestContext.diagnostic()`, not
|
|
46
68
|
* inferred from anything.** A test that makes a backend call and wants its
|
|
47
69
|
* TEST_PASSED/TEST_FAILED evidence to correlate with that call's backend
|
|
@@ -96,7 +118,7 @@ export interface TestRunnerCollectorOptions {
|
|
|
96
118
|
* discovery rather than re-derived, so nothing downstream re-parses a
|
|
97
119
|
* command string it has already been told the answer for.
|
|
98
120
|
*/
|
|
99
|
-
export type RunnerKind = "node:test" | "jest" | "vitest" | "junit" | "xunit" | "playwright" | "pytest" | "rspec" | "phpunit" | "minitest";
|
|
121
|
+
export type RunnerKind = "node:test" | "jest" | "vitest" | "junit" | "xunit" | "playwright" | "pytest" | "rspec" | "phpunit" | "minitest" | "unittest";
|
|
100
122
|
/**
|
|
101
123
|
* The version of the NDJSON envelope every reporter speaks (RT-130).
|
|
102
124
|
*
|
|
@@ -211,6 +233,62 @@ export type RunnerDiscovery = {
|
|
|
211
233
|
* three and is why this is per-runner rather than one shared rule.
|
|
212
234
|
*/
|
|
213
235
|
export declare function withReporterFlags(args: readonly string[]): readonly string[];
|
|
236
|
+
/**
|
|
237
|
+
* One declared-command example per `PROFILES` entry, in table order.
|
|
238
|
+
*
|
|
239
|
+
* This is the fix for B4: the "names no runner this collector observes"
|
|
240
|
+
* refusal used to be a hardcoded string naming three runners, written when
|
|
241
|
+
* only node:test/Jest/Vitest existed and never regenerated as the other
|
|
242
|
+
* seven landed — so a published build that fully supported pytest told a
|
|
243
|
+
* Python caller only "node, jest, vitest" are supported. Deriving the list
|
|
244
|
+
* from `PROFILES` here means it cannot go stale again without the profile
|
|
245
|
+
* itself changing.
|
|
246
|
+
*/
|
|
247
|
+
export declare function supportedRunnerExamples(): readonly string[];
|
|
248
|
+
/** What `matchRunner` answers for a command it can name a profile for — everything a caller needs to render "this collector would use X", without exposing `RunnerProfile` itself. */
|
|
249
|
+
export interface RunnerMatch {
|
|
250
|
+
readonly kind: RunnerKind;
|
|
251
|
+
readonly declaredAs: string;
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Pure, side-effect-free: answers "would `discoverRunner` recognise this
|
|
255
|
+
* command's *shape*, and as which runner" without tokenizing into anything
|
|
256
|
+
* spawnable, without touching the filesystem, and without starting a
|
|
257
|
+
* collector.
|
|
258
|
+
*
|
|
259
|
+
* **Exists for one reason** (the second UAT finding on B4): `descry-core`'s
|
|
260
|
+
* `observe_tests` handshake used to mint a confirmation token for any
|
|
261
|
+
* declared command and only discover — on redemption, after already
|
|
262
|
+
* promising the caller a run — that `discoverRunner` would refuse it. A
|
|
263
|
+
* handshake that calls this function before minting a token refuses before
|
|
264
|
+
* it promises, instead of after.
|
|
265
|
+
*
|
|
266
|
+
* **The same matching `discoverRunner` itself uses, not a second copy of
|
|
267
|
+
* it.** Both call `findMatchingProfile`; a profile added, removed, or
|
|
268
|
+
* changed here is reflected in both without either being touched again —
|
|
269
|
+
* the discipline the hardcoded three-runner refusal list never had.
|
|
270
|
+
*
|
|
271
|
+
* A command `tokenizeCommand` cannot parse, and a command wrapped in `npx`,
|
|
272
|
+
* both return `null` here exactly as `discoverRunner` refuses them — `null`
|
|
273
|
+
* is authoritative in both of those cases: if this returns `null`,
|
|
274
|
+
* `discoverRunner` returns `{ ok: false }` for the same command, always.
|
|
275
|
+
* It is **not** authoritative the other direction — a non-null result names
|
|
276
|
+
* which profile a command's shape matches, not that `discoverRunner` will
|
|
277
|
+
* ultimately accept it. A matched profile can still refuse on the full
|
|
278
|
+
* argument list (`vitest` with no `run`, a command that already configures
|
|
279
|
+
* its own `--reporter`), which needs the complete tokenized args this
|
|
280
|
+
* predicate deliberately does not evaluate — that is a second, more
|
|
281
|
+
* specific refusal reached only by actually calling `discoverRunner`. Read
|
|
282
|
+
* a non-null result as "not obviously unsupported", not as "guaranteed to
|
|
283
|
+
* run".
|
|
284
|
+
*
|
|
285
|
+
* Use `supportedRunnerExamples()` to render the same "supported, and each
|
|
286
|
+
* declared explicitly: ..." list `discoverRunner`'s own generic refusal
|
|
287
|
+
* uses, so a handshake's up-front refusal and this collector's own
|
|
288
|
+
* run-time refusal are guaranteed to name the same runners rather than
|
|
289
|
+
* being two strings that happen to agree today.
|
|
290
|
+
*/
|
|
291
|
+
export declare function matchRunner(rawCommand: string): RunnerMatch | null;
|
|
214
292
|
/**
|
|
215
293
|
* Exported on its own so a caller can validate a configured command before
|
|
216
294
|
* ever attempting to spawn it — the same "refuse atomically before anything
|
|
@@ -288,6 +366,65 @@ export interface NodeTestEvent {
|
|
|
288
366
|
};
|
|
289
367
|
}
|
|
290
368
|
export declare function isNodeTestEvent(value: unknown): value is NodeTestEvent;
|
|
369
|
+
/**
|
|
370
|
+
* Parses CPython's own `unittest.runner.TextTestResult` verbose (`-v`)
|
|
371
|
+
* output into the same `NodeTestEvent` shape every other profile's reporter
|
|
372
|
+
* emits as real NDJSON -- so `createEventTranslator` never has to know this
|
|
373
|
+
* event did not arrive as JSON. See the file-level doc comment ("unittest is
|
|
374
|
+
* the one profile...") for why a reporter is not possible here at all.
|
|
375
|
+
*
|
|
376
|
+
* **Measured directly against a real `python -m unittest -v` run**, not
|
|
377
|
+
* assumed from documentation:
|
|
378
|
+
*
|
|
379
|
+
* ```
|
|
380
|
+
* test_pass (test_sample.TestSample.test_pass) ... ok
|
|
381
|
+
* test_fail (test_sample.TestSample.test_fail) ... FAIL
|
|
382
|
+
* test_error (test_sample.TestSample.test_error) ... ERROR
|
|
383
|
+
* test_skip (test_sample.TestSample.test_skip) ... skipped 'not ready'
|
|
384
|
+
* test_xfail (test_sample.TestSample.test_xfail) ... expected failure
|
|
385
|
+
* test_xpass (test_sample.TestSample.test_xpass) ... unexpected success
|
|
386
|
+
* ```
|
|
387
|
+
*
|
|
388
|
+
* and, for a test with a docstring, split across two lines instead of one
|
|
389
|
+
* (`getDescription` returns `"%s\n%s" % (str(test), doc_first_line)` when a
|
|
390
|
+
* docstring is present, `str(test)` alone otherwise):
|
|
391
|
+
*
|
|
392
|
+
* ```
|
|
393
|
+
* test_with_doc (test_doc.TestDoc.test_with_doc)
|
|
394
|
+
* This is a docstring. ... ok
|
|
395
|
+
* ```
|
|
396
|
+
*
|
|
397
|
+
* A header-only line is trusted for at most one line of lookahead: whatever
|
|
398
|
+
* arrives next either completes it (a docstring's first line, ending in
|
|
399
|
+
* ` ... <outcome>`) or does not, and either way the header is then
|
|
400
|
+
* discarded -- never left pending indefinitely waiting for a continuation
|
|
401
|
+
* that a stray print from the test body or an unrecognised outcome word
|
|
402
|
+
* might otherwise be mistaken for. A line the parser cannot place at all
|
|
403
|
+
* (the `======`/`----` banners, a traceback body, `Ran N tests...`, `OK`,
|
|
404
|
+
* `FAILED (...)`, or the test process's own stdout) is silently ignored --
|
|
405
|
+
* the same "unparseable output is ordinary and expected" rule every
|
|
406
|
+
* NDJSON-based profile already applies to its own noise.
|
|
407
|
+
*
|
|
408
|
+
* **What this deliberately does not attempt.** unittest's per-test line
|
|
409
|
+
* carries a qualified name only, never a file or line number -- those
|
|
410
|
+
* appear solely in the traceback section printed after every test in the
|
|
411
|
+
* run has already finished, under a `======`-delimited header repeating the
|
|
412
|
+
* test's own description. Re-associating that traceback with the correct
|
|
413
|
+
* earlier result, reliably, across a run with many tests (some sharing a
|
|
414
|
+
* class or method name across modules), is exactly the kind of inference
|
|
415
|
+
* precision-over-recall exists to forbid -- so no attempt is made, every
|
|
416
|
+
* `sourceLocation` this parser produces is null, and every FAILED/ERROR
|
|
417
|
+
* carries no `error` detail either, rather than one guessed from prose.
|
|
418
|
+
* `expected failure`/`unexpected success` fold into `TEST_SKIPPED`/
|
|
419
|
+
* `TEST_PASSED` respectively -- the same choice the pytest reporter already
|
|
420
|
+
* made for `xfail`/`xpass`, not a new one invented here. An outcome word
|
|
421
|
+
* this parser has never measured (a future CPython addition) still gets a
|
|
422
|
+
* `TEST_STARTED` -- the test did start -- but no paired result, on the same
|
|
423
|
+
* "report nothing rather than guess" rule.
|
|
424
|
+
*/
|
|
425
|
+
export declare function createUnittestResultParser(): {
|
|
426
|
+
feed(line: string): readonly NodeTestEvent[];
|
|
427
|
+
};
|
|
291
428
|
/**
|
|
292
429
|
* `test:pass`/`test:fail` arrive from node's own reporter stream BEFORE any
|
|
293
430
|
* `t.diagnostic()` call inside that same test shows up as its own
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-runner-collector.d.ts","sourceRoot":"","sources":["../src/test-runner-collector.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"test-runner-collector.d.ts","sourceRoot":"","sources":["../src/test-runner-collector.ts"],"names":[],"mappings":"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"}
|