@ontrails/testing 1.0.0-beta.15 → 1.0.0-beta.16
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/CHANGELOG.md +56 -1
- package/README.md +2 -2
- package/package.json +15 -7
- package/src/all.ts +7 -7
- package/src/context.ts +3 -0
- package/src/contracts.ts +1 -16
- package/src/examples.ts +19 -11
- package/src/index.ts +1 -1
- package/src/logger.ts +3 -1
- package/src/scenario.ts +3 -5
- package/src/signals.ts +221 -0
- package/src/types.ts +1 -1
- package/.turbo/turbo-build.log +0 -1
- package/.turbo/turbo-lint.log +0 -3
- package/.turbo/turbo-typecheck.log +0 -1
- package/dist/all.d.ts +0 -36
- package/dist/all.d.ts.map +0 -1
- package/dist/all.js +0 -99
- package/dist/all.js.map +0 -1
- package/dist/assertions.d.ts +0 -72
- package/dist/assertions.d.ts.map +0 -1
- package/dist/assertions.js +0 -238
- package/dist/assertions.js.map +0 -1
- package/dist/context.d.ts +0 -76
- package/dist/context.d.ts.map +0 -1
- package/dist/context.js +0 -118
- package/dist/context.js.map +0 -1
- package/dist/contracts.d.ts +0 -17
- package/dist/contracts.d.ts.map +0 -1
- package/dist/contracts.js +0 -75
- package/dist/contracts.js.map +0 -1
- package/dist/crosses.d.ts +0 -38
- package/dist/crosses.d.ts.map +0 -1
- package/dist/crosses.js +0 -223
- package/dist/crosses.js.map +0 -1
- package/dist/detours.d.ts +0 -13
- package/dist/detours.d.ts.map +0 -1
- package/dist/detours.js +0 -109
- package/dist/detours.js.map +0 -1
- package/dist/effective-examples.d.ts +0 -30
- package/dist/effective-examples.d.ts.map +0 -1
- package/dist/effective-examples.js +0 -227
- package/dist/effective-examples.js.map +0 -1
- package/dist/examples.d.ts +0 -23
- package/dist/examples.d.ts.map +0 -1
- package/dist/examples.js +0 -240
- package/dist/examples.js.map +0 -1
- package/dist/harness-cli.d.ts +0 -21
- package/dist/harness-cli.d.ts.map +0 -1
- package/dist/harness-cli.js +0 -205
- package/dist/harness-cli.js.map +0 -1
- package/dist/harness-mcp.d.ts +0 -21
- package/dist/harness-mcp.d.ts.map +0 -1
- package/dist/harness-mcp.js +0 -54
- package/dist/harness-mcp.js.map +0 -1
- package/dist/index.d.ts +0 -18
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -19
- package/dist/index.js.map +0 -1
- package/dist/logger.d.ts +0 -15
- package/dist/logger.d.ts.map +0 -1
- package/dist/logger.js +0 -87
- package/dist/logger.js.map +0 -1
- package/dist/scenario.d.ts +0 -37
- package/dist/scenario.d.ts.map +0 -1
- package/dist/scenario.js +0 -235
- package/dist/scenario.js.map +0 -1
- package/dist/trail.d.ts +0 -20
- package/dist/trail.d.ts.map +0 -1
- package/dist/trail.js +0 -80
- package/dist/trail.js.map +0 -1
- package/dist/types.d.ts +0 -113
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -5
- package/dist/types.js.map +0 -1
- package/src/__tests__/all.test.ts +0 -254
- package/src/__tests__/context.test.ts +0 -170
- package/src/__tests__/contracts.test.ts +0 -239
- package/src/__tests__/crosses.test.ts +0 -587
- package/src/__tests__/detours.test.ts +0 -212
- package/src/__tests__/effective-examples.test.ts +0 -203
- package/src/__tests__/examples.test.ts +0 -636
- package/src/__tests__/harness-cli.test.ts +0 -90
- package/src/__tests__/harness-mcp.test.ts +0 -37
- package/src/__tests__/logger.test.ts +0 -136
- package/src/__tests__/partial-match.test.ts +0 -126
- package/src/__tests__/scenario.test.ts +0 -381
- package/src/__tests__/trail.test.ts +0 -99
- package/tsconfig.json +0 -9
- package/tsconfig.tests.json +0 -10
- package/tsconfig.tsbuildinfo +0 -1
|
@@ -1,227 +0,0 @@
|
|
|
1
|
-
import { getContourReferences } from '@ontrails/core';
|
|
2
|
-
import { z } from 'zod';
|
|
3
|
-
/**
|
|
4
|
-
* Tracks examples that `deriveTrailExamples` synthesizes from contour
|
|
5
|
-
* fixtures. Authored examples are passed through untouched and never
|
|
6
|
-
* appear here, so consumers can distinguish the two by identity.
|
|
7
|
-
*
|
|
8
|
-
* Exposed via `isDerivedExample` so downstream testing helpers (e.g.
|
|
9
|
-
* `testExamples` crossing coverage) can relax invariants that only make
|
|
10
|
-
* sense for authored inputs.
|
|
11
|
-
*/
|
|
12
|
-
const derivedExamples = new WeakSet();
|
|
13
|
-
/**
|
|
14
|
-
* Returns `true` if the given example was synthesized from contour fixtures
|
|
15
|
-
* by `deriveTrailExamples`, `false` if it was authored on the trail.
|
|
16
|
-
*/
|
|
17
|
-
export const isDerivedExample = (example) => derivedExamples.has(example);
|
|
18
|
-
const capitalize = (value) => value.length === 0 ? value : value.slice(0, 1).toUpperCase() + value.slice(1);
|
|
19
|
-
const collectReferenceMap = (contours) => {
|
|
20
|
-
const contourNames = new Set(contours.map((contour) => contour.name));
|
|
21
|
-
return new Map(contours.map((contour) => [
|
|
22
|
-
contour.name,
|
|
23
|
-
getContourReferences(contour).filter((reference) => contourNames.has(reference.contour)),
|
|
24
|
-
]));
|
|
25
|
-
};
|
|
26
|
-
const getIdentityValue = (fixture) => fixture.example[fixture.contour.identity];
|
|
27
|
-
const candidateMatchesSelectedReference = (candidate, target, reference) => Object.is(candidate.example[reference.field], getIdentityValue(target));
|
|
28
|
-
const selectedMatchesCandidateReference = (fixture, candidate, reference) => Object.is(fixture.example[reference.field], getIdentityValue(candidate));
|
|
29
|
-
const matchesCandidateReferences = (candidate, selected, referencesByContour) => {
|
|
30
|
-
const candidateReferences = referencesByContour.get(candidate.contour.name) ?? [];
|
|
31
|
-
for (const reference of candidateReferences) {
|
|
32
|
-
const target = selected.find((fixture) => fixture.contour.name === reference.contour);
|
|
33
|
-
if (target === undefined) {
|
|
34
|
-
continue;
|
|
35
|
-
}
|
|
36
|
-
if (!candidateMatchesSelectedReference(candidate, target, reference)) {
|
|
37
|
-
return false;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
return true;
|
|
41
|
-
};
|
|
42
|
-
const matchesSelectedReferences = (candidate, selected, referencesByContour) => {
|
|
43
|
-
for (const fixture of selected) {
|
|
44
|
-
const fixtureReferences = referencesByContour.get(fixture.contour.name) ?? [];
|
|
45
|
-
for (const reference of fixtureReferences) {
|
|
46
|
-
if (reference.contour !== candidate.contour.name) {
|
|
47
|
-
continue;
|
|
48
|
-
}
|
|
49
|
-
if (!selectedMatchesCandidateReference(fixture, candidate, reference)) {
|
|
50
|
-
return false;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
return true;
|
|
55
|
-
};
|
|
56
|
-
const matchesKnownReferences = (candidate, selected, referencesByContour) => matchesCandidateReferences(candidate, selected, referencesByContour) &&
|
|
57
|
-
matchesSelectedReferences(candidate, selected, referencesByContour);
|
|
58
|
-
const selectContourFixtures = (contours, referencesByContour, index = 0, selected = []) => {
|
|
59
|
-
const contour = contours[index];
|
|
60
|
-
if (contour === undefined) {
|
|
61
|
-
return [selected];
|
|
62
|
-
}
|
|
63
|
-
const examples = contour.examples ?? [];
|
|
64
|
-
const matchingFixtures = examples.flatMap((example, exampleIndex) => {
|
|
65
|
-
const fixture = {
|
|
66
|
-
contour,
|
|
67
|
-
example: example,
|
|
68
|
-
index: exampleIndex,
|
|
69
|
-
};
|
|
70
|
-
if (!matchesKnownReferences(fixture, selected, referencesByContour)) {
|
|
71
|
-
return [];
|
|
72
|
-
}
|
|
73
|
-
return selectContourFixtures(contours, referencesByContour, index + 1, [
|
|
74
|
-
...selected,
|
|
75
|
-
fixture,
|
|
76
|
-
]);
|
|
77
|
-
});
|
|
78
|
-
return matchingFixtures;
|
|
79
|
-
};
|
|
80
|
-
/**
|
|
81
|
-
* Merge selected contour fixtures into a single candidate input object.
|
|
82
|
-
*
|
|
83
|
-
* The resulting record contains:
|
|
84
|
-
* - `<contour>`: the full fixture payload keyed by contour name.
|
|
85
|
-
* - `<contour><Identity>`: the fixture's identity value on a prefixed key.
|
|
86
|
-
* - `<contour><Field>`: every fixture field on a prefixed key.
|
|
87
|
-
* - Unqualified `<field>` keys: first-write-wins across contours.
|
|
88
|
-
*
|
|
89
|
-
* The first-write-wins behaviour on unqualified keys is intentional but can
|
|
90
|
-
* silently drop a later contour's value when two contours share a field name
|
|
91
|
-
* (e.g. both declare `id`). The prefixed aliases above are unambiguous and
|
|
92
|
-
* always written, so schemas that consume the prefixed form are unaffected;
|
|
93
|
-
* schemas that rely on the bare field name should disambiguate via the
|
|
94
|
-
* prefixed alias instead.
|
|
95
|
-
*/
|
|
96
|
-
const buildDerivedInput = (fixtures) => {
|
|
97
|
-
const candidate = {};
|
|
98
|
-
for (const fixture of fixtures) {
|
|
99
|
-
candidate[fixture.contour.name] = fixture.example;
|
|
100
|
-
candidate[`${fixture.contour.name}${capitalize(fixture.contour.identity)}`] = getIdentityValue(fixture);
|
|
101
|
-
for (const [field, value] of Object.entries(fixture.example)) {
|
|
102
|
-
if (!Object.hasOwn(candidate, field)) {
|
|
103
|
-
candidate[field] = value;
|
|
104
|
-
}
|
|
105
|
-
candidate[`${fixture.contour.name}${capitalize(field)}`] = value;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
return candidate;
|
|
109
|
-
};
|
|
110
|
-
/**
|
|
111
|
-
* Project the merged candidate input down to keys the trail's input schema
|
|
112
|
-
* knows about.
|
|
113
|
-
*
|
|
114
|
-
* `buildDerivedInput` emits synthesized prefixed aliases (e.g. `userEmail`)
|
|
115
|
-
* alongside bare field names. Strict schemas (`z.object(...).strict()`)
|
|
116
|
-
* reject any unknown key, which means an otherwise valid derived fixture
|
|
117
|
-
* would silently fail `safeParse` just because of the synthesized aliases.
|
|
118
|
-
* When the input is a `ZodObject`, trim the candidate to its declared keys
|
|
119
|
-
* before validation. Non-object inputs pass through unchanged — they are
|
|
120
|
-
* validated as-is and can decide for themselves.
|
|
121
|
-
*/
|
|
122
|
-
const projectInputForSchema = (inputSchema, candidate) => {
|
|
123
|
-
if (!(inputSchema instanceof z.ZodObject)) {
|
|
124
|
-
return candidate;
|
|
125
|
-
}
|
|
126
|
-
const known = Object.keys(inputSchema.shape);
|
|
127
|
-
const projected = {};
|
|
128
|
-
for (const key of known) {
|
|
129
|
-
if (Object.hasOwn(candidate, key)) {
|
|
130
|
-
projected[key] = candidate[key];
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
return projected;
|
|
134
|
-
};
|
|
135
|
-
/**
|
|
136
|
-
* Derive an expected output value from the selected contour fixtures when
|
|
137
|
-
* exactly one fixture's payload satisfies the trail's output schema.
|
|
138
|
-
*
|
|
139
|
-
* Returns `undefined` when the trail has no output schema, when no fixture
|
|
140
|
-
* matches, or when more than one matches — callers should then leave the
|
|
141
|
-
* derived example without an `expected` and fall back to schema-only
|
|
142
|
-
* validation. We intentionally do **not** infer `expected` from the merged
|
|
143
|
-
* candidate input: input and output schemas frequently overlap structurally
|
|
144
|
-
* but represent different semantics, so inferring from the input would
|
|
145
|
-
* produce false deep-equality failures.
|
|
146
|
-
*/
|
|
147
|
-
const deriveExpectedValue = (trail, fixtures) => {
|
|
148
|
-
if (trail.output === undefined) {
|
|
149
|
-
return undefined;
|
|
150
|
-
}
|
|
151
|
-
const outputSchema = trail.output;
|
|
152
|
-
const contourMatches = fixtures
|
|
153
|
-
.map((fixture) => outputSchema.safeParse(fixture.example))
|
|
154
|
-
.filter((candidate) => candidate.success);
|
|
155
|
-
if (contourMatches.length !== 1) {
|
|
156
|
-
return undefined;
|
|
157
|
-
}
|
|
158
|
-
const [singleMatch] = contourMatches;
|
|
159
|
-
if (singleMatch === undefined) {
|
|
160
|
-
return undefined;
|
|
161
|
-
}
|
|
162
|
-
return singleMatch.data;
|
|
163
|
-
};
|
|
164
|
-
const formatFixtureName = (fixtures, index) => {
|
|
165
|
-
const label = fixtures
|
|
166
|
-
.map((fixture) => {
|
|
167
|
-
const identity = getIdentityValue(fixture);
|
|
168
|
-
const fallback = fixture.index + 1;
|
|
169
|
-
return `${fixture.contour.name}:${String(identity ?? fallback)}`;
|
|
170
|
-
})
|
|
171
|
-
.join(', ');
|
|
172
|
-
return label.length > 0
|
|
173
|
-
? `Derived fixture ${index + 1} (${label})`
|
|
174
|
-
: `Derived fixture ${index + 1}`;
|
|
175
|
-
};
|
|
176
|
-
/**
|
|
177
|
-
* Prefer authored trail examples and fall back to contour-derived fixtures.
|
|
178
|
-
*
|
|
179
|
-
* Examples returned by this helper come from one of two provenances:
|
|
180
|
-
* - **Authored.** When `trail.examples` is non-empty, its entries are
|
|
181
|
-
* returned verbatim. These are the developer's stated intent and carry
|
|
182
|
-
* full invariants — including crossing-coverage assertions in
|
|
183
|
-
* `testExamples`.
|
|
184
|
-
* - **Derived.** When there are no authored examples but the trail has
|
|
185
|
-
* contours with examples, candidate inputs are synthesized from contour
|
|
186
|
-
* fixtures and validated against `trail.input`. These are opportunistic
|
|
187
|
-
* coverage that exists to let `testAll(app)` exercise contour-backed
|
|
188
|
-
* trails without per-test setup; they are not guaranteed to exercise
|
|
189
|
-
* every composition branch, so consumers should relax invariants that
|
|
190
|
-
* only make sense for authored inputs (see `isDerivedExample`).
|
|
191
|
-
*
|
|
192
|
-
* Contour examples stay as the raw input payload so Trails validation /
|
|
193
|
-
* transforms still happen exactly once inside the normal test execution
|
|
194
|
-
* path. Derived examples are additionally tagged via a module-level
|
|
195
|
-
* `WeakSet` so consumers can detect them without widening the public
|
|
196
|
-
* `TrailExample` shape.
|
|
197
|
-
*/
|
|
198
|
-
export const deriveTrailExamples = (trail) => {
|
|
199
|
-
if (trail.examples !== undefined && trail.examples.length > 0) {
|
|
200
|
-
return trail.examples;
|
|
201
|
-
}
|
|
202
|
-
if (trail.contours.length === 0) {
|
|
203
|
-
return [];
|
|
204
|
-
}
|
|
205
|
-
if (trail.contours.some((contour) => contour.examples === undefined || contour.examples.length === 0)) {
|
|
206
|
-
return [];
|
|
207
|
-
}
|
|
208
|
-
const referencesByContour = collectReferenceMap(trail.contours);
|
|
209
|
-
const fixtureSets = selectContourFixtures(trail.contours, referencesByContour);
|
|
210
|
-
return fixtureSets.flatMap((fixtures, index) => {
|
|
211
|
-
const merged = buildDerivedInput(fixtures);
|
|
212
|
-
const input = projectInputForSchema(trail.input, merged);
|
|
213
|
-
const validated = trail.input.safeParse(input);
|
|
214
|
-
if (!validated.success) {
|
|
215
|
-
return [];
|
|
216
|
-
}
|
|
217
|
-
const expected = deriveExpectedValue(trail, fixtures);
|
|
218
|
-
const derived = {
|
|
219
|
-
...(expected === undefined ? {} : { expected }),
|
|
220
|
-
input,
|
|
221
|
-
name: formatFixtureName(fixtures, index),
|
|
222
|
-
};
|
|
223
|
-
derivedExamples.add(derived);
|
|
224
|
-
return [derived];
|
|
225
|
-
});
|
|
226
|
-
};
|
|
227
|
-
//# sourceMappingURL=effective-examples.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"effective-examples.js","sourceRoot":"","sources":["../src/effective-examples.ts"],"names":[],"mappings":"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"}
|
package/dist/examples.d.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* testExamples — the headline one-liner.
|
|
3
|
-
*
|
|
4
|
-
* Iterates every trail in the app's topo. For each trail with examples,
|
|
5
|
-
* generates describe/test blocks using bun:test. Progressive assertion
|
|
6
|
-
* determines which check to run per example. For trails with `crosses`
|
|
7
|
-
* declarations, checks that every declared crossing was called at least once.
|
|
8
|
-
*/
|
|
9
|
-
import type { Topo, TrailContext } from '@ontrails/core';
|
|
10
|
-
import type { TestExecutionOptions } from './context.js';
|
|
11
|
-
/**
|
|
12
|
-
* Generate describe/test blocks for every trail example in the app.
|
|
13
|
-
*
|
|
14
|
-
* For trails with `crosses` declarations and examples, also verifies that
|
|
15
|
-
* every declared crossed ID was called at least once across all examples.
|
|
16
|
-
*
|
|
17
|
-
* One line in your test file:
|
|
18
|
-
* ```ts
|
|
19
|
-
* testExamples(graph);
|
|
20
|
-
* ```
|
|
21
|
-
*/
|
|
22
|
-
export declare const testExamples: (app: Topo, ctxOrFactory?: Partial<TrailContext> | TestExecutionOptions | (() => Partial<TrailContext> | TestExecutionOptions)) => void;
|
|
23
|
-
//# sourceMappingURL=examples.d.ts.map
|
package/dist/examples.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
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;AAuCxB,OAAO,KAAK,EAAkB,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAmPzE;;;;;;;;;;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,IAoGF,CAAC"}
|
package/dist/examples.js
DELETED
|
@@ -1,240 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* testExamples — the headline one-liner.
|
|
3
|
-
*
|
|
4
|
-
* Iterates every trail in the app's topo. For each trail with examples,
|
|
5
|
-
* generates describe/test blocks using bun:test. Progressive assertion
|
|
6
|
-
* determines which check to run per example. For trails with `crosses`
|
|
7
|
-
* declarations, checks that every declared crossing was called at least once.
|
|
8
|
-
*/
|
|
9
|
-
import { describe, expect, test } from 'bun:test';
|
|
10
|
-
import { AlreadyExistsError, AmbiguousError, AssertionError, AuthError, buildCrossValidationSchema, CancelledError, ConflictError, DerivationError, InternalError, NetworkError, NotFoundError, PermissionError, RateLimitError, RetryExhaustedError, executeTrail, Result, TimeoutError, TrailsError, ValidationError, validateInput, } from '@ontrails/core';
|
|
11
|
-
import { assertErrorMatch, assertFullMatch, assertPartialMatch, assertSchemaMatch, } from './assertions.js';
|
|
12
|
-
import { defaultCreatePermit, mergeResourceOverrides, mergeTestContext, normalizeTestExecutionOptions, createMockResources, } from './context.js';
|
|
13
|
-
import { isDerivedExample, deriveTrailExamples } from './effective-examples.js';
|
|
14
|
-
// ---------------------------------------------------------------------------
|
|
15
|
-
// Error class name -> constructor map
|
|
16
|
-
// ---------------------------------------------------------------------------
|
|
17
|
-
const ERROR_MAP = {
|
|
18
|
-
AlreadyExistsError: AlreadyExistsError,
|
|
19
|
-
AmbiguousError: AmbiguousError,
|
|
20
|
-
AssertionError: AssertionError,
|
|
21
|
-
AuthError: AuthError,
|
|
22
|
-
CancelledError: CancelledError,
|
|
23
|
-
ConflictError: ConflictError,
|
|
24
|
-
DerivationError: DerivationError,
|
|
25
|
-
InternalError: InternalError,
|
|
26
|
-
NetworkError: NetworkError,
|
|
27
|
-
NotFoundError: NotFoundError,
|
|
28
|
-
PermissionError: PermissionError,
|
|
29
|
-
RateLimitError: RateLimitError,
|
|
30
|
-
RetryExhaustedError: RetryExhaustedError,
|
|
31
|
-
TimeoutError: TimeoutError,
|
|
32
|
-
TrailsError: TrailsError,
|
|
33
|
-
ValidationError: ValidationError,
|
|
34
|
-
};
|
|
35
|
-
/**
|
|
36
|
-
* Resolve an error class name string to the actual constructor.
|
|
37
|
-
* Falls back to generic Error if the name is not in the core taxonomy.
|
|
38
|
-
*/
|
|
39
|
-
const resolveErrorClass = (name) => ERROR_MAP[name] ?? Error;
|
|
40
|
-
// ---------------------------------------------------------------------------
|
|
41
|
-
// Helpers
|
|
42
|
-
// ---------------------------------------------------------------------------
|
|
43
|
-
const assertProgressiveMatch = (result, example, output) => {
|
|
44
|
-
if (example.expected !== undefined) {
|
|
45
|
-
return assertFullMatch(result, example.expected);
|
|
46
|
-
}
|
|
47
|
-
if (example.expectedMatch !== undefined) {
|
|
48
|
-
return assertPartialMatch(result, example.expectedMatch);
|
|
49
|
-
}
|
|
50
|
-
if (example.error !== undefined) {
|
|
51
|
-
return assertErrorMatch(result, resolveErrorClass(example.error));
|
|
52
|
-
}
|
|
53
|
-
assertSchemaMatch(result, output);
|
|
54
|
-
};
|
|
55
|
-
/**
|
|
56
|
-
* Handle input validation failure for an example.
|
|
57
|
-
* Returns true if the validation error was expected (and assertions passed).
|
|
58
|
-
* Throws if the validation error was unexpected.
|
|
59
|
-
*/
|
|
60
|
-
const handleValidationError = (validated, example) => {
|
|
61
|
-
if (!validated.isErr()) {
|
|
62
|
-
return false;
|
|
63
|
-
}
|
|
64
|
-
if (example.error !== undefined) {
|
|
65
|
-
const errorClass = resolveErrorClass(example.error);
|
|
66
|
-
expect(validated.error).toBeInstanceOf(errorClass);
|
|
67
|
-
return true;
|
|
68
|
-
}
|
|
69
|
-
throw new Error(`Example "${example.name}" has invalid input: ${validated.error.message}`);
|
|
70
|
-
};
|
|
71
|
-
/**
|
|
72
|
-
* Apply auto-permit: if the trail declares scoped permits and the context
|
|
73
|
-
* doesn't already have a permit, create one and merge it into the context.
|
|
74
|
-
*/
|
|
75
|
-
const applyAutoPermit = (ctx, trailDef, opts) => {
|
|
76
|
-
if (opts.strictPermits) {
|
|
77
|
-
return ctx;
|
|
78
|
-
}
|
|
79
|
-
if (ctx.permit !== undefined) {
|
|
80
|
-
return ctx;
|
|
81
|
-
}
|
|
82
|
-
const create = opts.createPermit ?? defaultCreatePermit;
|
|
83
|
-
const permit = create(trailDef);
|
|
84
|
-
if (!permit) {
|
|
85
|
-
return ctx;
|
|
86
|
-
}
|
|
87
|
-
return { ...ctx, permit };
|
|
88
|
-
};
|
|
89
|
-
/**
|
|
90
|
-
* Run a single example against a trail.
|
|
91
|
-
* Handles validation, execution, and assertions.
|
|
92
|
-
*/
|
|
93
|
-
const runExample = async (t, example, output, testCtx, resources, opts) => {
|
|
94
|
-
const validated = validateInput(t.input, example.input);
|
|
95
|
-
if (handleValidationError(validated, example)) {
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
const ctx = opts ? applyAutoPermit(testCtx, t, opts) : testCtx;
|
|
99
|
-
const result = await executeTrail(t, example.input, {
|
|
100
|
-
ctx,
|
|
101
|
-
resources: resources ?? opts?.resources,
|
|
102
|
-
});
|
|
103
|
-
assertProgressiveMatch(result, example, output);
|
|
104
|
-
};
|
|
105
|
-
// ---------------------------------------------------------------------------
|
|
106
|
-
// Crossing coverage for trails with crossings
|
|
107
|
-
// ---------------------------------------------------------------------------
|
|
108
|
-
/**
|
|
109
|
-
* Build a recording cross function that tracks which trail IDs are called.
|
|
110
|
-
*
|
|
111
|
-
* Delegates to `baseCross` when available, otherwise looks up the trail
|
|
112
|
-
* in the topo and executes it with validated input. Falls back to
|
|
113
|
-
* `Result.ok()` when neither is available.
|
|
114
|
-
*/
|
|
115
|
-
const createCoverageCross = (called, baseCross, topo, ctx, resources) => {
|
|
116
|
-
const invokeCross = async (idOrTrail, input, self) => {
|
|
117
|
-
const id = typeof idOrTrail === 'string' ? idOrTrail : idOrTrail.id;
|
|
118
|
-
called.add(id);
|
|
119
|
-
if (baseCross !== undefined) {
|
|
120
|
-
return await baseCross(id, input);
|
|
121
|
-
}
|
|
122
|
-
const trailDef = topo.get(id);
|
|
123
|
-
if (trailDef !== undefined) {
|
|
124
|
-
return await executeTrail(trailDef, input, {
|
|
125
|
-
ctx: { ...ctx, cross: self },
|
|
126
|
-
resources,
|
|
127
|
-
validationSchema: buildCrossValidationSchema(trailDef),
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
return Result.ok();
|
|
131
|
-
};
|
|
132
|
-
// Accepts either a trail object (typed cross), a string id (untyped),
|
|
133
|
-
// or a batch of `[target, input]` tuples.
|
|
134
|
-
const cross = async function cross(idOrTrail, input) {
|
|
135
|
-
if (Array.isArray(idOrTrail)) {
|
|
136
|
-
return await Promise.all(idOrTrail.map(([target, batchInput]) => invokeCross(target, batchInput, cross)));
|
|
137
|
-
}
|
|
138
|
-
return await invokeCross(idOrTrail, input, cross);
|
|
139
|
-
};
|
|
140
|
-
return cross;
|
|
141
|
-
};
|
|
142
|
-
/**
|
|
143
|
-
* Run a single example against a trail with crossings, recording cross calls.
|
|
144
|
-
*/
|
|
145
|
-
const runCompositionExample = async (trailDef, example, output, baseCtx, called, topo, resources, opts) => {
|
|
146
|
-
const validated = validateInput(trailDef.input, example.input);
|
|
147
|
-
if (handleValidationError(validated, example)) {
|
|
148
|
-
return;
|
|
149
|
-
}
|
|
150
|
-
const permittedCtx = opts
|
|
151
|
-
? applyAutoPermit(baseCtx, trailDef, opts)
|
|
152
|
-
: baseCtx;
|
|
153
|
-
const cross = createCoverageCross(called, permittedCtx.cross, topo, permittedCtx, resources);
|
|
154
|
-
const testCtx = { ...permittedCtx, cross };
|
|
155
|
-
// Top-level trail validates against trail.input (not merged crossInput).
|
|
156
|
-
// Merged validation only applies to cross targets in executeFromMap/createCoverageCross.
|
|
157
|
-
const result = await executeTrail(trailDef, example.input, {
|
|
158
|
-
ctx: testCtx,
|
|
159
|
-
resources: resources ?? opts?.resources,
|
|
160
|
-
});
|
|
161
|
-
assertProgressiveMatch(result, example, output);
|
|
162
|
-
};
|
|
163
|
-
// ---------------------------------------------------------------------------
|
|
164
|
-
// testExamples
|
|
165
|
-
// ---------------------------------------------------------------------------
|
|
166
|
-
/**
|
|
167
|
-
* Generate describe/test blocks for every trail example in the app.
|
|
168
|
-
*
|
|
169
|
-
* For trails with `crosses` declarations and examples, also verifies that
|
|
170
|
-
* every declared crossed ID was called at least once across all examples.
|
|
171
|
-
*
|
|
172
|
-
* One line in your test file:
|
|
173
|
-
* ```ts
|
|
174
|
-
* testExamples(graph);
|
|
175
|
-
* ```
|
|
176
|
-
*/
|
|
177
|
-
export const testExamples = (app, ctxOrFactory) => {
|
|
178
|
-
const resolveInput = typeof ctxOrFactory === 'function' ? ctxOrFactory : () => ctxOrFactory;
|
|
179
|
-
const withExamples = app.list()
|
|
180
|
-
.map((trailDef) => ({
|
|
181
|
-
...trailDef,
|
|
182
|
-
examples: deriveTrailExamples(trailDef),
|
|
183
|
-
}))
|
|
184
|
-
.filter((trailDef) => trailDef.examples.length > 0);
|
|
185
|
-
const simpleTrails = withExamples.filter((t) => t.crosses.length === 0);
|
|
186
|
-
const compositionTrails = withExamples.filter((t) => t.crosses.length > 0);
|
|
187
|
-
// Simple trails: run examples directly
|
|
188
|
-
if (simpleTrails.length > 0) {
|
|
189
|
-
describe.each(simpleTrails)('$id', (t) => {
|
|
190
|
-
const { examples, output } = t;
|
|
191
|
-
if (!examples) {
|
|
192
|
-
return;
|
|
193
|
-
}
|
|
194
|
-
test.each([...examples])('example: $name', async (example) => {
|
|
195
|
-
const resolved = normalizeTestExecutionOptions(resolveInput());
|
|
196
|
-
const resources = mergeResourceOverrides(await createMockResources(app), resolved.ctx, resolved.resources);
|
|
197
|
-
const testCtx = mergeTestContext(resolved.ctx);
|
|
198
|
-
await runExample(t, example, output, testCtx, resources, resolved);
|
|
199
|
-
});
|
|
200
|
-
});
|
|
201
|
-
}
|
|
202
|
-
// Composition trails: use recording cross and check coverage.
|
|
203
|
-
//
|
|
204
|
-
// Crossing coverage only runs against AUTHORED examples. Contour-derived
|
|
205
|
-
// fixtures are opportunistic coverage that may not exercise every
|
|
206
|
-
// `ctx.cross()` branch in the trail, so asserting coverage against them
|
|
207
|
-
// would produce false failures for trails whose authored intent was a
|
|
208
|
-
// single path. When a trail has zero authored examples the coverage
|
|
209
|
-
// assertion is skipped entirely — the derived-example runs still
|
|
210
|
-
// execute, but they are not required to cover declared crossings.
|
|
211
|
-
if (compositionTrails.length > 0) {
|
|
212
|
-
describe.each(compositionTrails)('$id', (t) => {
|
|
213
|
-
const { examples, output } = t;
|
|
214
|
-
if (!examples) {
|
|
215
|
-
return;
|
|
216
|
-
}
|
|
217
|
-
const calledFromAuthored = new Set();
|
|
218
|
-
const hasAuthoredExamples = examples.some((example) => !isDerivedExample(example));
|
|
219
|
-
// Only record cross calls from authored examples. Derived fixtures
|
|
220
|
-
// execute normally but do not contribute to coverage — the sink map
|
|
221
|
-
// routes each example to the right bucket without an inline
|
|
222
|
-
// conditional inside the test body.
|
|
223
|
-
const discardSink = new Set();
|
|
224
|
-
const pickCoverageSink = (example) => isDerivedExample(example) ? discardSink : calledFromAuthored;
|
|
225
|
-
test.each([...examples])('example: $name', async (example) => {
|
|
226
|
-
const resolved = normalizeTestExecutionOptions(resolveInput());
|
|
227
|
-
const resources = mergeResourceOverrides(await createMockResources(app), resolved.ctx, resolved.resources);
|
|
228
|
-
const baseCtx = mergeTestContext(resolved.ctx);
|
|
229
|
-
await runCompositionExample(t, example, output, baseCtx, pickCoverageSink(example), app, resources, resolved);
|
|
230
|
-
});
|
|
231
|
-
if (hasAuthoredExamples) {
|
|
232
|
-
test('crossing coverage', () => {
|
|
233
|
-
const uncovered = t.crosses.filter((id) => !calledFromAuthored.has(id));
|
|
234
|
-
expect(uncovered).toEqual([]);
|
|
235
|
-
});
|
|
236
|
-
}
|
|
237
|
-
});
|
|
238
|
-
}
|
|
239
|
-
};
|
|
240
|
-
//# sourceMappingURL=examples.js.map
|
package/dist/examples.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"examples.js","sourceRoot":"","sources":["../src/examples.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAWlD,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,SAAS,EACT,0BAA0B,EAC1B,cAAc,EACd,aAAa,EACb,eAAe,EACf,aAAa,EACb,YAAY,EACZ,aAAa,EACb,eAAe,EACf,cAAc,EACd,mBAAmB,EACnB,YAAY,EACZ,MAAM,EACN,YAAY,EACZ,WAAW,EACX,eAAe,EACf,aAAa,GACd,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,gBAAgB,EAChB,6BAA6B,EAC7B,mBAAmB,GACpB,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAEhF,8EAA8E;AAC9E,sCAAsC;AACtC,8EAA8E;AAE9E,MAAM,SAAS,GAAoD;IACjE,kBAAkB,EAAE,kBAAqD;IACzE,cAAc,EAAE,cAAiD;IACjE,cAAc,EAAE,cAAiD;IACjE,SAAS,EAAE,SAA4C;IACvD,cAAc,EAAE,cAAiD;IACjE,aAAa,EAAE,aAAgD;IAC/D,eAAe,EAAE,eAAkD;IACnE,aAAa,EAAE,aAAgD;IAC/D,YAAY,EAAE,YAA+C;IAC7D,aAAa,EAAE,aAAgD;IAC/D,eAAe,EAAE,eAAkD;IACnE,cAAc,EAAE,cAAiD;IACjE,mBAAmB,EAAE,mBAEX;IACV,YAAY,EAAE,YAA+C;IAC7D,WAAW,EAAE,WAAyD;IACtE,eAAe,EAAE,eAAkD;CACpE,CAAC;AAEF;;;GAGG;AACH,MAAM,iBAAiB,GAAG,CAAC,IAAY,EAAqC,EAAE,CAC5E,SAAS,CAAC,IAAI,CAAC,IAAK,KAAyC,CAAC;AAEhE,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E,MAAM,sBAAsB,GAAG,CAC7B,MAA8B,EAC9B,OAAuC,EACvC,MAA6B,EACvB,EAAE;IACR,IAAI,OAAO,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QACnC,OAAO,eAAe,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IACnD,CAAC;IACD,IAAI,OAAO,CAAC,aAAa,KAAK,SAAS,EAAE,CAAC;QACxC,OAAO,kBAAkB,CAAC,MAAM,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;IAC3D,CAAC;IACD,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAChC,OAAO,gBAAgB,CAAC,MAAM,EAAE,iBAAiB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IACpE,CAAC;IACD,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACpC,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,qBAAqB,GAAG,CAC5B,SAAiC,EACjC,OAAuC,EAC9B,EAAE;IACX,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,EAAE,CAAC;QACvB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAChC,MAAM,UAAU,GAAG,iBAAiB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACpD,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;QACnD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,IAAI,KAAK,CACb,YAAY,OAAO,CAAC,IAAI,wBAAwB,SAAS,CAAC,KAAK,CAAC,OAAO,EAAE,CAC1E,CAAC;AACJ,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,eAAe,GAAG,CACtB,GAAiB,EACjB,QAAwB,EACxB,IAA0B,EACZ,EAAE;IAChB,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;QACvB,OAAO,GAAG,CAAC;IACb,CAAC;IACD,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC7B,OAAO,GAAG,CAAC;IACb,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,IAAI,mBAAmB,CAAC;IACxD,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IAChC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,GAAG,CAAC;IACb,CAAC;IACD,OAAO,EAAE,GAAG,GAAG,EAAE,MAAM,EAAE,CAAC;AAC5B,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,GAAG,KAAK,EACtB,CAAmC,EACnC,OAAuC,EACvC,MAA6B,EAC7B,OAAqB,EACrB,SAA+B,EAC/B,IAA2B,EACZ,EAAE;IACjB,MAAM,SAAS,GAAG,aAAa,CAAC,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IAExD,IAAI,qBAAqB,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,CAAC;QAC9C,OAAO;IACT,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,eAAe,CAAC,OAAO,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IAE/D,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC,KAAK,EAAE;QAClD,GAAG;QACH,SAAS,EAAE,SAAS,IAAI,IAAI,EAAE,SAAS;KACxC,CAAC,CAAC;IACH,sBAAsB,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;AAClD,CAAC,CAAC;AAEF,8EAA8E;AAC9E,8CAA8C;AAC9C,8EAA8E;AAE9E;;;;;;GAMG;AACH,MAAM,mBAAmB,GAAG,CAC1B,MAAmB,EACnB,SAA8B,EAC9B,IAAU,EACV,GAAiB,EACjB,SAA+B,EACtB,EAAE;IACX,MAAM,WAAW,GAAG,KAAK,EACvB,SAA2C,EAC3C,KAAc,EACd,IAAa,EACb,EAAE;QACF,MAAM,EAAE,GAAG,OAAO,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC;QACpE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAEf,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC5B,OAAO,MAAM,SAAS,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QACpC,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC9B,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,OAAO,MAAM,YAAY,CAAC,QAAQ,EAAE,KAAK,EAAE;gBACzC,GAAG,EAAE,EAAE,GAAG,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE;gBAC5B,SAAS;gBACT,gBAAgB,EAAE,0BAA0B,CAAC,QAAQ,CAAC;aACvD,CAAC,CAAC;QACL,CAAC;QAED,OAAO,MAAM,CAAC,EAAE,EAAE,CAAC;IACrB,CAAC,CAAC;IAEF,sEAAsE;IACtE,0CAA0C;IAC1C,MAAM,KAAK,GAAG,KAAK,UAAU,KAAK,CAChC,SAGqE,EACrE,KAAe;QAEf,IAAI,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;YAC7B,OAAO,MAAM,OAAO,CAAC,GAAG,CACtB,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,EAAE,CACrC,WAAW,CAAC,MAAM,EAAE,UAAU,EAAE,KAAgB,CAAC,CAClD,CACF,CAAC;QACJ,CAAC;QAED,OAAO,MAAM,WAAW,CACtB,SAA6C,EAC7C,KAAK,EACL,KAAgB,CACjB,CAAC;IACJ,CAAY,CAAC;IAEb,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,qBAAqB,GAAG,KAAK,EACjC,QAA0C,EAC1C,OAAuC,EACvC,MAA6B,EAC7B,OAAqB,EACrB,MAAmB,EACnB,IAAU,EACV,SAA+B,EAC/B,IAA2B,EACZ,EAAE;IACjB,MAAM,SAAS,GAAG,aAAa,CAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IAE/D,IAAI,qBAAqB,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,CAAC;QAC9C,OAAO;IACT,CAAC;IAED,MAAM,YAAY,GAAG,IAAI;QACvB,CAAC,CAAC,eAAe,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC;QAC1C,CAAC,CAAC,OAAO,CAAC;IACZ,MAAM,KAAK,GAAG,mBAAmB,CAC/B,MAAM,EACN,YAAY,CAAC,KAAK,EAClB,IAAI,EACJ,YAAY,EACZ,SAAS,CACV,CAAC;IACF,MAAM,OAAO,GAAiB,EAAE,GAAG,YAAY,EAAE,KAAK,EAAE,CAAC;IAEzD,yEAAyE;IACzE,yFAAyF;IACzF,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,KAAK,EAAE;QACzD,GAAG,EAAE,OAAO;QACZ,SAAS,EAAE,SAAS,IAAI,IAAI,EAAE,SAAS;KACxC,CAAC,CAAC;IACH,sBAAsB,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;AAClD,CAAC,CAAC;AAEF,8EAA8E;AAC9E,eAAe;AACf,8EAA8E;AAE9E;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,GAAS,EACT,YAGwD,EAClD,EAAE;IACR,MAAM,YAAY,GAChB,OAAO,YAAY,KAAK,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC;IACzE,MAAM,YAAY,GAAI,GAAG,CAAC,IAAI,EAAyC;SACpE,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAClB,GAAG,QAAQ;QACX,QAAQ,EAAE,mBAAmB,CAAC,QAAQ,CAAC;KACxC,CAAC,CAAC;SACF,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACtD,MAAM,YAAY,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC;IACxE,MAAM,iBAAiB,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAE3E,uCAAuC;IACvC,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE;YACvC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;YAC/B,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,OAAO;YACT,CAAC;YAED,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CACtB,gBAAgB,EAChB,KAAK,EAAE,OAAuC,EAAE,EAAE;gBAChD,MAAM,QAAQ,GAAG,6BAA6B,CAAC,YAAY,EAAE,CAAC,CAAC;gBAC/D,MAAM,SAAS,GAAG,sBAAsB,CACtC,MAAM,mBAAmB,CAAC,GAAG,CAAC,EAC9B,QAAQ,CAAC,GAAG,EACZ,QAAQ,CAAC,SAAS,CACnB,CAAC;gBACF,MAAM,OAAO,GAAG,gBAAgB,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;gBAC/C,MAAM,UAAU,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;YACrE,CAAC,CACF,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;IAED,8DAA8D;IAC9D,EAAE;IACF,yEAAyE;IACzE,kEAAkE;IAClE,wEAAwE;IACxE,sEAAsE;IACtE,oEAAoE;IACpE,iEAAiE;IACjE,kEAAkE;IAClE,IAAI,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACjC,QAAQ,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE;YAC5C,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;YAC/B,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,OAAO;YACT,CAAC;YAED,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAU,CAAC;YAC7C,MAAM,mBAAmB,GAAG,QAAQ,CAAC,IAAI,CACvC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,gBAAgB,CAAC,OAAO,CAAC,CACxC,CAAC;YAEF,mEAAmE;YACnE,oEAAoE;YACpE,4DAA4D;YAC5D,oCAAoC;YACpC,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;YACtC,MAAM,gBAAgB,GAAG,CACvB,OAAuC,EAC1B,EAAE,CACf,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,kBAAkB,CAAC;YAE/D,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CACtB,gBAAgB,EAChB,KAAK,EAAE,OAAuC,EAAE,EAAE;gBAChD,MAAM,QAAQ,GAAG,6BAA6B,CAAC,YAAY,EAAE,CAAC,CAAC;gBAC/D,MAAM,SAAS,GAAG,sBAAsB,CACtC,MAAM,mBAAmB,CAAC,GAAG,CAAC,EAC9B,QAAQ,CAAC,GAAG,EACZ,QAAQ,CAAC,SAAS,CACnB,CAAC;gBACF,MAAM,OAAO,GAAG,gBAAgB,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;gBAC/C,MAAM,qBAAqB,CACzB,CAAC,EACD,OAAO,EACP,MAAM,EACN,OAAO,EACP,gBAAgB,CAAC,OAAO,CAAC,EACzB,GAAG,EACH,SAAS,EACT,QAAQ,CACT,CAAC;YACJ,CAAC,CACF,CAAC;YAEF,IAAI,mBAAmB,EAAE,CAAC;gBACxB,IAAI,CAAC,mBAAmB,EAAE,GAAG,EAAE;oBAC7B,MAAM,SAAS,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,CAChC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,kBAAkB,CAAC,GAAG,CAAC,EAAE,CAAC,CACpC,CAAC;oBACF,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;gBAChC,CAAC,CAAC,CAAC;YACL,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC"}
|
package/dist/harness-cli.d.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CLI integration test harness.
|
|
3
|
-
*
|
|
4
|
-
* Builds CLI commands from a graph, executes them in-process,
|
|
5
|
-
* and captures stdout/stderr.
|
|
6
|
-
*/
|
|
7
|
-
import type { CliHarness, CliHarnessOptions } from './types.js';
|
|
8
|
-
/**
|
|
9
|
-
* Create a CLI harness for integration testing.
|
|
10
|
-
*
|
|
11
|
-
* Builds commands from the graph's topo and provides a `run()` method
|
|
12
|
-
* that parses command strings and executes them in-process.
|
|
13
|
-
*
|
|
14
|
-
* ```ts
|
|
15
|
-
* const harness = createCliHarness({ graph });
|
|
16
|
-
* const result = await harness.run("entity show --name Alpha --output json");
|
|
17
|
-
* expect(result.exitCode).toBe(0);
|
|
18
|
-
* ```
|
|
19
|
-
*/
|
|
20
|
-
export declare const createCliHarness: (options: CliHarnessOptions) => CliHarness;
|
|
21
|
-
//# sourceMappingURL=harness-cli.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"harness-cli.d.ts","sourceRoot":"","sources":["../src/harness-cli.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,OAAO,KAAK,EACV,UAAU,EACV,iBAAiB,EAElB,MAAM,YAAY,CAAC;AA8PpB;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,gBAAgB,GAAI,SAAS,iBAAiB,KAAG,UAW7D,CAAC"}
|