@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.
Files changed (45) hide show
  1. package/.turbo/turbo-lint.log +1 -1
  2. package/CHANGELOG.md +72 -22
  3. package/README.md +9 -9
  4. package/dist/context.d.ts +41 -11
  5. package/dist/context.d.ts.map +1 -1
  6. package/dist/context.js +36 -21
  7. package/dist/context.js.map +1 -1
  8. package/dist/contracts.js +8 -8
  9. package/dist/contracts.js.map +1 -1
  10. package/dist/crosses.d.ts +38 -0
  11. package/dist/crosses.d.ts.map +1 -0
  12. package/dist/crosses.js +213 -0
  13. package/dist/crosses.js.map +1 -0
  14. package/dist/examples.d.ts +4 -4
  15. package/dist/examples.d.ts.map +1 -1
  16. package/dist/examples.js +52 -32
  17. package/dist/examples.js.map +1 -1
  18. package/dist/harness-mcp.d.ts +1 -1
  19. package/dist/harness-mcp.js +2 -2
  20. package/dist/harness-mcp.js.map +1 -1
  21. package/dist/index.d.ts +6 -6
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +3 -3
  24. package/dist/index.js.map +1 -1
  25. package/dist/trail.js +1 -1
  26. package/dist/trail.js.map +1 -1
  27. package/dist/types.d.ts +8 -8
  28. package/dist/types.d.ts.map +1 -1
  29. package/package.json +5 -5
  30. package/src/__tests__/all.test.ts +20 -18
  31. package/src/__tests__/context.test.ts +27 -27
  32. package/src/__tests__/contracts.test.ts +29 -29
  33. package/src/__tests__/{follows.test.ts → crosses.test.ts} +193 -195
  34. package/src/__tests__/detours.test.ts +3 -3
  35. package/src/__tests__/examples.test.ts +221 -126
  36. package/src/__tests__/trail.test.ts +4 -4
  37. package/src/context.ts +80 -32
  38. package/src/contracts.ts +12 -12
  39. package/src/{follows.ts → crosses.ts} +97 -92
  40. package/src/examples.ts +76 -46
  41. package/src/harness-mcp.ts +2 -2
  42. package/src/index.ts +15 -7
  43. package/src/trail.ts +1 -1
  44. package/src/types.ts +9 -9
  45. package/tsconfig.tsbuildinfo +1 -1
@@ -1,3 +1,3 @@
1
1
  $ oxlint ./src
2
2
  Found 0 warnings and 0 errors.
3
- Finished in 71ms on 21 files with 93 rules using 24 threads.
3
+ Finished in 55ms on 21 files with 93 rules using 24 threads.
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 services as a first-class primitive.
57
+ - Add provisions as a first-class primitive.
8
58
 
9
- Services make infrastructure dependencies declarative, injectable, and governable. Define a service with `service()`, declare it on a trail with `services: [db]`, and access it with `db.from(ctx)` or `ctx.service()`.
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:** `service()` factory, `ServiceSpec<T>`, `ServiceContext`, singleton resolution in `executeTrail`, in-flight creation dedup, `isService` guard, `findDuplicateServiceId`, topo service discovery and validation, `services` field on trail specs.
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 `testFollows`. Explicit `services` overrides with correct precedence (`explicit > ctx.extensions > auto-mock`). Service mock propagation through follow graphs.
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:** `service-declarations` rule validates `db.from(ctx)` and `ctx.service()` usage matches declared `services: [...]`. `service-exists` rule validates declared service IDs resolve in project context. Scope-aware AST walking skips nested function boundaries.
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
- **Surfaces:** Service overrides thread through `dispatch` and `blaze` on CLI, MCP, and HTTP.
67
+ **Trailheads:** Provision overrides thread through `run` and `trailhead` on CLI, MCP, and HTTP.
18
68
 
19
- **Introspection:** Survey and surface map outputs include service graph. Topo exposes `.services`, `.getService()`, `.hasService()`, `.listServices()`, `.serviceIds()`, `.serviceCount`.
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 surface packages.
95
+ - Consolidated improvements across all trailhead packages.
46
96
 
