@overkill-dev/test 0.0.13 → 0.0.15
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/package.json +18 -12
- package/packages/test/authoring-input.js +34 -0
- package/packages/test/authoring-input.js.map +1 -0
- package/packages/test/authoring-source-locations.js +19 -3
- package/packages/test/authoring-source-locations.js.map +1 -1
- package/packages/test/authoring-test-data.d.ts +58 -0
- package/packages/test/authoring-test-data.d.ts.map +1 -0
- package/packages/test/authoring-test-data.js +194 -0
- package/packages/test/authoring-test-data.js.map +1 -0
- package/packages/test/command-line-runner.js +50 -5
- package/packages/test/command-line-runner.js.map +1 -1
- package/packages/test/compatibility.entry-point.d.ts +4 -0
- package/packages/test/compatibility.entry-point.d.ts.map +1 -0
- package/packages/test/compatibility.entry-point.js +2 -0
- package/packages/test/compatibility.entry-point.js.map +1 -0
- package/packages/test/config.entry-point.d.ts +1 -1
- package/packages/test/config.entry-point.d.ts.map +1 -1
- package/packages/test/harness-authoring.d.ts +18 -0
- package/packages/test/harness-authoring.d.ts.map +1 -0
- package/packages/test/harness-authoring.js +25 -0
- package/packages/test/harness-authoring.js.map +1 -0
- package/packages/test/interaction-transcript.d.ts +39 -0
- package/packages/test/interaction-transcript.d.ts.map +1 -0
- package/packages/test/interaction-transcript.js +302 -0
- package/packages/test/interaction-transcript.js.map +1 -0
- package/packages/test/reporters.entry-point.d.ts +1 -0
- package/packages/test/reporters.entry-point.d.ts.map +1 -1
- package/packages/test/resource-wrapper-composition.js +313 -0
- package/packages/test/resource-wrapper-composition.js.map +1 -0
- package/packages/test/resource-wrapper-data.d.ts +39 -0
- package/packages/test/resource-wrapper-data.d.ts.map +1 -0
- package/packages/test/resource-wrapper-data.js +101 -0
- package/packages/test/resource-wrapper-data.js.map +1 -0
- package/packages/test/resource-wrapper-runtime-scope.js +44 -0
- package/packages/test/resource-wrapper-runtime-scope.js.map +1 -0
- package/packages/test/resource-wrapper-session.js +3 -0
- package/packages/test/resource-wrapper-session.js.map +1 -0
- package/packages/test/resources.entry-point.d.ts +20 -1
- package/packages/test/resources.entry-point.d.ts.map +1 -1
- package/packages/test/resources.entry-point.js +46 -2
- package/packages/test/resources.entry-point.js.map +1 -1
- package/packages/test/run-seed-parser.js +8 -0
- package/packages/test/run-seed-parser.js.map +1 -0
- package/packages/test/run-shard-parser.js +32 -0
- package/packages/test/run-shard-parser.js.map +1 -0
- package/packages/test/table-authoring.d.ts +19 -0
- package/packages/test/table-authoring.d.ts.map +1 -0
- package/packages/test/table-authoring.js +77 -0
- package/packages/test/table-authoring.js.map +1 -0
- package/packages/test/test-authoring.d.ts +68 -0
- package/packages/test/test-authoring.d.ts.map +1 -0
- package/packages/test/test-authoring.js +212 -0
- package/packages/test/test-authoring.js.map +1 -0
- package/packages/test/test.entry-point.d.ts +10 -57
- package/packages/test/test.entry-point.d.ts.map +1 -1
- package/packages/test/test.entry-point.js +3 -215
- package/packages/test/test.entry-point.js.map +1 -1
- package/packages/test/throwing-test-authoring.d.ts +15 -0
- package/packages/test/throwing-test-authoring.d.ts.map +1 -0
- package/packages/test/throwing-test-authoring.js +47 -0
- package/packages/test/throwing-test-authoring.js.map +1 -0
- package/readme.md +355 -16
- package/sbom.cdx.json +61 -44
- package/packages/test/authoring-metadata.d.ts +0 -32
- package/packages/test/authoring-metadata.d.ts.map +0 -1
- package/packages/test/authoring-metadata.js +0 -98
- package/packages/test/authoring-metadata.js.map +0 -1
package/readme.md
CHANGED
|
@@ -6,13 +6,70 @@ This package ships the public `overkill` binary and the staged root authoring
|
|
|
6
6
|
facade. The binary parses the minimal command surface and delegates
|
|
7
7
|
execution to `@overkill-dev/run/command-line`.
|
|
8
8
|
|
|
9
|
+
## Quick start
|
|
10
|
+
|
|
11
|
+
Install the standard distribution:
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
npm install -D @overkill-dev/test
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Create `overkill.config.ts`:
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
import { defineConfig } from '@overkill-dev/test/config';
|
|
21
|
+
|
|
22
|
+
export const config = defineConfig({
|
|
23
|
+
profiles: {
|
|
24
|
+
microtest: {
|
|
25
|
+
testFamily: 'microtest',
|
|
26
|
+
files: {
|
|
27
|
+
include: [ 'source/**/*.test.ts' ]
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Create `source/calculator.test.ts`:
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
import { suite, test } from '@overkill-dev/test';
|
|
38
|
+
|
|
39
|
+
function add(left: number, right: number): number {
|
|
40
|
+
return left + right;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export const testNode = suite('calculator', [
|
|
44
|
+
test('adds numbers', (scope) => {
|
|
45
|
+
scope.assert.equal(add(2, 3), 5);
|
|
46
|
+
|
|
47
|
+
return scope.assert.collect();
|
|
48
|
+
})
|
|
49
|
+
]);
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Run the configured test files:
|
|
53
|
+
|
|
54
|
+
```sh
|
|
55
|
+
npx overkill run
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Package surface
|
|
59
|
+
|
|
9
60
|
Current root runtime exports:
|
|
10
61
|
|
|
11
62
|
- `test`
|
|
63
|
+
- `skippedTest`
|
|
12
64
|
- `suite`
|
|
13
65
|
- `table`
|
|
66
|
+
- `defineHarness`
|
|
14
67
|
- `defineMacro`
|
|
15
68
|
- `defineParameterizedTestBody`
|
|
69
|
+
- `createTranscript`
|
|
70
|
+
- `recordSink`
|
|
71
|
+
- `recordAsyncSink`
|
|
72
|
+
- `transcriptUsage`
|
|
16
73
|
- `doubleUsage`
|
|
17
74
|
- `rule`
|
|
18
75
|
- `testDouble`
|
|
@@ -34,14 +91,19 @@ Standard subpaths:
|
|
|
34
91
|
`createGithubActionsOutputRenderer`.
|
|
35
92
|
- `@overkill-dev/test/assert` re-exports assertion-extension helpers from
|
|
36
93
|
`@overkill-dev/assert`.
|
|
37
|
-
- `@overkill-dev/test/
|
|
38
|
-
|
|
39
|
-
|
|
94
|
+
- `@overkill-dev/test/compatibility` exports `throwingTest` for explicit
|
|
95
|
+
throwable-style test authoring.
|
|
96
|
+
- `@overkill-dev/test/resources` re-exports typed resource and runtime
|
|
97
|
+
descriptors from `@overkill-dev/resources`, including
|
|
98
|
+
`createTemporaryDirectoryResource(...)`, and adds `withRuntime(...)`,
|
|
99
|
+
`withResource(...)`, and `withResources(...)` for runner-aware binding.
|
|
100
|
+
- `@overkill-dev/test/bench` and `@overkill-dev/test/baselines` are reserved.
|
|
101
|
+
They currently export only `unavailable()`.
|
|
40
102
|
|
|
41
103
|
Implemented root authoring forms:
|
|
42
104
|
|
|
43
105
|
```ts
|
|
44
|
-
import { doubleUsage, suite, table, test, testDouble } from '@overkill-dev/test';
|
|
106
|
+
import { doubleUsage, skippedTest, suite, table, test, testDouble } from '@overkill-dev/test';
|
|
45
107
|
|
|
46
108
|
export const testNode = suite('users', [
|
|
47
109
|
test('loads user', (scope) => {
|
|
@@ -61,7 +123,8 @@ export const testNode = suite('users', [
|
|
|
61
123
|
scope.assert.true(canLoadUser(scope.parameters));
|
|
62
124
|
return scope.assert.collect();
|
|
63
125
|
}
|
|
64
|
-
})
|
|
126
|
+
}),
|
|
127
|
+
skippedTest('loads platform user', 'requires linux')
|
|
65
128
|
]);
|
|
66
129
|
```
|
|
67
130
|
|
|
@@ -69,21 +132,40 @@ The root doubles exports are the current lightweight public surface from
|
|
|
69
132
|
`@overkill-dev/doubles`. Import the leaf package directly when documenting or
|
|
70
133
|
testing doubles package ownership.
|
|
71
134
|
|
|
72
|
-
Nodes created through this root facade
|
|
73
|
-
|
|
74
|
-
|
|
135
|
+
Nodes created through this root facade are family-neutral. The selected runner
|
|
136
|
+
profile owns family policy, capture support, resource policy, and timeout
|
|
137
|
+
validation.
|
|
138
|
+
|
|
139
|
+
Use the object form when attaching annotations or controls. Annotations on the
|
|
140
|
+
exported top-level `testNode` apply to the whole module's test tree.
|
|
141
|
+
|
|
142
|
+
`skippedTest(title, reason)` creates a visible leaf test with a mandatory
|
|
143
|
+
reason. It is discovered, listed, reported as skipped, and never runs user
|
|
144
|
+
code. Object form is `skippedTest({ title, annotations, controls, reason })`.
|
|
75
145
|
|
|
76
|
-
|
|
77
|
-
|
|
146
|
+
`throwingTest` is available from the compatibility subpath when a test should
|
|
147
|
+
pass by completing normally instead of returning `scope.assert.collect()`:
|
|
148
|
+
|
|
149
|
+
```ts
|
|
150
|
+
import { throwingTest } from '@overkill-dev/test/compatibility';
|
|
151
|
+
|
|
152
|
+
export const testNode = throwingTest('legacy assertion', (scope) => {
|
|
153
|
+
scope.assert.equal(add(2, 3), 5);
|
|
154
|
+
});
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
The throwing body receives `scope.assert`, `scope.require`, and `scope.signal`.
|
|
158
|
+
It does not expose `scope.plan` or `scope.assert.collect`.
|
|
78
159
|
|
|
79
160
|
```ts
|
|
80
161
|
export const testNode = suite({
|
|
81
162
|
title: 'users',
|
|
82
|
-
|
|
163
|
+
annotations: { tags: [ 'auth' ] },
|
|
83
164
|
children: [
|
|
84
165
|
test({
|
|
85
166
|
title: 'loads user',
|
|
86
|
-
|
|
167
|
+
annotations: { tags: [ 'critical' ] },
|
|
168
|
+
controls: { timeoutMilliseconds: 1_000 },
|
|
87
169
|
body(scope) {
|
|
88
170
|
scope.assert.equal(loadUser('42').name, 'Ada');
|
|
89
171
|
return scope.assert.collect();
|
|
@@ -98,6 +180,81 @@ body receives the original row value as `scope.parameters`; default row titles
|
|
|
98
180
|
are `case 1`, `case 2`, and so on. Reachable tables must contain at least two
|
|
99
181
|
rows.
|
|
100
182
|
|
|
183
|
+
`defineHarness` creates reusable test-side harness constructors:
|
|
184
|
+
|
|
185
|
+
```ts
|
|
186
|
+
const userHarness = defineHarness({
|
|
187
|
+
loadUser: () => testDouble.resolves<() => Promise<User>>(user)
|
|
188
|
+
}, (parts) => {
|
|
189
|
+
return {
|
|
190
|
+
subject: createUserService({ loadUser: parts.loadUser }),
|
|
191
|
+
...parts
|
|
192
|
+
};
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
const harness = userHarness.create();
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Object-form part factories run fresh for each `create()` call. Sparse
|
|
199
|
+
overrides replace final part values; overridden factories are not called.
|
|
200
|
+
Function-form harnesses support richer sync or async setup:
|
|
201
|
+
|
|
202
|
+
```ts
|
|
203
|
+
const renderUser = defineHarness(async (overrides: {
|
|
204
|
+
readonly loadUser?: () => Promise<User>;
|
|
205
|
+
}) => {
|
|
206
|
+
const loadUser = overrides.loadUser ?? testDouble.resolves<() => Promise<User>>(user);
|
|
207
|
+
|
|
208
|
+
return {
|
|
209
|
+
loadUser,
|
|
210
|
+
rendered: await render(<UserPage loadUser={loadUser} />)
|
|
211
|
+
};
|
|
212
|
+
});
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
`createTranscript` records ordered interaction entries as tuple values:
|
|
216
|
+
|
|
217
|
+
```ts
|
|
218
|
+
const transcript = createTranscript<readonly [kind: 'state', value: number]>();
|
|
219
|
+
|
|
220
|
+
transcript.record('state', 1);
|
|
221
|
+
|
|
222
|
+
scope.assert(transcriptUsage.exactly, transcript, [
|
|
223
|
+
[ 'state', 1 ]
|
|
224
|
+
]);
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
`transcript.sink(kind)` creates a void test double that records each call as
|
|
228
|
+
`[kind, ...args]`. The double call history and transcript entries reset
|
|
229
|
+
independently.
|
|
230
|
+
|
|
231
|
+
```ts
|
|
232
|
+
const transcript = createTranscript<readonly [kind: 'warn', message: string]>();
|
|
233
|
+
const warn = transcript.sink<(message: string) => void>('warn');
|
|
234
|
+
|
|
235
|
+
warn('retrying');
|
|
236
|
+
|
|
237
|
+
scope.assert(transcriptUsage.contains, transcript, [ 'warn', 'retrying' ]);
|
|
238
|
+
scope.assert(doubleUsage.calledOnceWith, warn, [ 'retrying' ]);
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
`recordSink` and `recordAsyncSink` subscribe immediately and return disposable
|
|
242
|
+
transcripts for callback-based sources:
|
|
243
|
+
|
|
244
|
+
```ts
|
|
245
|
+
const states = recordSink<readonly [kind: 'state', value: number]>((record) => {
|
|
246
|
+
return store.subscribe((value) => {
|
|
247
|
+
record('state', value);
|
|
248
|
+
});
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
const events = recordAsyncSink<readonly [kind: 'event', value: Event]>((record) => {
|
|
252
|
+
return queue.listen((value) => {
|
|
253
|
+
record('event', value);
|
|
254
|
+
});
|
|
255
|
+
});
|
|
256
|
+
```
|
|
257
|
+
|
|
101
258
|
`defineMacro` preserves source locations for reusable test-node factories:
|
|
102
259
|
|
|
103
260
|
```ts
|
|
@@ -129,8 +286,112 @@ export const testNode = suite('users', [
|
|
|
129
286
|
]);
|
|
130
287
|
```
|
|
131
288
|
|
|
132
|
-
|
|
133
|
-
|
|
289
|
+
Runtime handles stay behind the resources subpath:
|
|
290
|
+
|
|
291
|
+
```ts
|
|
292
|
+
import { createTestFacade } from '@overkill-dev/test';
|
|
293
|
+
import {
|
|
294
|
+
composeRuntimes,
|
|
295
|
+
createTemporaryDirectoryResource,
|
|
296
|
+
defineResource,
|
|
297
|
+
defineRuntime,
|
|
298
|
+
withResource,
|
|
299
|
+
withRuntime
|
|
300
|
+
} from '@overkill-dev/test/resources';
|
|
301
|
+
|
|
302
|
+
const api = createTestFacade({ annotations: { tags: [ 'api' ] } });
|
|
303
|
+
const scratch = createTemporaryDirectoryResource('scratch');
|
|
304
|
+
const database = defineResource({
|
|
305
|
+
name: 'database',
|
|
306
|
+
scope: 'per-file',
|
|
307
|
+
requirements: [],
|
|
308
|
+
dependencies: {},
|
|
309
|
+
acquire() {
|
|
310
|
+
return openDatabase();
|
|
311
|
+
},
|
|
312
|
+
deserializeHandle(payload) {
|
|
313
|
+
return { url: payload.url };
|
|
314
|
+
},
|
|
315
|
+
dispose(database) {
|
|
316
|
+
return database.close();
|
|
317
|
+
},
|
|
318
|
+
serializeHandle(database) {
|
|
319
|
+
return { url: database.url };
|
|
320
|
+
}
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
const runtime = defineRuntime({
|
|
324
|
+
name: 'api',
|
|
325
|
+
dimensions: {},
|
|
326
|
+
resources: { database, scratch },
|
|
327
|
+
requirements: []
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
api.test(
|
|
331
|
+
'loads user',
|
|
332
|
+
withRuntime(runtime, (scope) => {
|
|
333
|
+
scope.assert.true(scope.signal instanceof AbortSignal);
|
|
334
|
+
scope.assert.equal(typeof scope.runtimes.api.database, 'object');
|
|
335
|
+
return scope.assert.collect();
|
|
336
|
+
})
|
|
337
|
+
);
|
|
338
|
+
|
|
339
|
+
api.test(
|
|
340
|
+
'writes scratch output',
|
|
341
|
+
withResource(scratch, (scope) => {
|
|
342
|
+
scope.assert.true(scope.signal instanceof AbortSignal);
|
|
343
|
+
scope.assert.true(scope.resources.scratch.path.length > 0);
|
|
344
|
+
return scope.assert.collect();
|
|
345
|
+
})
|
|
346
|
+
);
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
Resource wrappers attach descriptors for runner collection and acquire handles
|
|
350
|
+
when the body executes. `withRuntime(...)` exposes handles at
|
|
351
|
+
`scope.runtimes.<runtimeName>`, while `withResource(...)` and
|
|
352
|
+
`withResources(...)` expose handles at `scope.resources.<resourceKey>`.
|
|
353
|
+
`composeRuntimes(...)` combines leaf runtimes and runtime matrices into one
|
|
354
|
+
graph while keeping child runtime names as the public `scope.runtimes` keys.
|
|
355
|
+
Nested resource wrappers compose into one per-case acquisition graph before
|
|
356
|
+
the body runs when no runner lifecycle policy is active. During normal
|
|
357
|
+
runner execution, wrappers declare descriptors and the runner acquires them at
|
|
358
|
+
their declared `per-run`, `per-file`, `per-suite`, `per-case`, or
|
|
359
|
+
`shared-per-worker` lifetime boundary. Duplicate public `scope.resources` keys or public
|
|
360
|
+
`scope.runtimes` names are rejected before planning; resource keys inside
|
|
361
|
+
different runtime scopes remain namespaced by their runtime name.
|
|
362
|
+
`per-run` resources require `serializeHandle(...)` and
|
|
363
|
+
`deserializeHandle(...)`; `per-file` and `per-suite` resources may use those
|
|
364
|
+
hooks when the owner handle and consumer handle differ.
|
|
365
|
+
Microtest profiles reject collected resource descriptors before execution.
|
|
366
|
+
|
|
367
|
+
Test bodies receive async-control methods on `scope`:
|
|
368
|
+
|
|
369
|
+
| Method | Purpose |
|
|
370
|
+
| -------------------- | --------------------------------------------------------- |
|
|
371
|
+
| `drainMicrotasks()` | Wait for already-scheduled Promise and microtask work. |
|
|
372
|
+
| `yieldToNextTurn()` | Yield through one Node event-loop turn. |
|
|
373
|
+
| `settleAsyncWork()` | Run a bounded set of microtask and next-turn checkpoints. |
|
|
374
|
+
| `startInFlight(...)` | Start background Promise work now and observe it later. |
|
|
375
|
+
| `cleanup(...)` | Register sync or async teardown for test-owned resources. |
|
|
376
|
+
|
|
377
|
+
```ts
|
|
378
|
+
test('logs background failures', async (scope) => {
|
|
379
|
+
const run = scope.startInFlight(() => worker.run());
|
|
380
|
+
|
|
381
|
+
await scope.yieldToNextTurn();
|
|
382
|
+
|
|
383
|
+
await run.rejects({ message: 'boom' });
|
|
384
|
+
scope.assert.equal(logger.error.interactionCount, 1);
|
|
385
|
+
return scope.assert.collect();
|
|
386
|
+
});
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
`settleAsyncWork()` is intentionally bounded. Use it for finite queue
|
|
390
|
+
cascades, not as proof that all background work is complete. Work started with
|
|
391
|
+
`startInFlight(...)` must settle and be observed before the test ends.
|
|
392
|
+
|
|
393
|
+
`createTestFacade` creates another narrow authoring surface without selecting
|
|
394
|
+
a test family:
|
|
134
395
|
|
|
135
396
|
```ts
|
|
136
397
|
import { createTestFacade } from '@overkill-dev/test';
|
|
@@ -139,17 +400,84 @@ export const {
|
|
|
139
400
|
defineMacro,
|
|
140
401
|
defineParameterizedTestBody,
|
|
141
402
|
runIfMain,
|
|
403
|
+
skippedTest,
|
|
142
404
|
suite,
|
|
143
405
|
table,
|
|
144
406
|
test
|
|
145
407
|
} = createTestFacade({
|
|
146
|
-
|
|
147
|
-
|
|
408
|
+
annotations: { tags: [ 'api' ] },
|
|
409
|
+
controls: { capture: 'live' }
|
|
148
410
|
});
|
|
149
411
|
```
|
|
150
412
|
|
|
413
|
+
Facades can also bind one runtime graph, direct resources, and project-owned
|
|
414
|
+
scope conveniences:
|
|
415
|
+
|
|
416
|
+
```ts
|
|
417
|
+
import { createTestFacade } from '@overkill-dev/test';
|
|
418
|
+
import { apiRuntime, scratch } from '#tests/resources';
|
|
419
|
+
|
|
420
|
+
export const { test } = createTestFacade({
|
|
421
|
+
runtime: apiRuntime,
|
|
422
|
+
resources: { scratch },
|
|
423
|
+
mapScope(scope) {
|
|
424
|
+
return {
|
|
425
|
+
apiUrl: scope.runtimes.api.server.url,
|
|
426
|
+
scratchPath: scope.resources.scratch.path
|
|
427
|
+
};
|
|
428
|
+
}
|
|
429
|
+
});
|
|
430
|
+
|
|
431
|
+
test('loads users', (scope) => {
|
|
432
|
+
scope.assert.true(scope.apiUrl.length > 0);
|
|
433
|
+
scope.assert.true(scope.scratchPath.length > 0);
|
|
434
|
+
return scope.assert.collect();
|
|
435
|
+
});
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
`mapScope(...)` sees the base test scope plus facade-bound runtime and
|
|
439
|
+
resource handles. Body-specific `withRuntime(...)`, `withResource(...)`, and
|
|
440
|
+
`withResources(...)` wrappers still compose into the final body scope, but
|
|
441
|
+
they are not inputs to the facade mapper.
|
|
442
|
+
|
|
443
|
+
`mapScope(...)` may add project-owned convenience properties only. It must not
|
|
444
|
+
return reserved scope keys: `assert`, `require`, `plan`, `collect`, `cleanup`,
|
|
445
|
+
`signal`, `drainMicrotasks`, `settleAsyncWork`, `startInFlight`,
|
|
446
|
+
`yieldToNextTurn`, `runtimes`, `resources`, or `parameters`. Known collisions
|
|
447
|
+
are rejected by TypeScript, and dynamic mapper results are validated at
|
|
448
|
+
runtime before the mapped scope is composed.
|
|
449
|
+
|
|
151
450
|
The returned facade contains authoring helpers only. Assertions and doubles
|
|
152
451
|
are imported alongside it instead of being registered into the facade.
|
|
452
|
+
Facades and root helpers accept `controls.capture` as authored data. The
|
|
453
|
+
selected profile decides whether that control is valid for a run.
|
|
454
|
+
|
|
455
|
+
Default tests should keep importing from `@overkill-dev/test`. When a project
|
|
456
|
+
has a custom facade, it can re-export that facade through a stable local alias:
|
|
457
|
+
|
|
458
|
+
```json
|
|
459
|
+
{
|
|
460
|
+
"imports": {
|
|
461
|
+
"#tests/custom-authoring": "./testing/custom-authoring.ts"
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
```ts
|
|
467
|
+
import { createTestFacade } from '@overkill-dev/test';
|
|
468
|
+
|
|
469
|
+
export const { suite, test } = createTestFacade({
|
|
470
|
+
annotations: { tags: [ 'custom-authoring' ] }
|
|
471
|
+
});
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
```ts
|
|
475
|
+
import { suite, test } from '#tests/custom-authoring';
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
Native Node `package.json#imports` aliases must start with `#`. A project can
|
|
479
|
+
use an alias such as `@tests/my-facade` only when its TypeScript or bundler
|
|
480
|
+
tooling owns that resolution.
|
|
153
481
|
|
|
154
482
|
Direct Node execution:
|
|
155
483
|
|
|
@@ -179,8 +507,11 @@ Supported command-line surface:
|
|
|
179
507
|
- `--config <path>`
|
|
180
508
|
- `--file <path>`
|
|
181
509
|
- `--filter <expr>`
|
|
510
|
+
- `--order <seeded|lexical>`
|
|
511
|
+
- `--seed <n>`
|
|
182
512
|
- `--title <text>`
|
|
183
513
|
- `--profile <name>`
|
|
514
|
+
- `--no-capture`
|
|
184
515
|
- `--measure-resource-usage`
|
|
185
516
|
- `--resource-budget <name=value>`
|
|
186
517
|
- `--with-locations`
|
|
@@ -191,10 +522,18 @@ Supported command-line surface:
|
|
|
191
522
|
`residentSetGrowthBytesPerSecond`. Supplying a resource budget enables
|
|
192
523
|
resource usage measurement for that run.
|
|
193
524
|
|
|
525
|
+
`--no-capture` applies to `run` only. It passes stdout and stderr through live
|
|
526
|
+
for capture-capable profiles and is invalid for microtest profiles.
|
|
527
|
+
|
|
194
528
|
`--filter`, `--title`, and `--file` apply the same run selection to `run` and
|
|
195
529
|
`list`. `--filter` supports `=`, `~`, `:`, `!`, `|`, and parentheses over
|
|
196
530
|
`tag`, `runtime`, `owner`, `stability`, `file`, `title`, `suite`, and `params`.
|
|
197
531
|
|
|
532
|
+
Runs use seeded ordering by default. Pass `--seed <n>` to reproduce a shuffle,
|
|
533
|
+
or `--order lexical` to use deterministic source-stable order. `runIfMain(...)`
|
|
534
|
+
also uses seeded order and reports the generated seed through run facts and
|
|
535
|
+
first-party reporters.
|
|
536
|
+
|
|
198
537
|
When no paths are supplied, `run` and `list` discover files from the selected
|
|
199
538
|
profile's `files.include` and `files.exclude` policy. Explicit file paths run
|
|
200
539
|
directly. Directory paths filter the selected profile's discovered files and
|
package/sbom.cdx.json
CHANGED
|
@@ -16,115 +16,128 @@
|
|
|
16
16
|
"component": {
|
|
17
17
|
"type": "library",
|
|
18
18
|
"name": "@overkill-dev/test",
|
|
19
|
-
"version": "0.0.
|
|
20
|
-
"bom-ref": "pkg:npm/@overkill-dev/test@0.0.
|
|
21
|
-
"purl": "pkg:npm/@overkill-dev/test@0.0.
|
|
19
|
+
"version": "0.0.15",
|
|
20
|
+
"bom-ref": "pkg:npm/@overkill-dev/test@0.0.15",
|
|
21
|
+
"purl": "pkg:npm/@overkill-dev/test@0.0.15"
|
|
22
22
|
}
|
|
23
23
|
},
|
|
24
24
|
"components": [
|
|
25
25
|
{
|
|
26
26
|
"type": "library",
|
|
27
27
|
"name": "@overkill-dev/assert",
|
|
28
|
-
"version": "0.0.
|
|
29
|
-
"bom-ref": "pkg:npm/@overkill-dev/assert@0.0.
|
|
28
|
+
"version": "0.0.31",
|
|
29
|
+
"bom-ref": "pkg:npm/@overkill-dev/assert@0.0.31",
|
|
30
30
|
"scope": "required",
|
|
31
31
|
"licenses": [
|
|
32
32
|
{
|
|
33
33
|
"expression": "MIT"
|
|
34
34
|
}
|
|
35
35
|
],
|
|
36
|
-
"purl": "pkg:npm/@overkill-dev/assert@0.0.
|
|
36
|
+
"purl": "pkg:npm/@overkill-dev/assert@0.0.31"
|
|
37
37
|
},
|
|
38
38
|
{
|
|
39
39
|
"type": "library",
|
|
40
40
|
"name": "@overkill-dev/doubles",
|
|
41
|
-
"version": "0.0.
|
|
42
|
-
"bom-ref": "pkg:npm/@overkill-dev/doubles@0.0.
|
|
41
|
+
"version": "0.0.29",
|
|
42
|
+
"bom-ref": "pkg:npm/@overkill-dev/doubles@0.0.29",
|
|
43
43
|
"scope": "required",
|
|
44
44
|
"licenses": [
|
|
45
45
|
{
|
|
46
46
|
"expression": "MIT"
|
|
47
47
|
}
|
|
48
48
|
],
|
|
49
|
-
"purl": "pkg:npm/@overkill-dev/doubles@0.0.
|
|
49
|
+
"purl": "pkg:npm/@overkill-dev/doubles@0.0.29"
|
|
50
50
|
},
|
|
51
51
|
{
|
|
52
52
|
"type": "library",
|
|
53
53
|
"name": "@overkill-dev/engine",
|
|
54
|
-
"version": "0.0.
|
|
55
|
-
"bom-ref": "pkg:npm/@overkill-dev/engine@0.0.
|
|
54
|
+
"version": "0.0.39",
|
|
55
|
+
"bom-ref": "pkg:npm/@overkill-dev/engine@0.0.39",
|
|
56
56
|
"scope": "required",
|
|
57
57
|
"licenses": [
|
|
58
58
|
{
|
|
59
59
|
"expression": "MIT"
|
|
60
60
|
}
|
|
61
61
|
],
|
|
62
|
-
"purl": "pkg:npm/@overkill-dev/engine@0.0.
|
|
62
|
+
"purl": "pkg:npm/@overkill-dev/engine@0.0.39"
|
|
63
63
|
},
|
|
64
64
|
{
|
|
65
65
|
"type": "library",
|
|
66
66
|
"name": "@overkill-dev/output-renderer-github-actions",
|
|
67
|
-
"version": "0.0.
|
|
68
|
-
"bom-ref": "pkg:npm/@overkill-dev/output-renderer-github-actions@0.0.
|
|
67
|
+
"version": "0.0.20",
|
|
68
|
+
"bom-ref": "pkg:npm/@overkill-dev/output-renderer-github-actions@0.0.20",
|
|
69
69
|
"scope": "required",
|
|
70
70
|
"licenses": [
|
|
71
71
|
{
|
|
72
72
|
"expression": "MIT"
|
|
73
73
|
}
|
|
74
74
|
],
|
|
75
|
-
"purl": "pkg:npm/@overkill-dev/output-renderer-github-actions@0.0.
|
|
75
|
+
"purl": "pkg:npm/@overkill-dev/output-renderer-github-actions@0.0.20"
|
|
76
76
|
},
|
|
77
77
|
{
|
|
78
78
|
"type": "library",
|
|
79
79
|
"name": "@overkill-dev/reporter-brief",
|
|
80
|
-
"version": "0.0.
|
|
81
|
-
"bom-ref": "pkg:npm/@overkill-dev/reporter-brief@0.0.
|
|
80
|
+
"version": "0.0.20",
|
|
81
|
+
"bom-ref": "pkg:npm/@overkill-dev/reporter-brief@0.0.20",
|
|
82
82
|
"scope": "required",
|
|
83
83
|
"licenses": [
|
|
84
84
|
{
|
|
85
85
|
"expression": "MIT"
|
|
86
86
|
}
|
|
87
87
|
],
|
|
88
|
-
"purl": "pkg:npm/@overkill-dev/reporter-brief@0.0.
|
|
88
|
+
"purl": "pkg:npm/@overkill-dev/reporter-brief@0.0.20"
|
|
89
89
|
},
|
|
90
90
|
{
|
|
91
91
|
"type": "library",
|
|
92
92
|
"name": "@overkill-dev/reporter-dot",
|
|
93
|
-
"version": "0.0.
|
|
94
|
-
"bom-ref": "pkg:npm/@overkill-dev/reporter-dot@0.0.
|
|
93
|
+
"version": "0.0.31",
|
|
94
|
+
"bom-ref": "pkg:npm/@overkill-dev/reporter-dot@0.0.31",
|
|
95
95
|
"scope": "required",
|
|
96
96
|
"licenses": [
|
|
97
97
|
{
|
|
98
98
|
"expression": "MIT"
|
|
99
99
|
}
|
|
100
100
|
],
|
|
101
|
-
"purl": "pkg:npm/@overkill-dev/reporter-dot@0.0.
|
|
101
|
+
"purl": "pkg:npm/@overkill-dev/reporter-dot@0.0.31"
|
|
102
102
|
},
|
|
103
103
|
{
|
|
104
104
|
"type": "library",
|
|
105
105
|
"name": "@overkill-dev/reporter-line",
|
|
106
|
-
"version": "0.0.
|
|
107
|
-
"bom-ref": "pkg:npm/@overkill-dev/reporter-line@0.0.
|
|
106
|
+
"version": "0.0.31",
|
|
107
|
+
"bom-ref": "pkg:npm/@overkill-dev/reporter-line@0.0.31",
|
|
108
108
|
"scope": "required",
|
|
109
109
|
"licenses": [
|
|
110
110
|
{
|
|
111
111
|
"expression": "MIT"
|
|
112
112
|
}
|
|
113
113
|
],
|
|
114
|
-
"purl": "pkg:npm/@overkill-dev/reporter-line@0.0.
|
|
114
|
+
"purl": "pkg:npm/@overkill-dev/reporter-line@0.0.31"
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"type": "library",
|
|
118
|
+
"name": "@overkill-dev/resources",
|
|
119
|
+
"version": "0.0.2",
|
|
120
|
+
"bom-ref": "pkg:npm/@overkill-dev/resources@0.0.2",
|
|
121
|
+
"scope": "required",
|
|
122
|
+
"licenses": [
|
|
123
|
+
{
|
|
124
|
+
"expression": "MIT"
|
|
125
|
+
}
|
|
126
|
+
],
|
|
127
|
+
"purl": "pkg:npm/@overkill-dev/resources@0.0.2"
|
|
115
128
|
},
|
|
116
129
|
{
|
|
117
130
|
"type": "library",
|
|
118
131
|
"name": "@overkill-dev/run",
|
|
119
|
-
"version": "0.0.
|
|
120
|
-
"bom-ref": "pkg:npm/@overkill-dev/run@0.0.
|
|
132
|
+
"version": "0.0.51",
|
|
133
|
+
"bom-ref": "pkg:npm/@overkill-dev/run@0.0.51",
|
|
121
134
|
"scope": "required",
|
|
122
135
|
"licenses": [
|
|
123
136
|
{
|
|
124
137
|
"expression": "MIT"
|
|
125
138
|
}
|
|
126
139
|
],
|
|
127
|
-
"purl": "pkg:npm/@overkill-dev/run@0.0.
|
|
140
|
+
"purl": "pkg:npm/@overkill-dev/run@0.0.51"
|
|
128
141
|
},
|
|
129
142
|
{
|
|
130
143
|
"type": "library",
|
|
@@ -142,40 +155,44 @@
|
|
|
142
155
|
],
|
|
143
156
|
"dependencies": [
|
|
144
157
|
{
|
|
145
|
-
"ref": "pkg:npm/@overkill-dev/assert@0.0.
|
|
158
|
+
"ref": "pkg:npm/@overkill-dev/assert@0.0.31"
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
"ref": "pkg:npm/@overkill-dev/doubles@0.0.29"
|
|
146
162
|
},
|
|
147
163
|
{
|
|
148
|
-
"ref": "pkg:npm/@overkill-dev/
|
|
164
|
+
"ref": "pkg:npm/@overkill-dev/engine@0.0.39"
|
|
149
165
|
},
|
|
150
166
|
{
|
|
151
|
-
"ref": "pkg:npm/@overkill-dev/
|
|
167
|
+
"ref": "pkg:npm/@overkill-dev/output-renderer-github-actions@0.0.20"
|
|
152
168
|
},
|
|
153
169
|
{
|
|
154
|
-
"ref": "pkg:npm/@overkill-dev/
|
|
170
|
+
"ref": "pkg:npm/@overkill-dev/reporter-brief@0.0.20"
|
|
155
171
|
},
|
|
156
172
|
{
|
|
157
|
-
"ref": "pkg:npm/@overkill-dev/reporter-
|
|
173
|
+
"ref": "pkg:npm/@overkill-dev/reporter-dot@0.0.31"
|
|
158
174
|
},
|
|
159
175
|
{
|
|
160
|
-
"ref": "pkg:npm/@overkill-dev/reporter-
|
|
176
|
+
"ref": "pkg:npm/@overkill-dev/reporter-line@0.0.31"
|
|
161
177
|
},
|
|
162
178
|
{
|
|
163
|
-
"ref": "pkg:npm/@overkill-dev/
|
|
179
|
+
"ref": "pkg:npm/@overkill-dev/resources@0.0.2"
|
|
164
180
|
},
|
|
165
181
|
{
|
|
166
|
-
"ref": "pkg:npm/@overkill-dev/run@0.0.
|
|
182
|
+
"ref": "pkg:npm/@overkill-dev/run@0.0.51"
|
|
167
183
|
},
|
|
168
184
|
{
|
|
169
|
-
"ref": "pkg:npm/@overkill-dev/test@0.0.
|
|
185
|
+
"ref": "pkg:npm/@overkill-dev/test@0.0.15",
|
|
170
186
|
"dependsOn": [
|
|
171
|
-
"pkg:npm/@overkill-dev/assert@0.0.
|
|
172
|
-
"pkg:npm/@overkill-dev/doubles@0.0.
|
|
173
|
-
"pkg:npm/@overkill-dev/engine@0.0.
|
|
174
|
-
"pkg:npm/@overkill-dev/output-renderer-github-actions@0.0.
|
|
175
|
-
"pkg:npm/@overkill-dev/reporter-brief@0.0.
|
|
176
|
-
"pkg:npm/@overkill-dev/reporter-dot@0.0.
|
|
177
|
-
"pkg:npm/@overkill-dev/reporter-line@0.0.
|
|
178
|
-
"pkg:npm/@overkill-dev/
|
|
187
|
+
"pkg:npm/@overkill-dev/assert@0.0.31",
|
|
188
|
+
"pkg:npm/@overkill-dev/doubles@0.0.29",
|
|
189
|
+
"pkg:npm/@overkill-dev/engine@0.0.39",
|
|
190
|
+
"pkg:npm/@overkill-dev/output-renderer-github-actions@0.0.20",
|
|
191
|
+
"pkg:npm/@overkill-dev/reporter-brief@0.0.20",
|
|
192
|
+
"pkg:npm/@overkill-dev/reporter-dot@0.0.31",
|
|
193
|
+
"pkg:npm/@overkill-dev/reporter-line@0.0.31",
|
|
194
|
+
"pkg:npm/@overkill-dev/resources@0.0.2",
|
|
195
|
+
"pkg:npm/@overkill-dev/run@0.0.51",
|
|
179
196
|
"pkg:npm/cmd-ts@0.15.0"
|
|
180
197
|
]
|
|
181
198
|
},
|