@ontrails/testing 1.0.0-beta.14 → 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 +69 -0
- package/README.md +12 -12
- package/package.json +15 -6
- package/src/all.ts +153 -16
- package/src/assertions.ts +253 -0
- package/src/context.ts +67 -38
- package/src/contracts.ts +15 -24
- package/src/crosses.ts +93 -51
- package/src/detours.ts +155 -18
- package/src/effective-examples.ts +350 -0
- package/src/examples.ts +139 -63
- package/src/harness-cli.ts +19 -11
- package/src/harness-mcp.ts +9 -8
- package/src/index.ts +14 -4
- package/src/logger.ts +3 -1
- package/src/scenario.ts +368 -0
- package/src/signals.ts +221 -0
- package/src/types.ts +64 -6
- 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 -31
- package/dist/all.d.ts.map +0 -1
- package/dist/all.js +0 -47
- package/dist/all.js.map +0 -1
- package/dist/assertions.d.ts +0 -49
- package/dist/assertions.d.ts.map +0 -1
- package/dist/assertions.js +0 -84
- package/dist/assertions.js.map +0 -1
- package/dist/context.d.ts +0 -75
- package/dist/context.d.ts.map +0 -1
- package/dist/context.js +0 -107
- 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 -71
- 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 -213
- package/dist/crosses.js.map +0 -1
- package/dist/detours.d.ts +0 -12
- package/dist/detours.d.ts.map +0 -1
- package/dist/detours.js +0 -30
- package/dist/detours.js.map +0 -1
- package/dist/examples.d.ts +0 -23
- package/dist/examples.d.ts.map +0 -1
- package/dist/examples.js +0 -202
- package/dist/examples.js.map +0 -1
- package/dist/follows.d.ts +0 -38
- package/dist/follows.d.ts.map +0 -1
- package/dist/follows.js +0 -212
- package/dist/follows.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 -200
- 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 -53
- package/dist/harness-mcp.js.map +0 -1
- package/dist/index.d.ts +0 -16
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -16
- 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/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 -80
- 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 -135
- package/src/__tests__/context.test.ts +0 -150
- package/src/__tests__/contracts.test.ts +0 -185
- package/src/__tests__/crosses.test.ts +0 -587
- package/src/__tests__/detours.test.ts +0 -55
- package/src/__tests__/examples.test.ts +0 -534
- package/src/__tests__/harness-cli.test.ts +0 -66
- package/src/__tests__/logger.test.ts +0 -136
- package/src/__tests__/trail.test.ts +0 -99
- package/tsconfig.json +0 -9
- package/tsconfig.tsbuildinfo +0 -1
package/dist/all.d.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* testAll — single-line governance suite for any Topo.
|
|
3
|
-
*
|
|
4
|
-
* Wraps topo validation, example execution, contract checks, and detour
|
|
5
|
-
* verification into one describe block.
|
|
6
|
-
*/
|
|
7
|
-
import type { Topo, TrailContext } from '@ontrails/core';
|
|
8
|
-
import type { TestExecutionOptions } from './context.js';
|
|
9
|
-
/**
|
|
10
|
-
* Run the full governance test suite for a Topo.
|
|
11
|
-
*
|
|
12
|
-
* Generates a `governance` describe block containing:
|
|
13
|
-
* - Structural validation via `validateTopo`
|
|
14
|
-
* - Example execution via `testExamples`
|
|
15
|
-
* - Output contract checks via `testContracts`
|
|
16
|
-
* - Detour target verification via `testDetours`
|
|
17
|
-
*
|
|
18
|
-
* Accepts either a static context or a factory function that produces a
|
|
19
|
-
* fresh context per test (useful when the context contains mutable state
|
|
20
|
-
* like an in-memory store).
|
|
21
|
-
*
|
|
22
|
-
* @example
|
|
23
|
-
* ```ts
|
|
24
|
-
* import { testAll } from '@ontrails/testing';
|
|
25
|
-
* import { app } from '../src/app.js';
|
|
26
|
-
*
|
|
27
|
-
* testAll(app);
|
|
28
|
-
* ```
|
|
29
|
-
*/
|
|
30
|
-
export declare const testAll: (topo: Topo, ctxOrFactory?: Partial<TrailContext> | TestExecutionOptions | (() => Partial<TrailContext> | TestExecutionOptions)) => void;
|
|
31
|
-
//# sourceMappingURL=all.d.ts.map
|
package/dist/all.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
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
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* testAll — single-line governance suite for any Topo.
|
|
3
|
-
*
|
|
4
|
-
* Wraps topo validation, example execution, contract checks, and detour
|
|
5
|
-
* verification into one describe block.
|
|
6
|
-
*/
|
|
7
|
-
import { describe, expect, test } from 'bun:test';
|
|
8
|
-
import { validateTopo } from '@ontrails/core';
|
|
9
|
-
import { testContracts } from './contracts.js';
|
|
10
|
-
import { testDetours } from './detours.js';
|
|
11
|
-
import { testExamples } from './examples.js';
|
|
12
|
-
/**
|
|
13
|
-
* Run the full governance test suite for a Topo.
|
|
14
|
-
*
|
|
15
|
-
* Generates a `governance` describe block containing:
|
|
16
|
-
* - Structural validation via `validateTopo`
|
|
17
|
-
* - Example execution via `testExamples`
|
|
18
|
-
* - Output contract checks via `testContracts`
|
|
19
|
-
* - Detour target verification via `testDetours`
|
|
20
|
-
*
|
|
21
|
-
* Accepts either a static context or a factory function that produces a
|
|
22
|
-
* fresh context per test (useful when the context contains mutable state
|
|
23
|
-
* like an in-memory store).
|
|
24
|
-
*
|
|
25
|
-
* @example
|
|
26
|
-
* ```ts
|
|
27
|
-
* import { testAll } from '@ontrails/testing';
|
|
28
|
-
* import { app } from '../src/app.js';
|
|
29
|
-
*
|
|
30
|
-
* testAll(app);
|
|
31
|
-
* ```
|
|
32
|
-
*/
|
|
33
|
-
export const testAll = (topo, ctxOrFactory) => {
|
|
34
|
-
describe('governance', () => {
|
|
35
|
-
test('topo validates', () => {
|
|
36
|
-
const result = validateTopo(topo);
|
|
37
|
-
expect(result.isOk()).toBe(true);
|
|
38
|
-
});
|
|
39
|
-
// oxlint-disable-next-line jest/require-hook -- these generate describe/test blocks, not setup code
|
|
40
|
-
testExamples(topo, ctxOrFactory);
|
|
41
|
-
// oxlint-disable-next-line jest/require-hook -- these generate describe/test blocks, not setup code
|
|
42
|
-
testContracts(topo, ctxOrFactory);
|
|
43
|
-
// oxlint-disable-next-line jest/require-hook -- these generate describe/test blocks, not setup code
|
|
44
|
-
testDetours(topo);
|
|
45
|
-
});
|
|
46
|
-
};
|
|
47
|
-
//# sourceMappingURL=all.js.map
|
package/dist/all.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
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/assertions.d.ts
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Progressive assertion logic for example-driven testing.
|
|
3
|
-
*
|
|
4
|
-
* Three tiers:
|
|
5
|
-
* 1. Full match — example has `expected` output
|
|
6
|
-
* 2. Schema-only — no expected output, no error
|
|
7
|
-
* 3. Error match — example declares an error class name
|
|
8
|
-
*/
|
|
9
|
-
import type { Result } from '@ontrails/core';
|
|
10
|
-
import type { z } from 'zod';
|
|
11
|
-
/**
|
|
12
|
-
* Assert that a Result is Ok and return its value.
|
|
13
|
-
*
|
|
14
|
-
* Eliminates the `if (result.isOk())` / `as unknown as` dance in tests.
|
|
15
|
-
*
|
|
16
|
-
* @example
|
|
17
|
-
* ```typescript
|
|
18
|
-
* const value = expectOk(result);
|
|
19
|
-
* expect(value.name).toBe('Alice');
|
|
20
|
-
* ```
|
|
21
|
-
*/
|
|
22
|
-
export declare const expectOk: <T, E>(result: Result<T, E>) => T;
|
|
23
|
-
/**
|
|
24
|
-
* Assert that a Result is Err and return its error.
|
|
25
|
-
*
|
|
26
|
-
* Eliminates the `if (result.isErr())` / `as unknown as` dance in tests.
|
|
27
|
-
*
|
|
28
|
-
* @example
|
|
29
|
-
* ```typescript
|
|
30
|
-
* const error = expectErr(result);
|
|
31
|
-
* expect(error).toBeInstanceOf(ValidationError);
|
|
32
|
-
* ```
|
|
33
|
-
*/
|
|
34
|
-
export declare const expectErr: <T, E>(result: Result<T, E>) => E;
|
|
35
|
-
/**
|
|
36
|
-
* Assert that the result is ok and its value deep-equals the expected output.
|
|
37
|
-
*/
|
|
38
|
-
export declare const assertFullMatch: (result: Result<unknown, Error>, expected: unknown) => void;
|
|
39
|
-
/**
|
|
40
|
-
* Assert that the result is ok and, if an output schema is provided,
|
|
41
|
-
* the value parses against it.
|
|
42
|
-
*/
|
|
43
|
-
export declare const assertSchemaMatch: (result: Result<unknown, Error>, outputSchema: z.ZodType | undefined) => void;
|
|
44
|
-
/**
|
|
45
|
-
* Assert that the result is an error of the specified type, with optional
|
|
46
|
-
* message substring matching.
|
|
47
|
-
*/
|
|
48
|
-
export declare const assertErrorMatch: (result: Result<unknown, Error>, expectedError: new (...args: never[]) => Error, expectedMessage?: string) => void;
|
|
49
|
-
//# sourceMappingURL=assertions.d.ts.map
|
package/dist/assertions.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"assertions.d.ts","sourceRoot":"","sources":["../src/assertions.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAE7C,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAM7B;;;;;;;;;;GAUG;AACH,eAAO,MAAM,QAAQ,GAAI,CAAC,EAAE,CAAC,EAAE,QAAQ,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,KAAG,CAGrD,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,SAAS,GAAI,CAAC,EAAE,CAAC,EAAE,QAAQ,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,KAAG,CAGtD,CAAC;AAMF;;GAEG;AACH,eAAO,MAAM,eAAe,GAC1B,QAAQ,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,EAC9B,UAAU,OAAO,KAChB,IAGF,CAAC;AAMF;;;GAGG;AACH,eAAO,MAAM,iBAAiB,GAC5B,QAAQ,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,EAC9B,cAAc,CAAC,CAAC,OAAO,GAAG,SAAS,KAClC,IAUF,CAAC;AAMF;;;GAGG;AACH,eAAO,MAAM,gBAAgB,GAC3B,QAAQ,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,EAC9B,eAAe,KAAK,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,KAAK,EAC9C,kBAAkB,MAAM,KACvB,IAMF,CAAC"}
|
package/dist/assertions.js
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Progressive assertion logic for example-driven testing.
|
|
3
|
-
*
|
|
4
|
-
* Three tiers:
|
|
5
|
-
* 1. Full match — example has `expected` output
|
|
6
|
-
* 2. Schema-only — no expected output, no error
|
|
7
|
-
* 3. Error match — example declares an error class name
|
|
8
|
-
*/
|
|
9
|
-
import { expect } from 'bun:test';
|
|
10
|
-
import { formatZodIssues } from '@ontrails/core';
|
|
11
|
-
// ---------------------------------------------------------------------------
|
|
12
|
-
// Result narrowing helpers
|
|
13
|
-
// ---------------------------------------------------------------------------
|
|
14
|
-
/**
|
|
15
|
-
* Assert that a Result is Ok and return its value.
|
|
16
|
-
*
|
|
17
|
-
* Eliminates the `if (result.isOk())` / `as unknown as` dance in tests.
|
|
18
|
-
*
|
|
19
|
-
* @example
|
|
20
|
-
* ```typescript
|
|
21
|
-
* const value = expectOk(result);
|
|
22
|
-
* expect(value.name).toBe('Alice');
|
|
23
|
-
* ```
|
|
24
|
-
*/
|
|
25
|
-
export const expectOk = (result) => {
|
|
26
|
-
expect(result.isOk()).toBe(true);
|
|
27
|
-
return result.value;
|
|
28
|
-
};
|
|
29
|
-
/**
|
|
30
|
-
* Assert that a Result is Err and return its error.
|
|
31
|
-
*
|
|
32
|
-
* Eliminates the `if (result.isErr())` / `as unknown as` dance in tests.
|
|
33
|
-
*
|
|
34
|
-
* @example
|
|
35
|
-
* ```typescript
|
|
36
|
-
* const error = expectErr(result);
|
|
37
|
-
* expect(error).toBeInstanceOf(ValidationError);
|
|
38
|
-
* ```
|
|
39
|
-
*/
|
|
40
|
-
export const expectErr = (result) => {
|
|
41
|
-
expect(result.isErr()).toBe(true);
|
|
42
|
-
return result.error;
|
|
43
|
-
};
|
|
44
|
-
// ---------------------------------------------------------------------------
|
|
45
|
-
// Full Match
|
|
46
|
-
// ---------------------------------------------------------------------------
|
|
47
|
-
/**
|
|
48
|
-
* Assert that the result is ok and its value deep-equals the expected output.
|
|
49
|
-
*/
|
|
50
|
-
export const assertFullMatch = (result, expected) => {
|
|
51
|
-
const value = expectOk(result);
|
|
52
|
-
expect(value).toEqual(expected);
|
|
53
|
-
};
|
|
54
|
-
// ---------------------------------------------------------------------------
|
|
55
|
-
// Schema-Only Match
|
|
56
|
-
// ---------------------------------------------------------------------------
|
|
57
|
-
/**
|
|
58
|
-
* Assert that the result is ok and, if an output schema is provided,
|
|
59
|
-
* the value parses against it.
|
|
60
|
-
*/
|
|
61
|
-
export const assertSchemaMatch = (result, outputSchema) => {
|
|
62
|
-
const value = expectOk(result);
|
|
63
|
-
if (outputSchema !== undefined) {
|
|
64
|
-
const parsed = outputSchema.safeParse(value);
|
|
65
|
-
if (!parsed.success) {
|
|
66
|
-
throw new Error(`Output does not match schema: ${formatZodIssues(parsed.error.issues).join('; ')}`);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
};
|
|
70
|
-
// ---------------------------------------------------------------------------
|
|
71
|
-
// Error Match
|
|
72
|
-
// ---------------------------------------------------------------------------
|
|
73
|
-
/**
|
|
74
|
-
* Assert that the result is an error of the specified type, with optional
|
|
75
|
-
* message substring matching.
|
|
76
|
-
*/
|
|
77
|
-
export const assertErrorMatch = (result, expectedError, expectedMessage) => {
|
|
78
|
-
const error = expectErr(result);
|
|
79
|
-
expect(error).toBeInstanceOf(expectedError);
|
|
80
|
-
if (expectedMessage !== undefined) {
|
|
81
|
-
expect(error.message).toContain(expectedMessage);
|
|
82
|
-
}
|
|
83
|
-
};
|
|
84
|
-
//# sourceMappingURL=assertions.js.map
|
package/dist/assertions.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"assertions.js","sourceRoot":"","sources":["../src/assertions.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAGlC,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAGjD,8EAA8E;AAC9E,2BAA2B;AAC3B,8EAA8E;AAE9E;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAO,MAAoB,EAAK,EAAE;IACxD,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjC,OAAQ,MAAkC,CAAC,KAAK,CAAC;AACnD,CAAC,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAO,MAAoB,EAAK,EAAE;IACzD,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClC,OAAQ,MAAkC,CAAC,KAAK,CAAC;AACnD,CAAC,CAAC;AAEF,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAC7B,MAA8B,EAC9B,QAAiB,EACX,EAAE;IACR,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC/B,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;AAClC,CAAC,CAAC;AAEF,8EAA8E;AAC9E,oBAAoB;AACpB,8EAA8E;AAE9E;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,MAA8B,EAC9B,YAAmC,EAC7B,EAAE;IACR,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC/B,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,YAAY,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAC7C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CACb,iCAAiC,eAAe,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACnF,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC,CAAC;AAEF,8EAA8E;AAC9E,cAAc;AACd,8EAA8E;AAE9E;;;GAGG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,MAA8B,EAC9B,aAA8C,EAC9C,eAAwB,EAClB,EAAE;IACR,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;IAChC,MAAM,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC;IAC5C,IAAI,eAAe,KAAK,SAAS,EAAE,CAAC;QAClC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;IACnD,CAAC;AACH,CAAC,CAAC"}
|
package/dist/context.d.ts
DELETED
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Test context factory for creating TrailContext instances suitable for testing.
|
|
3
|
-
*/
|
|
4
|
-
import type { CrossFn, ProvisionOverrideMap, Topo, TrailContext } from '@ontrails/core';
|
|
5
|
-
import { Result } from '@ontrails/core';
|
|
6
|
-
import type { TestTrailContextOptions } from './types.js';
|
|
7
|
-
/**
|
|
8
|
-
* Create a TrailContext with deterministic, test-friendly defaults.
|
|
9
|
-
*
|
|
10
|
-
* - `requestId`: `"test-request-001"` (deterministic)
|
|
11
|
-
* - `logger`: a `TestLogger` that captures entries
|
|
12
|
-
* - `abortSignal`: a non-aborted AbortController signal
|
|
13
|
-
*/
|
|
14
|
-
export declare const createTestContext: (overrides?: TestTrailContextOptions) => TrailContext;
|
|
15
|
-
export interface CreateCrossContextOptions {
|
|
16
|
-
readonly responses?: Record<string, Result<unknown, Error>> | undefined;
|
|
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
|
-
}
|
|
29
|
-
export interface TestExecutionOptions {
|
|
30
|
-
readonly ctx?: Partial<TrailContext> | 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;
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* Create a mock `CrossFn` for testing composite trails.
|
|
49
|
-
*
|
|
50
|
-
* Returns preconfigured `Result` values keyed by trail ID. Calls to
|
|
51
|
-
* unregistered IDs return `Result.err` with a descriptive message.
|
|
52
|
-
*
|
|
53
|
-
* @example
|
|
54
|
-
* ```ts
|
|
55
|
-
* const cross = createCrossContext({
|
|
56
|
-
* responses: { 'entity.add': Result.ok({ id: '1', name: 'Alpha' }) },
|
|
57
|
-
* });
|
|
58
|
-
* const ctx = { ...createTestContext(), cross };
|
|
59
|
-
* ```
|
|
60
|
-
*/
|
|
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;
|
|
67
|
-
export declare const normalizeTestExecutionOptions: (input?: Partial<TrailContext> | TestExecutionOptions) => TestExecutionOptions;
|
|
68
|
-
export declare const mergeProvisionOverrides: (autoResolved: ProvisionOverrideMap, ctx: Partial<TrailContext> | undefined, explicit: ProvisionOverrideMap | undefined) => ProvisionOverrideMap;
|
|
69
|
-
export declare const resolveMockProvisions: (app: Topo) => Promise<ProvisionOverrideMap>;
|
|
70
|
-
/**
|
|
71
|
-
* Merge a Partial<TrailContext> into a test context.
|
|
72
|
-
* Used internally when the public API accepts Partial<TrailContext>.
|
|
73
|
-
*/
|
|
74
|
-
export declare const mergeTestContext: (ctx?: Partial<TrailContext>, provisions?: ProvisionOverrideMap) => TrailContext;
|
|
75
|
-
//# sourceMappingURL=context.d.ts.map
|
package/dist/context.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
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
DELETED
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Test context factory for creating TrailContext instances suitable for testing.
|
|
3
|
-
*/
|
|
4
|
-
import { Result, createProvisionLookup } from '@ontrails/core';
|
|
5
|
-
import { createTestLogger } from './logger.js';
|
|
6
|
-
// ---------------------------------------------------------------------------
|
|
7
|
-
// createTestContext
|
|
8
|
-
// ---------------------------------------------------------------------------
|
|
9
|
-
/**
|
|
10
|
-
* Create a TrailContext with deterministic, test-friendly defaults.
|
|
11
|
-
*
|
|
12
|
-
* - `requestId`: `"test-request-001"` (deterministic)
|
|
13
|
-
* - `logger`: a `TestLogger` that captures entries
|
|
14
|
-
* - `abortSignal`: a non-aborted AbortController signal
|
|
15
|
-
*/
|
|
16
|
-
export const createTestContext = (overrides) => {
|
|
17
|
-
const cwd = overrides?.cwd ?? process.cwd();
|
|
18
|
-
const ctx = {
|
|
19
|
-
abortSignal: overrides?.abortSignal ?? new AbortController().signal,
|
|
20
|
-
cwd,
|
|
21
|
-
env: overrides?.env ?? { TRAILS_ENV: 'test' },
|
|
22
|
-
extensions: undefined,
|
|
23
|
-
logger: overrides?.logger ?? createTestLogger(),
|
|
24
|
-
requestId: overrides?.requestId ?? 'test-request-001',
|
|
25
|
-
workspaceRoot: cwd,
|
|
26
|
-
};
|
|
27
|
-
const lookup = createProvisionLookup(() => ctx);
|
|
28
|
-
ctx.provision = lookup;
|
|
29
|
-
return ctx;
|
|
30
|
-
};
|
|
31
|
-
/**
|
|
32
|
-
* Create a mock `CrossFn` for testing composite trails.
|
|
33
|
-
*
|
|
34
|
-
* Returns preconfigured `Result` values keyed by trail ID. Calls to
|
|
35
|
-
* unregistered IDs return `Result.err` with a descriptive message.
|
|
36
|
-
*
|
|
37
|
-
* @example
|
|
38
|
-
* ```ts
|
|
39
|
-
* const cross = createCrossContext({
|
|
40
|
-
* responses: { 'entity.add': Result.ok({ id: '1', name: 'Alpha' }) },
|
|
41
|
-
* });
|
|
42
|
-
* const ctx = { ...createTestContext(), cross };
|
|
43
|
-
* ```
|
|
44
|
-
*/
|
|
45
|
-
export const createCrossContext = (options) => {
|
|
46
|
-
const responses = options?.responses ?? {};
|
|
47
|
-
return (id, _input) => {
|
|
48
|
-
const response = responses[id];
|
|
49
|
-
if (response === undefined) {
|
|
50
|
-
return Promise.resolve(Result.err(new Error(`No mock response for cross("${id}")`)));
|
|
51
|
-
}
|
|
52
|
-
return Promise.resolve(response);
|
|
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
|
-
};
|
|
65
|
-
const isTestExecutionOptions = (input) => input !== undefined &&
|
|
66
|
-
(Object.hasOwn(input, 'ctx') ||
|
|
67
|
-
Object.hasOwn(input, 'provisions') ||
|
|
68
|
-
Object.hasOwn(input, 'strictPermits') ||
|
|
69
|
-
Object.hasOwn(input, 'mintPermit'));
|
|
70
|
-
export const normalizeTestExecutionOptions = (input) => isTestExecutionOptions(input) ? input : { ctx: input };
|
|
71
|
-
export const mergeProvisionOverrides = (autoResolved, ctx, explicit) => ({
|
|
72
|
-
...autoResolved,
|
|
73
|
-
...ctx?.extensions,
|
|
74
|
-
...explicit,
|
|
75
|
-
});
|
|
76
|
-
const buildMockProvisions = async (app) => {
|
|
77
|
-
const provisions = {};
|
|
78
|
-
for (const declaredProvision of app.listProvisions()) {
|
|
79
|
-
if (!declaredProvision.mock) {
|
|
80
|
-
continue;
|
|
81
|
-
}
|
|
82
|
-
provisions[declaredProvision.id] = await declaredProvision.mock();
|
|
83
|
-
}
|
|
84
|
-
return provisions;
|
|
85
|
-
};
|
|
86
|
-
export const resolveMockProvisions = async (app) => await buildMockProvisions(app);
|
|
87
|
-
/**
|
|
88
|
-
* Merge a Partial<TrailContext> into a test context.
|
|
89
|
-
* Used internally when the public API accepts Partial<TrailContext>.
|
|
90
|
-
*/
|
|
91
|
-
export const mergeTestContext = (ctx, provisions) => {
|
|
92
|
-
const base = createTestContext();
|
|
93
|
-
const extensions = {
|
|
94
|
-
...base.extensions,
|
|
95
|
-
...ctx?.extensions,
|
|
96
|
-
...provisions,
|
|
97
|
-
};
|
|
98
|
-
const merged = {
|
|
99
|
-
...base,
|
|
100
|
-
...ctx,
|
|
101
|
-
extensions: Object.keys(extensions).length === 0 ? undefined : extensions,
|
|
102
|
-
};
|
|
103
|
-
const lookup = createProvisionLookup(() => merged);
|
|
104
|
-
merged.provision = lookup;
|
|
105
|
-
return merged;
|
|
106
|
-
};
|
|
107
|
-
//# sourceMappingURL=context.js.map
|
package/dist/context.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH,OAAO,EAAE,MAAM,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAE/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAO/C,8EAA8E;AAC9E,oBAAoB;AACpB,8EAA8E;AAE9E;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,SAAmC,EACrB,EAAE;IAChB,MAAM,GAAG,GAAG,SAAS,EAAE,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAC5C,MAAM,GAAG,GAAG;QACV,WAAW,EAAE,SAAS,EAAE,WAAW,IAAI,IAAI,eAAe,EAAE,CAAC,MAAM;QACnE,GAAG;QACH,GAAG,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE;QAC7C,UAAU,EAAE,SAAS;QACrB,MAAM,EAAE,SAAS,EAAE,MAAM,IAAI,gBAAgB,EAAE;QAC/C,SAAS,EAAE,SAAS,EAAE,SAAS,IAAI,kBAAkB;QACrD,aAAa,EAAE,GAAG;KACI,CAAC;IACzB,MAAM,MAAM,GAAG,qBAAqB,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;IAChD,GAAG,CAAC,SAAS,GAAG,MAAM,CAAC;IACvB,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;AA2CF;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,OAAmC,EAC1B,EAAE;IACX,MAAM,SAAS,GAAG,OAAO,EAAE,SAAS,IAAI,EAAE,CAAC;IAC3C,OAAO,CAAI,EAAU,EAAE,MAAe,EAA6B,EAAE;QACnE,MAAM,QAAQ,GAAG,SAAS,CAAC,EAAE,CAAC,CAAC;QAC/B,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,OAAO,OAAO,CAAC,OAAO,CACpB,MAAM,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,+BAA+B,EAAE,IAAI,CAAC,CAG1D,CACF,CAAC;QACJ,CAAC;QACD,OAAO,OAAO,CAAC,OAAO,CAAC,QAA4B,CAAC,CAAC;IACvD,CAAC,CAAC;AACJ,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,KAAoB,EACM,EAAE;IAC5B,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/C,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,aAAa,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;AAC5D,CAAC,CAAC;AAEF,MAAM,sBAAsB,GAAG,CAC7B,KAA+D,EAChC,EAAE,CACjC,KAAK,KAAK,SAAS;IACnB,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC;QAC1B,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,YAAY,CAAC;QAClC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,eAAe,CAAC;QACrC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC;AAExC,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAC3C,KAAoD,EAC9B,EAAE,CACxB,sBAAsB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;AAEzD,MAAM,CAAC,MAAM,uBAAuB,GAAG,CACrC,YAAkC,EAClC,GAAsC,EACtC,QAA0C,EACpB,EAAE,CAAC,CAAC;IAC1B,GAAG,YAAY;IACf,GAAG,GAAG,EAAE,UAAU;IAClB,GAAG,QAAQ;CACZ,CAAC,CAAC;AAEH,MAAM,mBAAmB,GAAG,KAAK,EAC/B,GAAS,EACsB,EAAE;IACjC,MAAM,UAAU,GAA4B,EAAE,CAAC;IAC/C,KAAK,MAAM,iBAAiB,IAAI,GAAG,CAAC,cAAc,EAAE,EAAE,CAAC;QACrD,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,CAAC;YAC5B,SAAS;QACX,CAAC;QACD,UAAU,CAAC,iBAAiB,CAAC,EAAE,CAAC,GAAG,MAAM,iBAAiB,CAAC,IAAI,EAAE,CAAC;IACpE,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,EACxC,GAAS,EACsB,EAAE,CAAC,MAAM,mBAAmB,CAAC,GAAG,CAAC,CAAC;AAEnE;;;GAGG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,GAA2B,EAC3B,UAAiC,EACnB,EAAE;IAChB,MAAM,IAAI,GAAG,iBAAiB,EAAE,CAAC;IACjC,MAAM,UAAU,GAAG;QACjB,GAAG,IAAI,CAAC,UAAU;QAClB,GAAG,GAAG,EAAE,UAAU;QAClB,GAAG,UAAU;KACd,CAAC;IACF,MAAM,MAAM,GAAG;QACb,GAAG,IAAI;QACP,GAAG,GAAG;QACN,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU;KACnD,CAAC;IACzB,MAAM,MAAM,GAAG,qBAAqB,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC;IACnD,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC;IAC1B,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC"}
|
package/dist/contracts.d.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* testContracts — output schema verification.
|
|
3
|
-
*
|
|
4
|
-
* For every trail that has both examples and an output schema,
|
|
5
|
-
* run each example and validate the implementation output against
|
|
6
|
-
* the declared schema.
|
|
7
|
-
*/
|
|
8
|
-
import type { Topo, TrailContext } from '@ontrails/core';
|
|
9
|
-
import type { TestExecutionOptions } from './context.js';
|
|
10
|
-
/**
|
|
11
|
-
* Verify that every trail implementation output matches its declared
|
|
12
|
-
* output schema. Catches implementation-schema drift.
|
|
13
|
-
*
|
|
14
|
-
* Trails without output schemas or examples are skipped.
|
|
15
|
-
*/
|
|
16
|
-
export declare const testContracts: (app: Topo, ctxOrFactory?: Partial<TrailContext> | TestExecutionOptions | (() => Partial<TrailContext> | TestExecutionOptions)) => void;
|
|
17
|
-
//# sourceMappingURL=contracts.d.ts.map
|
package/dist/contracts.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
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
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* testContracts — output schema verification.
|
|
3
|
-
*
|
|
4
|
-
* For every trail that has both examples and an output schema,
|
|
5
|
-
* run each example and validate the implementation output against
|
|
6
|
-
* the declared schema.
|
|
7
|
-
*/
|
|
8
|
-
import { describe, test } from 'bun:test';
|
|
9
|
-
import { executeTrail, formatZodIssues, validateInput } from '@ontrails/core';
|
|
10
|
-
import { expectOk } from './assertions.js';
|
|
11
|
-
import { mergeProvisionOverrides, mergeTestContext, normalizeTestExecutionOptions, resolveMockProvisions, } from './context.js';
|
|
12
|
-
// ---------------------------------------------------------------------------
|
|
13
|
-
// Helpers
|
|
14
|
-
// ---------------------------------------------------------------------------
|
|
15
|
-
/** Check if a trail requires cross() but the context doesn't provide it. */
|
|
16
|
-
const needsCrossContext = (t, resolveCtx) => {
|
|
17
|
-
const spec = t;
|
|
18
|
-
if (!spec.crosses || spec.crosses.length === 0) {
|
|
19
|
-
return false;
|
|
20
|
-
}
|
|
21
|
-
return !normalizeTestExecutionOptions(resolveCtx()).ctx?.cross;
|
|
22
|
-
};
|
|
23
|
-
const validateOutputSchema = (outputSchema, value, trailId, exampleName) => {
|
|
24
|
-
const parsed = outputSchema.safeParse(value);
|
|
25
|
-
if (!parsed.success) {
|
|
26
|
-
const issues = formatZodIssues(parsed.error.issues);
|
|
27
|
-
throw new Error(`Output schema violation for trail "${trailId}", example "${exampleName}":\n${issues.map((i) => ` - ${i}`).join('\n')}\n\nActual output: ${JSON.stringify(value, null, 2)}`);
|
|
28
|
-
}
|
|
29
|
-
};
|
|
30
|
-
// ---------------------------------------------------------------------------
|
|
31
|
-
// testContracts
|
|
32
|
-
// ---------------------------------------------------------------------------
|
|
33
|
-
/**
|
|
34
|
-
* Verify that every trail implementation output matches its declared
|
|
35
|
-
* output schema. Catches implementation-schema drift.
|
|
36
|
-
*
|
|
37
|
-
* Trails without output schemas or examples are skipped.
|
|
38
|
-
*/
|
|
39
|
-
export const testContracts = (app, ctxOrFactory) => {
|
|
40
|
-
const resolveInput = typeof ctxOrFactory === 'function' ? ctxOrFactory : () => ctxOrFactory;
|
|
41
|
-
const allEntries = app.list();
|
|
42
|
-
describe('contracts', () => {
|
|
43
|
-
describe.each(allEntries)('$id', (t) => {
|
|
44
|
-
if (t.output === undefined) {
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
if (t.examples === undefined || t.examples.length === 0) {
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
if (needsCrossContext(t, resolveInput)) {
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
const { examples, output: outputSchema } = t;
|
|
54
|
-
const successExamples = examples.filter((e) => e.error === undefined);
|
|
55
|
-
test.each(successExamples)('contract: $name', async (example) => {
|
|
56
|
-
const resolved = normalizeTestExecutionOptions(resolveInput());
|
|
57
|
-
const provisions = mergeProvisionOverrides(await resolveMockProvisions(app), resolved.ctx, resolved.provisions);
|
|
58
|
-
const testCtx = mergeTestContext(resolved.ctx);
|
|
59
|
-
const validated = validateInput(t.input, example.input);
|
|
60
|
-
expectOk(validated);
|
|
61
|
-
const result = await executeTrail(t, example.input, {
|
|
62
|
-
ctx: testCtx,
|
|
63
|
-
provisions,
|
|
64
|
-
});
|
|
65
|
-
const resultValue = expectOk(result);
|
|
66
|
-
validateOutputSchema(outputSchema, resultValue, t.id, example.name);
|
|
67
|
-
});
|
|
68
|
-
});
|
|
69
|
-
});
|
|
70
|
-
};
|
|
71
|
-
//# sourceMappingURL=contracts.js.map
|
package/dist/contracts.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"contracts.js","sourceRoot":"","sources":["../src/contracts.ts"],"names":[],"mappings":"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"}
|
package/dist/crosses.d.ts
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
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
|
package/dist/crosses.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
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"}
|