@ontrails/testing 1.0.0-beta.11 → 1.0.0-beta.13
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/.turbo/turbo-lint.log +1 -1
- package/CHANGELOG.md +72 -22
- package/README.md +9 -9
- package/dist/context.d.ts +41 -11
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +36 -21
- package/dist/context.js.map +1 -1
- package/dist/contracts.js +8 -8
- package/dist/contracts.js.map +1 -1
- package/dist/crosses.d.ts +38 -0
- package/dist/crosses.d.ts.map +1 -0
- package/dist/crosses.js +213 -0
- package/dist/crosses.js.map +1 -0
- package/dist/examples.d.ts +4 -4
- package/dist/examples.d.ts.map +1 -1
- package/dist/examples.js +52 -32
- package/dist/examples.js.map +1 -1
- package/dist/harness-mcp.d.ts +1 -1
- package/dist/harness-mcp.js +2 -2
- package/dist/harness-mcp.js.map +1 -1
- package/dist/index.d.ts +6 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/trail.js +1 -1
- package/dist/trail.js.map +1 -1
- package/dist/types.d.ts +8 -8
- package/dist/types.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/__tests__/all.test.ts +20 -18
- package/src/__tests__/context.test.ts +27 -27
- package/src/__tests__/contracts.test.ts +29 -29
- package/src/__tests__/{follows.test.ts → crosses.test.ts} +193 -195
- package/src/__tests__/detours.test.ts +3 -3
- package/src/__tests__/examples.test.ts +221 -126
- package/src/__tests__/trail.test.ts +4 -4
- package/src/context.ts +80 -32
- package/src/contracts.ts +12 -12
- package/src/{follows.ts → crosses.ts} +97 -92
- package/src/examples.ts +76 -46
- package/src/harness-mcp.ts +2 -2
- package/src/index.ts +15 -7
- package/src/trail.ts +1 -1
- package/src/types.ts +9 -9
- package/tsconfig.tsbuildinfo +1 -1
package/.turbo/turbo-lint.log
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -1,22 +1,72 @@
|
|
|
1
1
|
# @ontrails/testing
|
|
2
2
|
|
|
3
|
+
## 1.0.0-beta.13
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Trail-native vocabulary cutover. Breaking API field renames across all packages:
|
|
8
|
+
|
|
9
|
+
- Trail spec: `run:` → `blaze:`, `follow:` → `crosses:`, `services:` → `provisions:`, `metadata:` → `meta:`, `emits:` → `signals:`
|
|
10
|
+
- Runtime: `ctx.follow()` → `ctx.cross()`, `ctx.emit()` → `ctx.signal()`, `ctx.signal` (abort) → `ctx.abortSignal`
|
|
11
|
+
- Entry points: `blaze(app)` → `trailhead(app)`
|
|
12
|
+
- Package rename: `@ontrails/crumbs` → `@ontrails/tracker`
|
|
13
|
+
- Wrapper types: `Layer` → `Gate`, `layers`/`middleware` → `gates`
|
|
14
|
+
- Transport: `surface` → `trailhead`, `adapter` → `connector`
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- 6944147: Complete trifecta for config, permits, and tracker (formerly tracks)
|
|
19
|
+
|
|
20
|
+
- **config**: Add `configProvision`, `configGate`, `config.trail`, and `config.workspace` trails with full `defineConfig`, `resolve`, `describe`, `explain`, `doctor`, and code generation support
|
|
21
|
+
- **permits**: Add `authService` and `auth.verify` trail for runtime authorization checks
|
|
22
|
+
- **tracker**: Rename tracks to tracker; add `trackerProvision` and `tracker.status` trail for structured signal tracking
|
|
23
|
+
- **cli**: Fix build flag handling and improve bootstrap scaffolding
|
|
24
|
+
- **testing**: Expand test context helpers and example-based testing utilities
|
|
25
|
+
- **core/mcp/http**: Internal alignment for provision and composition updates
|
|
26
|
+
|
|
27
|
+
- Updated dependencies [6944147]
|
|
28
|
+
- Updated dependencies
|
|
29
|
+
- @ontrails/core@1.0.0-beta.13
|
|
30
|
+
- @ontrails/cli@1.0.0-beta.13
|
|
31
|
+
- @ontrails/mcp@1.0.0-beta.13
|
|
32
|
+
- @ontrails/logging@1.0.0-beta.13
|
|
33
|
+
|
|
34
|
+
## 1.0.0-beta.12
|
|
35
|
+
|
|
36
|
+
### Patch Changes
|
|
37
|
+
|
|
38
|
+
- Complete trifecta for config, permits, and tracker (formerly tracks)
|
|
39
|
+
|
|
40
|
+
- **config**: Add `configProvision`, `config.gate`, `config.trail`, and `config.workspace` trails with full `defineConfig`, `resolve`, `describe`, `explain`, `doctor`, and code generation support
|
|
41
|
+
- **permits**: Add `authProvision` and `auth.verify` trail for runtime authorization checks
|
|
42
|
+
- **tracker**: Rename tracks to tracker; add `trackerProvision` and `tracker.status` trail for structured event tracking
|
|
43
|
+
- **cli**: Fix build flag handling and improve bootstrap scaffolding
|
|
44
|
+
- **testing**: Expand test context helpers and example-based testing utilities
|
|
45
|
+
- **core/mcp/http**: Internal alignment for provision and composition updates
|
|
46
|
+
|
|
47
|
+
- Updated dependencies
|
|
48
|
+
- @ontrails/core@1.0.0-beta.12
|
|
49
|
+
- @ontrails/cli@1.0.0-beta.12
|
|
50
|
+
- @ontrails/mcp@1.0.0-beta.12
|
|
51
|
+
- @ontrails/logging@1.0.0-beta.12
|
|
52
|
+
|
|
3
53
|
## 1.0.0-beta.11
|
|
4
54
|
|
|
5
55
|
### Minor Changes
|
|
6
56
|
|
|
7
|
-
- Add
|
|
57
|
+
- Add provisions as a first-class primitive.
|
|
8
58
|
|
|
9
|
-
|
|
59
|
+
Provisions make infrastructure dependencies declarative, injectable, and governable. Define a provision with `provision()`, declare it on a trail with `provisions: [db]`, and access it with `db.from(ctx)` or `ctx.provision()`.
|
|
10
60
|
|
|
11
|
-
**Core:** `
|
|
61
|
+
**Core:** `provision()` factory, `ProvisionSpec<T>`, `ProvisionContext`, singleton resolution in `executeTrail`, in-flight creation dedup, `isProvision` guard, `findDuplicateProvisionId`, topo provision discovery and validation, `provisions` field on trail specs.
|
|
12
62
|
|
|
13
|
-
**Testing:** Auto-resolution of `mock` factories in `testAll`, `testExamples`, `testContracts`, and `
|
|
63
|
+
**Testing:** Auto-resolution of `mock` factories in `testAll`, `testExamples`, `testContracts`, and `testCrosses`. Explicit `provisions` overrides with correct precedence (`explicit > ctx.extensions > auto-mock`). Provision mock propagation through crossing graphs.
|
|
14
64
|
|
|
15
|
-
**Warden:** `
|
|
65
|
+
**Warden:** `provision-declarations` rule validates `db.from(ctx)` and `ctx.provision()` usage matches declared `provisions: [...]`. `provision-exists` rule validates declared provision IDs resolve in project context. Scope-aware AST walking skips nested function boundaries.
|
|
16
66
|
|
|
17
|
-
**
|
|
67
|
+
**Trailheads:** Provision overrides thread through `run` and `trailhead` on CLI, MCP, and HTTP.
|
|
18
68
|
|
|
19
|
-
**Introspection:** Survey and
|
|
69
|
+
**Introspection:** Survey and trailhead map outputs include provision graph. Topo exposes `.provisions`, `.getProvision()`, `.hasProvision()`, `.listProvisions()`, `.provisionIds()`, `.provisionCount`.
|
|
20
70
|
|
|
21
71
|
**Docs:** ADR-009 accepted. Unified services guide, updated vocabulary, getting-started, architecture, and package READMEs.
|
|
22
72
|
|
|
@@ -42,9 +92,9 @@
|
|
|
42
92
|
|
|
43
93
|
### Minor Changes
|
|
44
94
|
|
|
45
|
-
- Consolidated improvements across all
|
|
95
|
+
- Consolidated improvements across all trailhead packages.
|
|
46
96
|
|
|
47
|
-
**core**: Add `TrailResult<T>` utility type, `topo.ids()` and `topo.count` accessors, `
|
|
97
|
+
**core**: Add `TrailResult<T>` utility type, `topo.ids()` and `topo.count` accessors, `run()` for headless trail execution, and extract shared `executeTrail` pipeline used by CLI/MCP/HTTP.
|
|
48
98
|
|
|
49
99
|
**http**: Detect route path collisions and return `Result` from `buildHttpRoutes()`, wire request `AbortSignal` through to trail context, and make write → POST mapping explicit in intent-to-method lookup.
|
|
50
100
|
|
|
@@ -52,7 +102,7 @@
|
|
|
52
102
|
|
|
53
103
|
**cli**: Verify exception catching via centralized `executeTrail`.
|
|
54
104
|
|
|
55
|
-
**testing**:
|
|
105
|
+
**testing**: Cross-context awareness improvements.
|
|
56
106
|
|
|
57
107
|
**warden**: Refactor rules as composable trails with examples.
|
|
58
108
|
|
|
@@ -112,15 +162,15 @@
|
|
|
112
162
|
|
|
113
163
|
**BREAKING CHANGES:**
|
|
114
164
|
|
|
115
|
-
- `hike()` removed — use `trail()` with optional `
|
|
116
|
-
- `follows` renamed to `
|
|
165
|
+
- `hike()` removed — use `trail()` with optional `crosses: [...]` field
|
|
166
|
+
- `follows` renamed to `crosses` (matching `ctx.cross()`)
|
|
117
167
|
- `topo.hikes` removed — single `topo.trails` map
|
|
118
168
|
- `kind: 'hike'` removed — everything is `kind: 'trail'`
|
|
119
169
|
- `readOnly`/`destructive` booleans replaced by `intent: 'read' | 'write' | 'destroy'`
|
|
120
170
|
- `implementation` field renamed to `run`
|
|
121
171
|
- `markers` field renamed to `metadata`
|
|
122
|
-
- `testHike` renamed to `
|
|
123
|
-
- `
|
|
172
|
+
- `testHike` renamed to `testCrosses`, `HikeScenario` to `CrossScenario`
|
|
173
|
+
- `trailhead()` now returns the trailhead handle (`Command` for CLI, `Server` for MCP)
|
|
124
174
|
|
|
125
175
|
### Patch Changes
|
|
126
176
|
|
|
@@ -134,15 +184,15 @@
|
|
|
134
184
|
|
|
135
185
|
### Minor Changes
|
|
136
186
|
|
|
137
|
-
- Bug fixes across all
|
|
187
|
+
- Bug fixes across all trailhead packages found via parallel Codex review.
|
|
138
188
|
|
|
139
189
|
**core**: Fix Result.toJson false circular detection on DAGs, deserializeError subclass round-trip, topo cross-kind ID collisions, validateTopo multi-node cycle detection, error example input validation bypass, and deriveFields array type collapse.
|
|
140
190
|
|
|
141
|
-
**cli**: Switch
|
|
191
|
+
**cli**: Switch trailhead to parseAsync for proper async error handling, add boolean flag negation (--no-flag), and strict number parsing that rejects partial input.
|
|
142
192
|
|
|
143
193
|
**mcp**: Align BlobRef with core (including ReadableStream support) and detect tool-name collisions after normalization.
|
|
144
194
|
|
|
145
|
-
**testing**: Include hikes in testContracts validation, with
|
|
195
|
+
**testing**: Include hikes in testContracts validation, with cross-context awareness.
|
|
146
196
|
|
|
147
197
|
**warden**: Collect hike detour targets, validate detour refs in hike specs, and stop implementation-returns-result from walking into nested function bodies.
|
|
148
198
|
|
|
@@ -186,12 +236,12 @@
|
|
|
186
236
|
- Initial v1 beta release of the Trails framework.
|
|
187
237
|
|
|
188
238
|
- **@ontrails/core** — Result type, error taxonomy, trail/hike/event/topo, validateTopo, validateInput/Output, deriveFields, patterns, redaction, branded types, resilience
|
|
189
|
-
- **@ontrails/cli** — CLI
|
|
190
|
-
- **@ontrails/mcp** — MCP
|
|
191
|
-
- **@ontrails/logging** — Structured logging, sinks, formatters, LogTape
|
|
192
|
-
- **@ontrails/testing** — testAll, testExamples, testTrail, testHike, testContracts, testDetours,
|
|
239
|
+
- **@ontrails/cli** — CLI trailhead connector, Commander integration, flag derivation, gates
|
|
240
|
+
- **@ontrails/mcp** — MCP trailhead connector, tool generation, annotations, progress bridge
|
|
241
|
+
- **@ontrails/logging** — Structured logging, sinks, formatters, LogTape connector
|
|
242
|
+
- **@ontrails/testing** — testAll, testExamples, testTrail, testHike, testContracts, testDetours, trailhead harnesses
|
|
193
243
|
- **@ontrails/warden** — AST-based code convention rules via oxc-parser, drift detection, CI formatters
|
|
194
|
-
- **@ontrails/schema** —
|
|
244
|
+
- **@ontrails/schema** — Trailhead map generation, hashing, semantic diffing
|
|
195
245
|
|
|
196
246
|
### Patch Changes
|
|
197
247
|
|
package/README.md
CHANGED
|
@@ -29,10 +29,10 @@ testDetours(app); // Verify detour targets exist
|
|
|
29
29
|
| --- | --- |
|
|
30
30
|
| `testAll(topo, ctx?)` | Single-line governance suite: validation + examples + contracts + detours |
|
|
31
31
|
| `testExamples(topo, ctx?)` | Run trail examples as `describe`/`test` blocks |
|
|
32
|
-
| `testTrail(trail, scenarios)` | Custom scenarios for edge cases, error paths, and
|
|
32
|
+
| `testTrail(trail, scenarios)` | Custom scenarios for edge cases, error paths, and cross chains |
|
|
33
33
|
| `testContracts(topo, ctx?)` | Validate output against declared schemas |
|
|
34
34
|
| `testDetours(topo)` | Verify every detour target exists in the topo |
|
|
35
|
-
| `
|
|
35
|
+
| `createCrossContext(options?)` | Mock `CrossFn` for testing composite trails; returns preconfigured `Result` values keyed by trail ID |
|
|
36
36
|
| `createTestContext(options?)` | `TrailContext` with sensible test defaults |
|
|
37
37
|
| `createTestLogger()` | Logger that captures entries in memory for assertions |
|
|
38
38
|
| `createCliHarness(options)` | Execute CLI commands in-process, capture stdout/stderr |
|
|
@@ -55,9 +55,9 @@ testTrail(showTrail, [
|
|
|
55
55
|
]);
|
|
56
56
|
```
|
|
57
57
|
|
|
58
|
-
## Testing composition (trails with
|
|
58
|
+
## Testing composition (trails with crosses)
|
|
59
59
|
|
|
60
|
-
`testTrail` works the same for trails with `
|
|
60
|
+
`testTrail` works the same for trails with `crosses` -- it exercises the crossing graph:
|
|
61
61
|
|
|
62
62
|
```typescript
|
|
63
63
|
import { testTrail } from '@ontrails/testing';
|
|
@@ -68,25 +68,25 @@ testTrail(onboardTrail, [
|
|
|
68
68
|
]);
|
|
69
69
|
```
|
|
70
70
|
|
|
71
|
-
When you need to isolate a composite trail and stub out its dependencies, use `
|
|
71
|
+
When you need to isolate a composite trail and stub out its dependencies, use `createCrossContext`:
|
|
72
72
|
|
|
73
73
|
```typescript
|
|
74
|
-
import {
|
|
74
|
+
import { createCrossContext, createTestContext } from '@ontrails/testing';
|
|
75
75
|
import { Result } from '@ontrails/core';
|
|
76
76
|
|
|
77
|
-
const
|
|
77
|
+
const cross = createCrossContext({
|
|
78
78
|
responses: {
|
|
79
79
|
'entity.add': Result.ok({ id: '1', name: 'Delta', type: 'tool' }),
|
|
80
80
|
'search': Result.ok({ results: [] }),
|
|
81
81
|
},
|
|
82
82
|
});
|
|
83
|
-
const ctx = { ...createTestContext(),
|
|
83
|
+
const ctx = { ...createTestContext(), cross };
|
|
84
84
|
const result = await onboardTrail.run({ name: 'Delta', type: 'tool' }, ctx);
|
|
85
85
|
```
|
|
86
86
|
|
|
87
87
|
Calls to unregistered trail IDs return `Result.err` with a descriptive message, so missing stubs fail loudly.
|
|
88
88
|
|
|
89
|
-
##
|
|
89
|
+
## Trailhead harnesses
|
|
90
90
|
|
|
91
91
|
```typescript
|
|
92
92
|
import { createCliHarness, createMcpHarness } from '@ontrails/testing';
|
package/dist/context.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Test context factory for creating TrailContext instances suitable for testing.
|
|
3
3
|
*/
|
|
4
|
-
import type {
|
|
4
|
+
import type { CrossFn, ProvisionOverrideMap, Topo, TrailContext } from '@ontrails/core';
|
|
5
5
|
import { Result } from '@ontrails/core';
|
|
6
6
|
import type { TestTrailContextOptions } from './types.js';
|
|
7
7
|
/**
|
|
@@ -9,37 +9,67 @@ import type { TestTrailContextOptions } from './types.js';
|
|
|
9
9
|
*
|
|
10
10
|
* - `requestId`: `"test-request-001"` (deterministic)
|
|
11
11
|
* - `logger`: a `TestLogger` that captures entries
|
|
12
|
-
* - `
|
|
12
|
+
* - `abortSignal`: a non-aborted AbortController signal
|
|
13
13
|
*/
|
|
14
14
|
export declare const createTestContext: (overrides?: TestTrailContextOptions) => TrailContext;
|
|
15
|
-
export interface
|
|
15
|
+
export interface CreateCrossContextOptions {
|
|
16
16
|
readonly responses?: Record<string, Result<unknown, Error>> | undefined;
|
|
17
17
|
}
|
|
18
|
+
/** Minimal permit shape returned by the mint function. */
|
|
19
|
+
export interface MintedPermit {
|
|
20
|
+
readonly id: string;
|
|
21
|
+
readonly scopes: readonly string[];
|
|
22
|
+
}
|
|
23
|
+
/** Trail shape consumed by the mint function — avoids importing permits. */
|
|
24
|
+
export interface MintableTrail {
|
|
25
|
+
readonly permit?: {
|
|
26
|
+
readonly scopes: readonly string[];
|
|
27
|
+
} | 'public' | undefined;
|
|
28
|
+
}
|
|
18
29
|
export interface TestExecutionOptions {
|
|
19
30
|
readonly ctx?: Partial<TrailContext> | undefined;
|
|
20
|
-
readonly
|
|
31
|
+
readonly provisions?: ProvisionOverrideMap | undefined;
|
|
32
|
+
/**
|
|
33
|
+
* When true, disables automatic permit minting. Tests must provide
|
|
34
|
+
* explicit permits.
|
|
35
|
+
*/
|
|
36
|
+
readonly strictPermits?: boolean | undefined;
|
|
37
|
+
/**
|
|
38
|
+
* Optional function to mint a test permit for a trail. When provided,
|
|
39
|
+
* called for each trail with a non-public `permit` requirement.
|
|
40
|
+
* Returning `undefined` skips minting for that trail.
|
|
41
|
+
*
|
|
42
|
+
* A default inline implementation is used when this is not provided,
|
|
43
|
+
* keeping the testing package free of a hard dependency on `@ontrails/permits`.
|
|
44
|
+
*/
|
|
45
|
+
readonly mintPermit?: (trail: MintableTrail) => MintedPermit | undefined;
|
|
21
46
|
}
|
|
22
47
|
/**
|
|
23
|
-
* Create a mock `
|
|
48
|
+
* Create a mock `CrossFn` for testing composite trails.
|
|
24
49
|
*
|
|
25
50
|
* Returns preconfigured `Result` values keyed by trail ID. Calls to
|
|
26
51
|
* unregistered IDs return `Result.err` with a descriptive message.
|
|
27
52
|
*
|
|
28
53
|
* @example
|
|
29
54
|
* ```ts
|
|
30
|
-
* const
|
|
55
|
+
* const cross = createCrossContext({
|
|
31
56
|
* responses: { 'entity.add': Result.ok({ id: '1', name: 'Alpha' }) },
|
|
32
57
|
* });
|
|
33
|
-
* const ctx = { ...createTestContext(),
|
|
58
|
+
* const ctx = { ...createTestContext(), cross };
|
|
34
59
|
* ```
|
|
35
60
|
*/
|
|
36
|
-
export declare const
|
|
61
|
+
export declare const createCrossContext: (options?: CreateCrossContextOptions) => CrossFn;
|
|
62
|
+
/**
|
|
63
|
+
* Default permit minter — reads `trail.permit.scopes` and produces a
|
|
64
|
+
* minimal permit object. No dependency on `@ontrails/permits`.
|
|
65
|
+
*/
|
|
66
|
+
export declare const defaultMintPermit: (trail: MintableTrail) => MintedPermit | undefined;
|
|
37
67
|
export declare const normalizeTestExecutionOptions: (input?: Partial<TrailContext> | TestExecutionOptions) => TestExecutionOptions;
|
|
38
|
-
export declare const
|
|
39
|
-
export declare const
|
|
68
|
+
export declare const mergeProvisionOverrides: (autoResolved: ProvisionOverrideMap, ctx: Partial<TrailContext> | undefined, explicit: ProvisionOverrideMap | undefined) => ProvisionOverrideMap;
|
|
69
|
+
export declare const resolveMockProvisions: (app: Topo) => Promise<ProvisionOverrideMap>;
|
|
40
70
|
/**
|
|
41
71
|
* Merge a Partial<TrailContext> into a test context.
|
|
42
72
|
* Used internally when the public API accepts Partial<TrailContext>.
|
|
43
73
|
*/
|
|
44
|
-
export declare const mergeTestContext: (ctx?: Partial<TrailContext>,
|
|
74
|
+
export declare const mergeTestContext: (ctx?: Partial<TrailContext>, provisions?: ProvisionOverrideMap) => TrailContext;
|
|
45
75
|
//# sourceMappingURL=context.d.ts.map
|
package/dist/context.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,OAAO,EACP,oBAAoB,EACpB,IAAI,EACJ,YAAY,EACb,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,MAAM,EAAyB,MAAM,gBAAgB,CAAC;AAG/D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAU1D;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,GAC5B,YAAY,uBAAuB,KAClC,YAcF,CAAC;AAMF,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,GAAG,SAAS,CAAC;CACzE;AAED,0DAA0D;AAC1D,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC;AAED,4EAA4E;AAC5E,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,MAAM,CAAC,EACZ;QAAE,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAA;KAAE,GACtC,QAAQ,GACR,SAAS,CAAC;CACf;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,SAAS,CAAC;IACjD,QAAQ,CAAC,UAAU,CAAC,EAAE,oBAAoB,GAAG,SAAS,CAAC;IACvD;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7C;;;;;;;OAOG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,YAAY,GAAG,SAAS,CAAC;CAC1E;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,kBAAkB,GAC7B,UAAU,yBAAyB,KAClC,OAcF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,iBAAiB,GAC5B,OAAO,aAAa,KACnB,YAAY,GAAG,SAKjB,CAAC;AAWF,eAAO,MAAM,6BAA6B,GACxC,QAAQ,OAAO,CAAC,YAAY,CAAC,GAAG,oBAAoB,KACnD,oBACqD,CAAC;AAEzD,eAAO,MAAM,uBAAuB,GAClC,cAAc,oBAAoB,EAClC,KAAK,OAAO,CAAC,YAAY,CAAC,GAAG,SAAS,EACtC,UAAU,oBAAoB,GAAG,SAAS,KACzC,oBAID,CAAC;AAeH,eAAO,MAAM,qBAAqB,GAChC,KAAK,IAAI,KACR,OAAO,CAAC,oBAAoB,CAAmC,CAAC;AAEnE;;;GAGG;AACH,eAAO,MAAM,gBAAgB,GAC3B,MAAM,OAAO,CAAC,YAAY,CAAC,EAC3B,aAAa,oBAAoB,KAChC,YAeF,CAAC"}
|
package/dist/context.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Test context factory for creating TrailContext instances suitable for testing.
|
|
3
3
|
*/
|
|
4
|
-
import { Result,
|
|
4
|
+
import { Result, createProvisionLookup } from '@ontrails/core';
|
|
5
5
|
import { createTestLogger } from './logger.js';
|
|
6
6
|
// ---------------------------------------------------------------------------
|
|
7
7
|
// createTestContext
|
|
@@ -11,82 +11,97 @@ import { createTestLogger } from './logger.js';
|
|
|
11
11
|
*
|
|
12
12
|
* - `requestId`: `"test-request-001"` (deterministic)
|
|
13
13
|
* - `logger`: a `TestLogger` that captures entries
|
|
14
|
-
* - `
|
|
14
|
+
* - `abortSignal`: a non-aborted AbortController signal
|
|
15
15
|
*/
|
|
16
16
|
export const createTestContext = (overrides) => {
|
|
17
17
|
const cwd = overrides?.cwd ?? process.cwd();
|
|
18
18
|
const ctx = {
|
|
19
|
+
abortSignal: overrides?.abortSignal ?? new AbortController().signal,
|
|
19
20
|
cwd,
|
|
20
21
|
env: overrides?.env ?? { TRAILS_ENV: 'test' },
|
|
21
22
|
extensions: undefined,
|
|
22
23
|
logger: overrides?.logger ?? createTestLogger(),
|
|
23
24
|
requestId: overrides?.requestId ?? 'test-request-001',
|
|
24
|
-
signal: overrides?.signal ?? new AbortController().signal,
|
|
25
25
|
workspaceRoot: cwd,
|
|
26
26
|
};
|
|
27
|
-
|
|
27
|
+
const lookup = createProvisionLookup(() => ctx);
|
|
28
|
+
ctx.provision = lookup;
|
|
28
29
|
return ctx;
|
|
29
30
|
};
|
|
30
31
|
/**
|
|
31
|
-
* Create a mock `
|
|
32
|
+
* Create a mock `CrossFn` for testing composite trails.
|
|
32
33
|
*
|
|
33
34
|
* Returns preconfigured `Result` values keyed by trail ID. Calls to
|
|
34
35
|
* unregistered IDs return `Result.err` with a descriptive message.
|
|
35
36
|
*
|
|
36
37
|
* @example
|
|
37
38
|
* ```ts
|
|
38
|
-
* const
|
|
39
|
+
* const cross = createCrossContext({
|
|
39
40
|
* responses: { 'entity.add': Result.ok({ id: '1', name: 'Alpha' }) },
|
|
40
41
|
* });
|
|
41
|
-
* const ctx = { ...createTestContext(),
|
|
42
|
+
* const ctx = { ...createTestContext(), cross };
|
|
42
43
|
* ```
|
|
43
44
|
*/
|
|
44
|
-
export const
|
|
45
|
+
export const createCrossContext = (options) => {
|
|
45
46
|
const responses = options?.responses ?? {};
|
|
46
47
|
return (id, _input) => {
|
|
47
48
|
const response = responses[id];
|
|
48
49
|
if (response === undefined) {
|
|
49
|
-
return Promise.resolve(Result.err(new Error(`No mock response for
|
|
50
|
+
return Promise.resolve(Result.err(new Error(`No mock response for cross("${id}")`)));
|
|
50
51
|
}
|
|
51
52
|
return Promise.resolve(response);
|
|
52
53
|
};
|
|
53
54
|
};
|
|
55
|
+
/**
|
|
56
|
+
* Default permit minter — reads `trail.permit.scopes` and produces a
|
|
57
|
+
* minimal permit object. No dependency on `@ontrails/permits`.
|
|
58
|
+
*/
|
|
59
|
+
export const defaultMintPermit = (trail) => {
|
|
60
|
+
if (!trail.permit || trail.permit === 'public') {
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
63
|
+
return { id: 'test-permit', scopes: trail.permit.scopes };
|
|
64
|
+
};
|
|
54
65
|
const isTestExecutionOptions = (input) => input !== undefined &&
|
|
55
|
-
(Object.hasOwn(input, 'ctx') ||
|
|
66
|
+
(Object.hasOwn(input, 'ctx') ||
|
|
67
|
+
Object.hasOwn(input, 'provisions') ||
|
|
68
|
+
Object.hasOwn(input, 'strictPermits') ||
|
|
69
|
+
Object.hasOwn(input, 'mintPermit'));
|
|
56
70
|
export const normalizeTestExecutionOptions = (input) => isTestExecutionOptions(input) ? input : { ctx: input };
|
|
57
|
-
export const
|
|
71
|
+
export const mergeProvisionOverrides = (autoResolved, ctx, explicit) => ({
|
|
58
72
|
...autoResolved,
|
|
59
73
|
...ctx?.extensions,
|
|
60
74
|
...explicit,
|
|
61
75
|
});
|
|
62
|
-
const
|
|
63
|
-
const
|
|
64
|
-
for (const
|
|
65
|
-
if (!
|
|
76
|
+
const buildMockProvisions = async (app) => {
|
|
77
|
+
const provisions = {};
|
|
78
|
+
for (const declaredProvision of app.listProvisions()) {
|
|
79
|
+
if (!declaredProvision.mock) {
|
|
66
80
|
continue;
|
|
67
81
|
}
|
|
68
|
-
|
|
82
|
+
provisions[declaredProvision.id] = await declaredProvision.mock();
|
|
69
83
|
}
|
|
70
|
-
return
|
|
84
|
+
return provisions;
|
|
71
85
|
};
|
|
72
|
-
export const
|
|
86
|
+
export const resolveMockProvisions = async (app) => await buildMockProvisions(app);
|
|
73
87
|
/**
|
|
74
88
|
* Merge a Partial<TrailContext> into a test context.
|
|
75
89
|
* Used internally when the public API accepts Partial<TrailContext>.
|
|
76
90
|
*/
|
|
77
|
-
export const mergeTestContext = (ctx,
|
|
91
|
+
export const mergeTestContext = (ctx, provisions) => {
|
|
78
92
|
const base = createTestContext();
|
|
79
93
|
const extensions = {
|
|
80
94
|
...base.extensions,
|
|
81
95
|
...ctx?.extensions,
|
|
82
|
-
...
|
|
96
|
+
...provisions,
|
|
83
97
|
};
|
|
84
98
|
const merged = {
|
|
85
99
|
...base,
|
|
86
100
|
...ctx,
|
|
87
101
|
extensions: Object.keys(extensions).length === 0 ? undefined : extensions,
|
|
88
102
|
};
|
|
89
|
-
|
|
103
|
+
const lookup = createProvisionLookup(() => merged);
|
|
104
|
+
merged.provision = lookup;
|
|
90
105
|
return merged;
|
|
91
106
|
};
|
|
92
107
|
//# sourceMappingURL=context.js.map
|
package/dist/context.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH,OAAO,EAAE,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"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"}
|
package/dist/contracts.js
CHANGED
|
@@ -8,17 +8,17 @@
|
|
|
8
8
|
import { describe, test } from 'bun:test';
|
|
9
9
|
import { executeTrail, formatZodIssues, validateInput } from '@ontrails/core';
|
|
10
10
|
import { expectOk } from './assertions.js';
|
|
11
|
-
import {
|
|
11
|
+
import { mergeProvisionOverrides, mergeTestContext, normalizeTestExecutionOptions, resolveMockProvisions, } from './context.js';
|
|
12
12
|
// ---------------------------------------------------------------------------
|
|
13
13
|
// Helpers
|
|
14
14
|
// ---------------------------------------------------------------------------
|
|
15
|
-
/** Check if a trail requires
|
|
16
|
-
const
|
|
15
|
+
/** Check if a trail requires cross() but the context doesn't provide it. */
|
|
16
|
+
const needsCrossContext = (t, resolveCtx) => {
|
|
17
17
|
const spec = t;
|
|
18
|
-
if (!spec.
|
|
18
|
+
if (!spec.crosses || spec.crosses.length === 0) {
|
|
19
19
|
return false;
|
|
20
20
|
}
|
|
21
|
-
return !normalizeTestExecutionOptions(resolveCtx()).ctx?.
|
|
21
|
+
return !normalizeTestExecutionOptions(resolveCtx()).ctx?.cross;
|
|
22
22
|
};
|
|
23
23
|
const validateOutputSchema = (outputSchema, value, trailId, exampleName) => {
|
|
24
24
|
const parsed = outputSchema.safeParse(value);
|
|
@@ -47,20 +47,20 @@ export const testContracts = (app, ctxOrFactory) => {
|
|
|
47
47
|
if (t.examples === undefined || t.examples.length === 0) {
|
|
48
48
|
return;
|
|
49
49
|
}
|
|
50
|
-
if (
|
|
50
|
+
if (needsCrossContext(t, resolveInput)) {
|
|
51
51
|
return;
|
|
52
52
|
}
|
|
53
53
|
const { examples, output: outputSchema } = t;
|
|
54
54
|
const successExamples = examples.filter((e) => e.error === undefined);
|
|
55
55
|
test.each(successExamples)('contract: $name', async (example) => {
|
|
56
56
|
const resolved = normalizeTestExecutionOptions(resolveInput());
|
|
57
|
-
const
|
|
57
|
+
const provisions = mergeProvisionOverrides(await resolveMockProvisions(app), resolved.ctx, resolved.provisions);
|
|
58
58
|
const testCtx = mergeTestContext(resolved.ctx);
|
|
59
59
|
const validated = validateInput(t.input, example.input);
|
|
60
60
|
expectOk(validated);
|
|
61
61
|
const result = await executeTrail(t, example.input, {
|
|
62
62
|
ctx: testCtx,
|
|
63
|
-
|
|
63
|
+
provisions,
|
|
64
64
|
});
|
|
65
65
|
const resultValue = expectOk(result);
|
|
66
66
|
validateOutputSchema(outputSchema, resultValue, t.id, example.name);
|
package/dist/contracts.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contracts.js","sourceRoot":"","sources":["../src/contracts.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAG1C,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAG9E,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"contracts.js","sourceRoot":"","sources":["../src/contracts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* testCrosses — crossing-aware scenario testing for trails with crossings.
|
|
3
|
+
*
|
|
4
|
+
* Tests the crossing graph: which trails were crossed, in what order,
|
|
5
|
+
* and supports failure injection from crossed trail examples.
|
|
6
|
+
*/
|
|
7
|
+
import type { AnyTrail, ProvisionOverrideMap, TrailContext } from '@ontrails/core';
|
|
8
|
+
import type { CrossScenario } from './types.js';
|
|
9
|
+
/** Options for testCrosses that provide trail definitions for injection. */
|
|
10
|
+
export interface TestCrossOptions {
|
|
11
|
+
/** Partial context overrides. */
|
|
12
|
+
readonly ctx?: Partial<TrailContext> | undefined;
|
|
13
|
+
/**
|
|
14
|
+
* Explicit provision overrides merged on top of auto-resolved mocks for every
|
|
15
|
+
* scenario. Values are passed by reference — provide immutable objects, or
|
|
16
|
+
* use `mock()` on the provision definition to get a fresh instance per run.
|
|
17
|
+
*/
|
|
18
|
+
readonly provisions?: ProvisionOverrideMap | undefined;
|
|
19
|
+
/** Map of trail ID to trail definition, used for injectFromExample. */
|
|
20
|
+
readonly trails?: ReadonlyMap<string, AnyTrail> | undefined;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Generate a describe block for a trail with crossings with one test per scenario.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```ts
|
|
27
|
+
* testCrosses(onboardTrail, [
|
|
28
|
+
* {
|
|
29
|
+
* description: "crosses add then relate",
|
|
30
|
+
* input: { name: "Alpha" },
|
|
31
|
+
* expectOk: true,
|
|
32
|
+
* expectCrossed: ["entity.add", "entity.relate"],
|
|
33
|
+
* },
|
|
34
|
+
* ]);
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export declare const testCrosses: (trailDef: AnyTrail, scenarios: readonly CrossScenario[], options?: TestCrossOptions) => void;
|
|
38
|
+
//# sourceMappingURL=crosses.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crosses.d.ts","sourceRoot":"","sources":["../src/crosses.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EACV,QAAQ,EAER,oBAAoB,EACpB,YAAY,EACb,MAAM,gBAAgB,CAAC;AAexB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AA0ShD,4EAA4E;AAC5E,MAAM,WAAW,gBAAgB;IAC/B,iCAAiC;IACjC,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,SAAS,CAAC;IACjD;;;;OAIG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,oBAAoB,GAAG,SAAS,CAAC;IACvD,uEAAuE;IACvE,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,SAAS,CAAC;CAC7D;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,WAAW,GACtB,UAAU,QAAQ,EAClB,WAAW,SAAS,aAAa,EAAE,EACnC,UAAU,gBAAgB,KACzB,IAsBF,CAAC"}
|