@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
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
import { describe, test } from 'bun:test';
|
|
2
|
-
|
|
3
|
-
import { Result, provision, trail, topo } from '@ontrails/core';
|
|
4
|
-
import { z } from 'zod';
|
|
5
|
-
|
|
6
|
-
import { testContracts } from '../contracts.js';
|
|
7
|
-
|
|
8
|
-
// ---------------------------------------------------------------------------
|
|
9
|
-
// Test trails
|
|
10
|
-
// ---------------------------------------------------------------------------
|
|
11
|
-
|
|
12
|
-
/** Trail whose implementation matches the output schema. */
|
|
13
|
-
const validTrail = trail('valid', {
|
|
14
|
-
blaze: (input: { name: string }) => Result.ok({ id: 1, name: input.name }),
|
|
15
|
-
examples: [
|
|
16
|
-
{
|
|
17
|
-
expected: { id: 1, name: 'Alpha' },
|
|
18
|
-
input: { name: 'Alpha' },
|
|
19
|
-
name: 'Valid output',
|
|
20
|
-
},
|
|
21
|
-
],
|
|
22
|
-
input: z.object({ name: z.string() }),
|
|
23
|
-
output: z.object({ id: z.number(), name: z.string() }),
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
/** Trail without output schema -- should be skipped. */
|
|
27
|
-
const noSchemaTrail = trail('noschema', {
|
|
28
|
-
blaze: (input: { x: number }) => Result.ok(input.x * 2),
|
|
29
|
-
examples: [{ expected: 10, input: { x: 5 }, name: 'No schema' }],
|
|
30
|
-
input: z.object({ x: z.number() }),
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
/** Trail without examples -- should be skipped. */
|
|
34
|
-
const noExamplesTrail = trail('noexamples', {
|
|
35
|
-
blaze: (input: { x: number }) => Result.ok({ value: input.x }),
|
|
36
|
-
input: z.object({ x: z.number() }),
|
|
37
|
-
output: z.object({ value: z.number() }),
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
// ---------------------------------------------------------------------------
|
|
41
|
-
// Composition trail
|
|
42
|
-
// ---------------------------------------------------------------------------
|
|
43
|
-
|
|
44
|
-
/** Composition trail whose implementation matches the output schema. */
|
|
45
|
-
const compositionTrail = trail('composition.valid', {
|
|
46
|
-
blaze: (input: { a: number; b: number }) =>
|
|
47
|
-
Result.ok({ total: input.a + input.b }),
|
|
48
|
-
crosses: ['valid'],
|
|
49
|
-
examples: [
|
|
50
|
-
{
|
|
51
|
-
expected: { total: 3 },
|
|
52
|
-
input: { a: 1, b: 2 },
|
|
53
|
-
name: 'Valid composition output',
|
|
54
|
-
},
|
|
55
|
-
],
|
|
56
|
-
input: z.object({ a: z.number(), b: z.number() }),
|
|
57
|
-
output: z.object({ total: z.number() }),
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
const transformedInputTrail = trail('contract.transformed', {
|
|
61
|
-
blaze: (input: { value: number }) => Result.ok({ value: input.value }),
|
|
62
|
-
examples: [
|
|
63
|
-
{
|
|
64
|
-
expected: { value: 2 },
|
|
65
|
-
input: { value: '1' },
|
|
66
|
-
name: 'Raw contract input is only transformed once',
|
|
67
|
-
},
|
|
68
|
-
],
|
|
69
|
-
input: z
|
|
70
|
-
.object({ value: z.string() })
|
|
71
|
-
.transform(({ value }) => ({ value: Number(value) + 1 })),
|
|
72
|
-
output: z.object({ value: z.number() }),
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
const undeclaredContractDbProvision = provision('db.undeclared.contracts', {
|
|
76
|
-
create: () => Result.ok({ source: 'factory' }),
|
|
77
|
-
mock: () => ({ source: 'mock' }),
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
const undeclaredContractTrail = trail('provision.undeclared.contracts', {
|
|
81
|
-
blaze: (_input, ctx) =>
|
|
82
|
-
Result.ok({
|
|
83
|
-
hasInjectedProvision:
|
|
84
|
-
ctx.extensions?.[undeclaredContractDbProvision.id] !== undefined,
|
|
85
|
-
}),
|
|
86
|
-
examples: [
|
|
87
|
-
{
|
|
88
|
-
expected: { hasInjectedProvision: false },
|
|
89
|
-
input: {},
|
|
90
|
-
name: 'Undeclared provisions are not preloaded into contract contexts',
|
|
91
|
-
},
|
|
92
|
-
],
|
|
93
|
-
input: z.object({}),
|
|
94
|
-
output: z.object({ hasInjectedProvision: z.literal(false) }),
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
const ctxOverrideContractProvision = provision('db.mock.contracts', {
|
|
98
|
-
create: () => Result.ok({ source: 'factory' }),
|
|
99
|
-
mock: () => ({ source: 'mock' }),
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
const ctxOverrideContractTrail = trail('provision.ctx.contracts', {
|
|
103
|
-
blaze: (_input, ctx) =>
|
|
104
|
-
Result.ok({ source: ctxOverrideContractProvision.from(ctx).source }),
|
|
105
|
-
examples: [
|
|
106
|
-
{
|
|
107
|
-
expected: { source: 'ctx' },
|
|
108
|
-
input: {},
|
|
109
|
-
name: 'Context extensions beat auto-resolved contract provision mocks',
|
|
110
|
-
},
|
|
111
|
-
],
|
|
112
|
-
input: z.object({}),
|
|
113
|
-
output: z.object({ source: z.literal('ctx') }),
|
|
114
|
-
provisions: [ctxOverrideContractProvision],
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
// ---------------------------------------------------------------------------
|
|
118
|
-
// Tests
|
|
119
|
-
// ---------------------------------------------------------------------------
|
|
120
|
-
|
|
121
|
-
describe('testContracts: valid output matches schema', () => {
|
|
122
|
-
// eslint-disable-next-line jest/require-hook
|
|
123
|
-
testContracts(topo('test-app', { validTrail } as Record<string, unknown>));
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
describe('testContracts: skips trails without output schemas', () => {
|
|
127
|
-
// eslint-disable-next-line jest/require-hook
|
|
128
|
-
testContracts(topo('test-app', { noSchemaTrail } as Record<string, unknown>));
|
|
129
|
-
|
|
130
|
-
test('no-op marker', () => {
|
|
131
|
-
// Trail without output schema is skipped -- no contract tests generated
|
|
132
|
-
});
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
describe('testContracts: skips trails without examples', () => {
|
|
136
|
-
// eslint-disable-next-line jest/require-hook
|
|
137
|
-
testContracts(
|
|
138
|
-
topo('test-app', { noExamplesTrail } as Record<string, unknown>)
|
|
139
|
-
);
|
|
140
|
-
|
|
141
|
-
test('no-op marker', () => {
|
|
142
|
-
// Trail without examples is skipped -- no contract tests generated
|
|
143
|
-
});
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
describe('testContracts: validates output schemas for trails with crossings', () => {
|
|
147
|
-
// eslint-disable-next-line jest/require-hook
|
|
148
|
-
testContracts(
|
|
149
|
-
topo('test-app', { compositionTrail } as Record<string, unknown>)
|
|
150
|
-
);
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
describe('testContracts: raw transformed input', () => {
|
|
154
|
-
// eslint-disable-next-line jest/require-hook
|
|
155
|
-
testContracts(
|
|
156
|
-
topo('transformed-contract-app', {
|
|
157
|
-
transformedInputTrail,
|
|
158
|
-
} as Record<string, unknown>)
|
|
159
|
-
);
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
describe('testContracts: context extension overrides', () => {
|
|
163
|
-
// eslint-disable-next-line jest/require-hook
|
|
164
|
-
testContracts(
|
|
165
|
-
topo('ctx-contract-app', {
|
|
166
|
-
ctxOverrideContractProvision,
|
|
167
|
-
ctxOverrideContractTrail,
|
|
168
|
-
} as Record<string, unknown>),
|
|
169
|
-
{
|
|
170
|
-
ctx: {
|
|
171
|
-
extensions: { 'db.mock.contracts': { source: 'ctx' } },
|
|
172
|
-
},
|
|
173
|
-
}
|
|
174
|
-
);
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
describe('testContracts provision declarations', () => {
|
|
178
|
-
// eslint-disable-next-line jest/require-hook
|
|
179
|
-
testContracts(
|
|
180
|
-
topo('undeclared-contract-provision-app', {
|
|
181
|
-
undeclaredContractDbProvision,
|
|
182
|
-
undeclaredContractTrail,
|
|
183
|
-
} as Record<string, unknown>)
|
|
184
|
-
);
|
|
185
|
-
});
|