47
- **core**: Add `TrailResult<T>` utility type, `topo.ids()` and `topo.count` accessors, `dispatch()` for headless trail execution, and extract shared `executeTrail` pipeline used by CLI/MCP/HTTP.
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**: Follow context awareness improvements.
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 `follow: [...]` field
116
- - `follows` renamed to `follow` (singular, matching `ctx.follow()`)
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 `testFollows`, `HikeScenario` to `FollowScenario`
123
- - `blaze()` now returns the surface handle (`Command` for CLI, `Server` for MCP)
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 surface packages found via parallel Codex review.
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 blaze to parseAsync for proper async error handling, add boolean flag negation (--no-flag), and strict number parsing that rejects partial input.
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 follow-context awareness.
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 surface adapter, Commander integration, flag derivation, layers
190
- - **@ontrails/mcp** — MCP surface adapter, tool generation, annotations, progress bridge
191
- - **@ontrails/logging** — Structured logging, sinks, formatters, LogTape adapter
192
- - **@ontrails/testing** — testAll, testExamples, testTrail, testHike, testContracts, testDetours, surface harnesses
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** — Surface map generation, hashing, semantic diffing
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 follow chains |
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
- | `createFollowContext(options?)` | Mock `FollowFn` for testing composite trails; returns preconfigured `Result` values keyed by trail ID |
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 follow)
58
+ ## Testing composition (trails with crosses)
59
59
 
60
- `testTrail` works the same for trails with `follow` -- it exercises the follow graph:
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 `createFollowContext`:
71
+ When you need to isolate a composite trail and stub out its dependencies, use `createCrossContext`:
72
72
 
73
73
  ```typescript
74
- import { createFollowContext, createTestContext } from '@ontrails/testing';
74
+ import { createCrossContext, createTestContext } from '@ontrails/testing';
75
75
  import { Result } from '@ontrails/core';
76
76
 
77
- const follow = createFollowContext({
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(), follow };
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
- ## Surface harnesses
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 { FollowFn, ServiceOverrideMap, Topo, TrailContext } from '@ontrails/core';
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
- * - `signal`: a non-aborted AbortController signal
12
+ * - `abortSignal`: a non-aborted AbortController signal
13
13
  */
14
14
  export declare const createTestContext: (overrides?: TestTrailContextOptions) => TrailContext;
15
- export interface CreateFollowContextOptions {
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 services?: ServiceOverrideMap | undefined;
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 `FollowFn` for testing composite trails.
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 follow = createFollowContext({
55
+ * const cross = createCrossContext({
31
56
  * responses: { 'entity.add': Result.ok({ id: '1', name: 'Alpha' }) },
32
57
  * });
33
- * const ctx = { ...createTestContext(), follow };
58
+ * const ctx = { ...createTestContext(), cross };
34
59
  * ```
35
60
  */
36
- export declare const createFollowContext: (options?: CreateFollowContextOptions) => FollowFn;
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 mergeServiceOverrides: (autoResolved: ServiceOverrideMap, ctx: Partial<TrailContext> | undefined, explicit: ServiceOverrideMap | undefined) => ServiceOverrideMap;
39
- export declare const resolveMockServices: (app: Topo) => Promise<ServiceOverrideMap>;
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>, services?: ServiceOverrideMap) => TrailContext;
74
+ export declare const mergeTestContext: (ctx?: Partial<TrailContext>, provisions?: ProvisionOverrideMap) => TrailContext;
45
75
  //# sourceMappingURL=context.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,QAAQ,EACR,kBAAkB,EAClB,IAAI,EACJ,YAAY,EACb,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,MAAM,EAAuB,MAAM,gBAAgB,CAAC;AAG7D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAU1D;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,GAC5B,YAAY,uBAAuB,KAClC,YAaF,CAAC;AAMF,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,GAAG,SAAS,CAAC;CACzE;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,SAAS,CAAC;IACjD,QAAQ,CAAC,QAAQ,CAAC,EAAE,kBAAkB,GAAG,SAAS,CAAC;CACpD;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,mBAAmB,GAC9B,UAAU,0BAA0B,KACnC,QAcF,CAAC;AAQF,eAAO,MAAM,6BAA6B,GACxC,QAAQ,OAAO,CAAC,YAAY,CAAC,GAAG,oBAAoB,KACnD,oBACqD,CAAC;AAEzD,eAAO,MAAM,qBAAqB,GAChC,cAAc,kBAAkB,EAChC,KAAK,OAAO,CAAC,YAAY,CAAC,GAAG,SAAS,EACtC,UAAU,kBAAkB,GAAG,SAAS,KACvC,kBAID,CAAC;AAaH,eAAO,MAAM,mBAAmB,GAC9B,KAAK,IAAI,KACR,OAAO,CAAC,kBAAkB,CAAiC,CAAC;AAE/D;;;GAGG;AACH,eAAO,MAAM,gBAAgB,GAC3B,MAAM,OAAO,CAAC,YAAY,CAAC,EAC3B,WAAW,kBAAkB,KAC5B,YAcF,CAAC"}
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, createServiceLookup } from '@ontrails/core';
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
- * - `signal`: a non-aborted AbortController signal
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
- ctx.service = createServiceLookup(() => ctx);
27
+ const lookup = createProvisionLookup(() => ctx);
28
+ ctx.provision = lookup;
28
29
  return ctx;
