@ontrails/testing 1.0.0-beta.1 → 1.0.0-beta.11
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 +166 -0
- package/README.md +25 -7
- package/dist/all.d.ts +2 -1
- package/dist/all.d.ts.map +1 -1
- package/dist/all.js.map +1 -1
- package/dist/context.d.ts +28 -2
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +70 -11
- package/dist/context.js.map +1 -1
- package/dist/contracts.d.ts +3 -2
- package/dist/contracts.d.ts.map +1 -1
- package/dist/contracts.js +25 -10
- package/dist/contracts.js.map +1 -1
- package/dist/examples.d.ts +4 -3
- package/dist/examples.d.ts.map +1 -1
- package/dist/examples.js +63 -68
- package/dist/examples.js.map +1 -1
- package/dist/follows.d.ts +38 -0
- package/dist/follows.d.ts.map +1 -0
- package/dist/{hike.js → follows.js} +71 -28
- package/dist/follows.js.map +1 -0
- package/dist/harness-mcp.d.ts.map +1 -1
- package/dist/harness-mcp.js +5 -2
- package/dist/harness-mcp.js.map +1 -1
- package/dist/index.d.ts +6 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- 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 +2 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +6 -6
- package/src/__tests__/all.test.ts +64 -0
- package/src/__tests__/context.test.ts +92 -2
- package/src/__tests__/contracts.test.ts +122 -5
- package/src/__tests__/detours.test.ts +3 -3
- package/src/__tests__/examples.test.ts +285 -22
- package/src/__tests__/follows.test.ts +589 -0
- package/src/__tests__/trail.test.ts +4 -4
- package/src/all.ts +5 -1
- package/src/context.ts +121 -13
- package/src/contracts.ts +43 -12
- package/src/examples.ts +111 -105
- package/src/{hike.ts → follows.ts} +138 -43
- package/src/harness-mcp.ts +5 -2
- package/src/index.ts +6 -4
- package/src/trail.ts +1 -1
- package/src/types.ts +3 -3
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/hike.d.ts +0 -32
- package/dist/hike.d.ts.map +0 -1
- package/dist/hike.js.map +0 -1
- package/src/__tests__/hike.test.ts +0 -164
package/.turbo/turbo-lint.log
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,171 @@
|
|
|
1
1
|
# @ontrails/testing
|
|
2
2
|
|
|
3
|
+
## 1.0.0-beta.11
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Add services as a first-class primitive.
|
|
8
|
+
|
|
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()`.
|
|
10
|
+
|
|
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.
|
|
12
|
+
|
|
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.
|
|
14
|
+
|
|
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.
|
|
16
|
+
|
|
17
|
+
**Surfaces:** Service overrides thread through `dispatch` and `blaze` on CLI, MCP, and HTTP.
|
|
18
|
+
|
|
19
|
+
**Introspection:** Survey and surface map outputs include service graph. Topo exposes `.services`, `.getService()`, `.hasService()`, `.listServices()`, `.serviceIds()`, `.serviceCount`.
|
|
20
|
+
|
|
21
|
+
**Docs:** ADR-009 accepted. Unified services guide, updated vocabulary, getting-started, architecture, and package READMEs.
|
|
22
|
+
|
|
23
|
+
### Patch Changes
|
|
24
|
+
|
|
25
|
+
- Updated dependencies
|
|
26
|
+
- @ontrails/core@1.0.0-beta.11
|
|
27
|
+
- @ontrails/cli@1.0.0-beta.11
|
|
28
|
+
- @ontrails/mcp@1.0.0-beta.11
|
|
29
|
+
- @ontrails/logging@1.0.0-beta.11
|
|
30
|
+
|
|
31
|
+
## 1.0.0-beta.10
|
|
32
|
+
|
|
33
|
+
### Patch Changes
|
|
34
|
+
|
|
35
|
+
- Updated dependencies
|
|
36
|
+
- @ontrails/core@1.0.0-beta.10
|
|
37
|
+
- @ontrails/cli@1.0.0-beta.10
|
|
38
|
+
- @ontrails/mcp@1.0.0-beta.10
|
|
39
|
+
- @ontrails/logging@1.0.0-beta.10
|
|
40
|
+
|
|
41
|
+
## 1.0.0-beta.9
|
|
42
|
+
|
|
43
|
+
### Minor Changes
|
|
44
|
+
|
|
45
|
+
- Consolidated improvements across all surface packages.
|
|
46
|
+
|
|
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.
|
|
48
|
+
|
|
49
|
+
**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
|
+
|
|
51
|
+
**mcp**: Return `Result` from `buildMcpTools()` on collision instead of throwing.
|
|
52
|
+
|
|
53
|
+
**cli**: Verify exception catching via centralized `executeTrail`.
|
|
54
|
+
|
|
55
|
+
**testing**: Follow context awareness improvements.
|
|
56
|
+
|
|
57
|
+
**warden**: Refactor rules as composable trails with examples.
|
|
58
|
+
|
|
59
|
+
**schema**: Error code and empty body fixes.
|
|
60
|
+
|
|
61
|
+
### Patch Changes
|
|
62
|
+
|
|
63
|
+
- Updated dependencies
|
|
64
|
+
- @ontrails/core@1.0.0-beta.9
|
|
65
|
+
- @ontrails/cli@1.0.0-beta.9
|
|
66
|
+
- @ontrails/mcp@1.0.0-beta.9
|
|
67
|
+
- @ontrails/logging@1.0.0-beta.9
|
|
68
|
+
|
|
69
|
+
## 1.0.0-beta.8
|
|
70
|
+
|
|
71
|
+
### Patch Changes
|
|
72
|
+
|
|
73
|
+
- @ontrails/cli@1.0.0-beta.8
|
|
74
|
+
- @ontrails/core@1.0.0-beta.8
|
|
75
|
+
- @ontrails/logging@1.0.0-beta.8
|
|
76
|
+
- @ontrails/mcp@1.0.0-beta.8
|
|
77
|
+
|
|
78
|
+
## 1.0.0-beta.7
|
|
79
|
+
|
|
80
|
+
### Patch Changes
|
|
81
|
+
|
|
82
|
+
- @ontrails/cli@1.0.0-beta.7
|
|
83
|
+
- @ontrails/core@1.0.0-beta.7
|
|
84
|
+
- @ontrails/logging@1.0.0-beta.7
|
|
85
|
+
- @ontrails/mcp@1.0.0-beta.7
|
|
86
|
+
|
|
87
|
+
## 1.0.0-beta.6
|
|
88
|
+
|
|
89
|
+
### Patch Changes
|
|
90
|
+
|
|
91
|
+
- Updated dependencies
|
|
92
|
+
- @ontrails/core@1.0.0-beta.6
|
|
93
|
+
- @ontrails/cli@1.0.0-beta.6
|
|
94
|
+
- @ontrails/logging@1.0.0-beta.6
|
|
95
|
+
- @ontrails/mcp@1.0.0-beta.6
|
|
96
|
+
|
|
97
|
+
## 1.0.0-beta.5
|
|
98
|
+
|
|
99
|
+
### Patch Changes
|
|
100
|
+
|
|
101
|
+
- Updated dependencies
|
|
102
|
+
- @ontrails/core@1.0.0-beta.5
|
|
103
|
+
- @ontrails/logging@1.0.0-beta.5
|
|
104
|
+
- @ontrails/cli@1.0.0-beta.5
|
|
105
|
+
- @ontrails/mcp@1.0.0-beta.5
|
|
106
|
+
|
|
107
|
+
## 1.0.0-beta.4
|
|
108
|
+
|
|
109
|
+
### Major Changes
|
|
110
|
+
|
|
111
|
+
- API simplification: unified trail model, intent enum, run, metadata.
|
|
112
|
+
|
|
113
|
+
**BREAKING CHANGES:**
|
|
114
|
+
|
|
115
|
+
- `hike()` removed — use `trail()` with optional `follow: [...]` field
|
|
116
|
+
- `follows` renamed to `follow` (singular, matching `ctx.follow()`)
|
|
117
|
+
- `topo.hikes` removed — single `topo.trails` map
|
|
118
|
+
- `kind: 'hike'` removed — everything is `kind: 'trail'`
|
|
119
|
+
- `readOnly`/`destructive` booleans replaced by `intent: 'read' | 'write' | 'destroy'`
|
|
120
|
+
- `implementation` field renamed to `run`
|
|
121
|
+
- `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)
|
|
124
|
+
|
|
125
|
+
### Patch Changes
|
|
126
|
+
|
|
127
|
+
- Updated dependencies
|
|
128
|
+
- @ontrails/core@1.0.0-beta.4
|
|
129
|
+
- @ontrails/cli@1.0.0-beta.4
|
|
130
|
+
- @ontrails/mcp@1.0.0-beta.4
|
|
131
|
+
- @ontrails/logging@1.0.0-beta.4
|
|
132
|
+
|
|
133
|
+
## 1.0.0-beta.3
|
|
134
|
+
|
|
135
|
+
### Minor Changes
|
|
136
|
+
|
|
137
|
+
- Bug fixes across all surface packages found via parallel Codex review.
|
|
138
|
+
|
|
139
|
+
**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
|
+
|
|
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.
|
|
142
|
+
|
|
143
|
+
**mcp**: Align BlobRef with core (including ReadableStream support) and detect tool-name collisions after normalization.
|
|
144
|
+
|
|
145
|
+
**testing**: Include hikes in testContracts validation, with follow-context awareness.
|
|
146
|
+
|
|
147
|
+
**warden**: Collect hike detour targets, validate detour refs in hike specs, and stop implementation-returns-result from walking into nested function bodies.
|
|
148
|
+
|
|
149
|
+
### Patch Changes
|
|
150
|
+
|
|
151
|
+
- Updated dependencies
|
|
152
|
+
- @ontrails/core@1.0.0-beta.3
|
|
153
|
+
- @ontrails/cli@1.0.0-beta.3
|
|
154
|
+
- @ontrails/mcp@1.0.0-beta.3
|
|
155
|
+
- @ontrails/logging@1.0.0-beta.3
|
|
156
|
+
|
|
157
|
+
## 1.0.0-beta.2
|
|
158
|
+
|
|
159
|
+
### Patch Changes
|
|
160
|
+
|
|
161
|
+
- Fix workspace dependency resolution in published packages. Now using bun publish
|
|
162
|
+
which correctly replaces workspace:^ with actual version numbers.
|
|
163
|
+
- Updated dependencies
|
|
164
|
+
- @ontrails/core@1.0.0-beta.2
|
|
165
|
+
- @ontrails/cli@1.0.0-beta.2
|
|
166
|
+
- @ontrails/mcp@1.0.0-beta.2
|
|
167
|
+
- @ontrails/logging@1.0.0-beta.2
|
|
168
|
+
|
|
3
169
|
## 1.0.0-beta.1
|
|
4
170
|
|
|
5
171
|
### Patch Changes
|
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
|
|
33
|
-
| `
|
|
34
|
-
| `testContracts(topo, ctx?)` | Validate implementation output against declared schemas |
|
|
32
|
+
| `testTrail(trail, scenarios)` | Custom scenarios for edge cases, error paths, and follow chains |
|
|
33
|
+
| `testContracts(topo, ctx?)` | Validate output against declared schemas |
|
|
35
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 |
|
|
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,19 +55,37 @@ testTrail(showTrail, [
|
|
|
55
55
|
]);
|
|
56
56
|
```
|
|
57
57
|
|
|
58
|
-
##
|
|
58
|
+
## Testing composition (trails with follow)
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
`testTrail` works the same for trails with `follow` -- it exercises the follow graph:
|
|
61
61
|
|
|
62
62
|
```typescript
|
|
63
|
-
import {
|
|
63
|
+
import { testTrail } from '@ontrails/testing';
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
testTrail(onboardTrail, [
|
|
66
66
|
{ description: 'happy path', input: { name: 'Delta', type: 'tool' }, expectOk: true },
|
|
67
67
|
{ description: 'add fails', input: { name: 'Alpha' }, expectErr: AlreadyExistsError },
|
|
68
68
|
]);
|
|
69
69
|
```
|
|
70
70
|
|
|
71
|
+
When you need to isolate a composite trail and stub out its dependencies, use `createFollowContext`:
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
import { createFollowContext, createTestContext } from '@ontrails/testing';
|
|
75
|
+
import { Result } from '@ontrails/core';
|
|
76
|
+
|
|
77
|
+
const follow = createFollowContext({
|
|
78
|
+
responses: {
|
|
79
|
+
'entity.add': Result.ok({ id: '1', name: 'Delta', type: 'tool' }),
|
|
80
|
+
'search': Result.ok({ results: [] }),
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
const ctx = { ...createTestContext(), follow };
|
|
84
|
+
const result = await onboardTrail.run({ name: 'Delta', type: 'tool' }, ctx);
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Calls to unregistered trail IDs return `Result.err` with a descriptive message, so missing stubs fail loudly.
|
|
88
|
+
|
|
71
89
|
## Surface harnesses
|
|
72
90
|
|
|
73
91
|
```typescript
|
package/dist/all.d.ts
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* verification into one describe block.
|
|
6
6
|
*/
|
|
7
7
|
import type { Topo, TrailContext } from '@ontrails/core';
|
|
8
|
+
import type { TestExecutionOptions } from './context.js';
|
|
8
9
|
/**
|
|
9
10
|
* Run the full governance test suite for a Topo.
|
|
10
11
|
*
|
|
@@ -26,5 +27,5 @@ import type { Topo, TrailContext } from '@ontrails/core';
|
|
|
26
27
|
* testAll(app);
|
|
27
28
|
* ```
|
|
28
29
|
*/
|
|
29
|
-
export declare const testAll: (topo: Topo, ctxOrFactory?: Partial<TrailContext> | (() => Partial<TrailContext>)) => void;
|
|
30
|
+
export declare const testAll: (topo: Topo, ctxOrFactory?: Partial<TrailContext> | TestExecutionOptions | (() => Partial<TrailContext> | TestExecutionOptions)) => void;
|
|
30
31
|
//# sourceMappingURL=all.d.ts.map
|
package/dist/all.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"all.d.ts","sourceRoot":"","sources":["../src/all.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"all.d.ts","sourceRoot":"","sources":["../src/all.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAIzD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAIzD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,OAAO,GAClB,MAAM,IAAI,EACV,eACI,OAAO,CAAC,YAAY,CAAC,GACrB,oBAAoB,GACpB,CAAC,MAAM,OAAO,CAAC,YAAY,CAAC,GAAG,oBAAoB,CAAC,KACvD,IAcF,CAAC"}
|
package/dist/all.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"all.js","sourceRoot":"","sources":["../src/all.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAGlD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"all.js","sourceRoot":"","sources":["../src/all.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAGlD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CACrB,IAAU,EACV,YAGwD,EAClD,EAAE;IACR,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;QAC1B,IAAI,CAAC,gBAAgB,EAAE,GAAG,EAAE;YAC1B,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;YAClC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;QAEH,oGAAoG;QACpG,YAAY,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;QACjC,oGAAoG;QACpG,aAAa,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;QAClC,oGAAoG;QACpG,WAAW,CAAC,IAAI,CAAC,CAAC;IACpB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC"}
|
package/dist/context.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Test context factory for creating TrailContext instances suitable for testing.
|
|
3
3
|
*/
|
|
4
|
-
import type { TrailContext } from '@ontrails/core';
|
|
4
|
+
import type { FollowFn, ServiceOverrideMap, Topo, TrailContext } from '@ontrails/core';
|
|
5
|
+
import { Result } from '@ontrails/core';
|
|
5
6
|
import type { TestTrailContextOptions } from './types.js';
|
|
6
7
|
/**
|
|
7
8
|
* Create a TrailContext with deterministic, test-friendly defaults.
|
|
@@ -11,9 +12,34 @@ import type { TestTrailContextOptions } from './types.js';
|
|
|
11
12
|
* - `signal`: a non-aborted AbortController signal
|
|
12
13
|
*/
|
|
13
14
|
export declare const createTestContext: (overrides?: TestTrailContextOptions) => TrailContext;
|
|
15
|
+
export interface CreateFollowContextOptions {
|
|
16
|
+
readonly responses?: Record<string, Result<unknown, Error>> | undefined;
|
|
17
|
+
}
|
|
18
|
+
export interface TestExecutionOptions {
|
|
19
|
+
readonly ctx?: Partial<TrailContext> | undefined;
|
|
20
|
+
readonly services?: ServiceOverrideMap | undefined;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Create a mock `FollowFn` for testing composite trails.
|
|
24
|
+
*
|
|
25
|
+
* Returns preconfigured `Result` values keyed by trail ID. Calls to
|
|
26
|
+
* unregistered IDs return `Result.err` with a descriptive message.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```ts
|
|
30
|
+
* const follow = createFollowContext({
|
|
31
|
+
* responses: { 'entity.add': Result.ok({ id: '1', name: 'Alpha' }) },
|
|
32
|
+
* });
|
|
33
|
+
* const ctx = { ...createTestContext(), follow };
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export declare const createFollowContext: (options?: CreateFollowContextOptions) => FollowFn;
|
|
37
|
+
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>;
|
|
14
40
|
/**
|
|
15
41
|
* Merge a Partial<TrailContext> into a test context.
|
|
16
42
|
* Used internally when the public API accepts Partial<TrailContext>.
|
|
17
43
|
*/
|
|
18
|
-
export declare const mergeTestContext: (ctx?: Partial<TrailContext
|
|
44
|
+
export declare const mergeTestContext: (ctx?: Partial<TrailContext>, services?: ServiceOverrideMap) => TrailContext;
|
|
19
45
|
//# 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,
|
|
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"}
|
package/dist/context.js
CHANGED
|
@@ -1,6 +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
5
|
import { createTestLogger } from './logger.js';
|
|
5
6
|
// ---------------------------------------------------------------------------
|
|
6
7
|
// createTestContext
|
|
@@ -12,22 +13,80 @@ import { createTestLogger } from './logger.js';
|
|
|
12
13
|
* - `logger`: a `TestLogger` that captures entries
|
|
13
14
|
* - `signal`: a non-aborted AbortController signal
|
|
14
15
|
*/
|
|
15
|
-
export const createTestContext = (overrides) =>
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
export const createTestContext = (overrides) => {
|
|
17
|
+
const cwd = overrides?.cwd ?? process.cwd();
|
|
18
|
+
const ctx = {
|
|
19
|
+
cwd,
|
|
20
|
+
env: overrides?.env ?? { TRAILS_ENV: 'test' },
|
|
21
|
+
extensions: undefined,
|
|
22
|
+
logger: overrides?.logger ?? createTestLogger(),
|
|
23
|
+
requestId: overrides?.requestId ?? 'test-request-001',
|
|
24
|
+
signal: overrides?.signal ?? new AbortController().signal,
|
|
25
|
+
workspaceRoot: cwd,
|
|
26
|
+
};
|
|
27
|
+
ctx.service = createServiceLookup(() => ctx);
|
|
28
|
+
return ctx;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Create a mock `FollowFn` for testing composite trails.
|
|
32
|
+
*
|
|
33
|
+
* Returns preconfigured `Result` values keyed by trail ID. Calls to
|
|
34
|
+
* unregistered IDs return `Result.err` with a descriptive message.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```ts
|
|
38
|
+
* const follow = createFollowContext({
|
|
39
|
+
* responses: { 'entity.add': Result.ok({ id: '1', name: 'Alpha' }) },
|
|
40
|
+
* });
|
|
41
|
+
* const ctx = { ...createTestContext(), follow };
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export const createFollowContext = (options) => {
|
|
45
|
+
const responses = options?.responses ?? {};
|
|
46
|
+
return (id, _input) => {
|
|
47
|
+
const response = responses[id];
|
|
48
|
+
if (response === undefined) {
|
|
49
|
+
return Promise.resolve(Result.err(new Error(`No mock response for follow("${id}")`)));
|
|
50
|
+
}
|
|
51
|
+
return Promise.resolve(response);
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
const isTestExecutionOptions = (input) => input !== undefined &&
|
|
55
|
+
(Object.hasOwn(input, 'ctx') || Object.hasOwn(input, 'services'));
|
|
56
|
+
export const normalizeTestExecutionOptions = (input) => isTestExecutionOptions(input) ? input : { ctx: input };
|
|
57
|
+
export const mergeServiceOverrides = (autoResolved, ctx, explicit) => ({
|
|
58
|
+
...autoResolved,
|
|
59
|
+
...ctx?.extensions,
|
|
60
|
+
...explicit,
|
|
21
61
|
});
|
|
62
|
+
const buildMockServices = async (app) => {
|
|
63
|
+
const services = {};
|
|
64
|
+
for (const declaredService of app.listServices()) {
|
|
65
|
+
if (!declaredService.mock) {
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
services[declaredService.id] = await declaredService.mock();
|
|
69
|
+
}
|
|
70
|
+
return services;
|
|
71
|
+
};
|
|
72
|
+
export const resolveMockServices = async (app) => await buildMockServices(app);
|
|
22
73
|
/**
|
|
23
74
|
* Merge a Partial<TrailContext> into a test context.
|
|
24
75
|
* Used internally when the public API accepts Partial<TrailContext>.
|
|
25
76
|
*/
|
|
26
|
-
export const mergeTestContext = (ctx) => {
|
|
27
|
-
if (ctx === undefined) {
|
|
28
|
-
return createTestContext();
|
|
29
|
-
}
|
|
77
|
+
export const mergeTestContext = (ctx, services) => {
|
|
30
78
|
const base = createTestContext();
|
|
31
|
-
|
|
79
|
+
const extensions = {
|
|
80
|
+
...base.extensions,
|
|
81
|
+
...ctx?.extensions,
|
|
82
|
+
...services,
|
|
83
|
+
};
|
|
84
|
+
const merged = {
|
|
85
|
+
...base,
|
|
86
|
+
...ctx,
|
|
87
|
+
extensions: Object.keys(extensions).length === 0 ? undefined : extensions,
|
|
88
|
+
};
|
|
89
|
+
merged.service = createServiceLookup(() => merged);
|
|
90
|
+
return merged;
|
|
32
91
|
};
|
|
33
92
|
//# 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;
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"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"}
|
package/dist/contracts.d.ts
CHANGED
|
@@ -6,11 +6,12 @@
|
|
|
6
6
|
* the declared schema.
|
|
7
7
|
*/
|
|
8
8
|
import type { Topo, TrailContext } from '@ontrails/core';
|
|
9
|
+
import type { TestExecutionOptions } from './context.js';
|
|
9
10
|
/**
|
|
10
|
-
* Verify that every trail
|
|
11
|
+
* Verify that every trail implementation output matches its declared
|
|
11
12
|
* output schema. Catches implementation-schema drift.
|
|
12
13
|
*
|
|
13
14
|
* Trails without output schemas or examples are skipped.
|
|
14
15
|
*/
|
|
15
|
-
export declare const testContracts: (app: Topo, ctxOrFactory?: Partial<TrailContext> | (() => Partial<TrailContext>)) => void;
|
|
16
|
+
export declare const testContracts: (app: Topo, ctxOrFactory?: Partial<TrailContext> | TestExecutionOptions | (() => Partial<TrailContext> | TestExecutionOptions)) => void;
|
|
16
17
|
//# sourceMappingURL=contracts.d.ts.map
|
package/dist/contracts.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../src/contracts.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,IAAI,EAAuB,YAAY,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../src/contracts.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,IAAI,EAAuB,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAW9E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAqCzD;;;;;GAKG;AACH,eAAO,MAAM,aAAa,GACxB,KAAK,IAAI,EACT,eACI,OAAO,CAAC,YAAY,CAAC,GACrB,oBAAoB,GACpB,CAAC,MAAM,OAAO,CAAC,YAAY,CAAC,GAAG,oBAAoB,CAAC,KACvD,IA6CF,CAAC"}
|
package/dist/contracts.js
CHANGED
|
@@ -6,12 +6,20 @@
|
|
|
6
6
|
* the declared schema.
|
|
7
7
|
*/
|
|
8
8
|
import { describe, test } from 'bun:test';
|
|
9
|
-
import { formatZodIssues, validateInput } from '@ontrails/core';
|
|
9
|
+
import { executeTrail, formatZodIssues, validateInput } from '@ontrails/core';
|
|
10
10
|
import { expectOk } from './assertions.js';
|
|
11
|
-
import { mergeTestContext } from './context.js';
|
|
11
|
+
import { mergeServiceOverrides, mergeTestContext, normalizeTestExecutionOptions, resolveMockServices, } 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) => {
|
|
17
|
+
const spec = t;
|
|
18
|
+
if (!spec.follow || spec.follow.length === 0) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
return !normalizeTestExecutionOptions(resolveCtx()).ctx?.follow;
|
|
22
|
+
};
|
|
15
23
|
const validateOutputSchema = (outputSchema, value, trailId, exampleName) => {
|
|
16
24
|
const parsed = outputSchema.safeParse(value);
|
|
17
25
|
if (!parsed.success) {
|
|
@@ -23,30 +31,37 @@ const validateOutputSchema = (outputSchema, value, trailId, exampleName) => {
|
|
|
23
31
|
// testContracts
|
|
24
32
|
// ---------------------------------------------------------------------------
|
|
25
33
|
/**
|
|
26
|
-
* Verify that every trail
|
|
34
|
+
* Verify that every trail implementation output matches its declared
|
|
27
35
|
* output schema. Catches implementation-schema drift.
|
|
28
36
|
*
|
|
29
37
|
* Trails without output schemas or examples are skipped.
|
|
30
38
|
*/
|
|
31
39
|
export const testContracts = (app, ctxOrFactory) => {
|
|
32
|
-
const
|
|
33
|
-
const
|
|
40
|
+
const resolveInput = typeof ctxOrFactory === 'function' ? ctxOrFactory : () => ctxOrFactory;
|
|
41
|
+
const allEntries = app.list();
|
|
34
42
|
describe('contracts', () => {
|
|
35
|
-
describe.each(
|
|
36
|
-
const t = trailDef;
|
|
43
|
+
describe.each(allEntries)('$id', (t) => {
|
|
37
44
|
if (t.output === undefined) {
|
|
38
45
|
return;
|
|
39
46
|
}
|
|
40
47
|
if (t.examples === undefined || t.examples.length === 0) {
|
|
41
48
|
return;
|
|
42
49
|
}
|
|
50
|
+
if (needsFollowContext(t, resolveInput)) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
43
53
|
const { examples, output: outputSchema } = t;
|
|
44
54
|
const successExamples = examples.filter((e) => e.error === undefined);
|
|
45
55
|
test.each(successExamples)('contract: $name', async (example) => {
|
|
46
|
-
const
|
|
56
|
+
const resolved = normalizeTestExecutionOptions(resolveInput());
|
|
57
|
+
const services = mergeServiceOverrides(await resolveMockServices(app), resolved.ctx, resolved.services);
|
|
58
|
+
const testCtx = mergeTestContext(resolved.ctx);
|
|
47
59
|
const validated = validateInput(t.input, example.input);
|
|
48
|
-
|
|
49
|
-
const result = await t.
|
|
60
|
+
expectOk(validated);
|
|
61
|
+
const result = await executeTrail(t, example.input, {
|
|
62
|
+
ctx: testCtx,
|
|
63
|
+
services,
|
|
64
|
+
});
|
|
50
65
|
const resultValue = expectOk(result);
|
|
51
66
|
validateOutputSchema(outputSchema, resultValue, t.id, example.name);
|
|
52
67
|
});
|
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,eAAe,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"contracts.js","sourceRoot":"","sources":["../src/contracts.ts"],"names":[],"mappings":"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"}
|
package/dist/examples.d.ts
CHANGED
|
@@ -3,14 +3,15 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Iterates every trail in the app's topo. For each trail with examples,
|
|
5
5
|
* generates describe/test blocks using bun:test. Progressive assertion
|
|
6
|
-
* determines which check to run per example. For
|
|
6
|
+
* determines which check to run per example. For trails with `follow`
|
|
7
7
|
* declarations, checks that every declared follow was called at least once.
|
|
8
8
|
*/
|
|
9
9
|
import type { Topo, TrailContext } from '@ontrails/core';
|
|
10
|
+
import type { TestExecutionOptions } from './context.js';
|
|
10
11
|
/**
|
|
11
12
|
* Generate describe/test blocks for every trail example in the app.
|
|
12
13
|
*
|
|
13
|
-
* For
|
|
14
|
+
* For trails with `follow` declarations and examples, also verifies that
|
|
14
15
|
* every declared follow ID was called at least once across all examples.
|
|
15
16
|
*
|
|
16
17
|
* One line in your test file:
|
|
@@ -18,5 +19,5 @@ import type { Topo, TrailContext } from '@ontrails/core';
|
|
|
18
19
|
* testExamples(app);
|
|
19
20
|
* ```
|
|
20
21
|
*/
|
|
21
|
-
export declare const testExamples: (app: Topo, ctxOrFactory?: Partial<TrailContext> | (() => Partial<TrailContext>)) => void;
|
|
22
|
+
export declare const testExamples: (app: Topo, ctxOrFactory?: Partial<TrailContext> | TestExecutionOptions | (() => Partial<TrailContext> | TestExecutionOptions)) => void;
|
|
22
23
|
//# sourceMappingURL=examples.d.ts.map
|
package/dist/examples.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"examples.d.ts","sourceRoot":"","sources":["../src/examples.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAGV,IAAI,EAGJ,YAAY,EACb,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"examples.d.ts","sourceRoot":"","sources":["../src/examples.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAGV,IAAI,EAGJ,YAAY,EACb,MAAM,gBAAgB,CAAC;AAkCxB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAiLzD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,YAAY,GACvB,KAAK,IAAI,EACT,eACI,OAAO,CAAC,YAAY,CAAC,GACrB,oBAAoB,GACpB,CAAC,MAAM,OAAO,CAAC,YAAY,CAAC,GAAG,oBAAoB,CAAC,KACvD,IAyEF,CAAC"}
|