29
30
  };
30
31
  /**
31
- * Create a mock `FollowFn` for testing composite trails.
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 follow = createFollowContext({
39
+ * const cross = createCrossContext({
39
40
  * responses: { 'entity.add': Result.ok({ id: '1', name: 'Alpha' }) },
40
41
  * });
41
- * const ctx = { ...createTestContext(), follow };
42
+ * const ctx = { ...createTestContext(), cross };
42
43
  * ```
43
44
  */
44
- export const createFollowContext = (options) => {
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 follow("${id}")`)));
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') || Object.hasOwn(input, 'services'));
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 mergeServiceOverrides = (autoResolved, ctx, explicit) => ({
71
+ export const mergeProvisionOverrides = (autoResolved, ctx, explicit) => ({
58
72
  ...autoResolved,
59
73
  ...ctx?.extensions,
60
74
  ...explicit,
61
75
  });
62
- const buildMockServices = async (app) => {
63
- const services = {};
64
- for (const declaredService of app.listServices()) {
65
- if (!declaredService.mock) {
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
- services[declaredService.id] = await declaredService.mock();
82
+ provisions[declaredProvision.id] = await declaredProvision.mock();
69
83
  }
70
- return services;
84
+ return provisions;
71
85
  };
72
- export const resolveMockServices = async (app) => await buildMockServices(app);
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, services) => {
91
+ export const mergeTestContext = (ctx, provisions) => {
78
92
  const base = createTestContext();
79
93
  const extensions = {
80
94
  ...base.extensions,
81
95
  ...ctx?.extensions,
82
- ...services,
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
- merged.service = createServiceLookup(() => merged);
103
+ const lookup = createProvisionLookup(() => merged);
104
+ merged.provision = lookup;
90
105
  return merged;
91
106
  };
92
107
  //# sourceMappingURL=context.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"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"}
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 { mergeServiceOverrides, mergeTestContext, normalizeTestExecutionOptions, resolveMockServices, } from './context.js';
11
+ import { mergeProvisionOverrides, mergeTestContext, normalizeTestExecutionOptions, resolveMockProvisions, } from './context.js';
12
12
  // ---------------------------------------------------------------------------
13
13
  // Helpers
14
14
  // ---------------------------------------------------------------------------
15
- /** Check if a trail requires follow() but the context doesn't provide it. */
16
- const needsFollowContext = (t, resolveCtx) => {
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.follow || spec.follow.length === 0) {
18
+ if (!spec.crosses || spec.crosses.length === 0) {
19
19
  return false;
20
20
  }
21
- return !normalizeTestExecutionOptions(resolveCtx()).ctx?.follow;
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 (needsFollowContext(t, resolveInput)) {
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 services = mergeServiceOverrides(await resolveMockServices(app), resolved.ctx, resolved.services);
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
- services,
63
+ provisions,
64
64
  });
65
65
  const resultValue = expectOk(result);
66
66
  validateOutputSchema(outputSchema, resultValue, t.id, example.name);
@@ -1 +1 @@
1
- {"version":3,"file":"contracts.js","sourceRoot":"","sources":["../src/contracts.ts"],"names":[],"mappings":"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"}
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"}