@ontrails/testing 1.0.0-beta.15 → 1.0.0-beta.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/CHANGELOG.md +70 -1
  2. package/README.md +47 -3
  3. package/package.json +16 -7
  4. package/src/all.ts +32 -7
  5. package/src/context.ts +3 -0
  6. package/src/contracts.ts +1 -16
  7. package/src/examples.ts +19 -11
  8. package/src/harness-cli.ts +16 -3
  9. package/src/harness-http.ts +263 -0
  10. package/src/harness-mcp.ts +2 -0
  11. package/src/index.ts +18 -1
  12. package/src/logger.ts +3 -1
  13. package/src/scenario.ts +3 -5
  14. package/src/signals.ts +221 -0
  15. package/src/surface-parity.ts +356 -0
  16. package/src/types.ts +136 -1
  17. package/.turbo/turbo-build.log +0 -1
  18. package/.turbo/turbo-lint.log +0 -3
  19. package/.turbo/turbo-typecheck.log +0 -1
  20. package/dist/all.d.ts +0 -36
  21. package/dist/all.d.ts.map +0 -1
  22. package/dist/all.js +0 -99
  23. package/dist/all.js.map +0 -1
  24. package/dist/assertions.d.ts +0 -72
  25. package/dist/assertions.d.ts.map +0 -1
  26. package/dist/assertions.js +0 -238
  27. package/dist/assertions.js.map +0 -1
  28. package/dist/context.d.ts +0 -76
  29. package/dist/context.d.ts.map +0 -1
  30. package/dist/context.js +0 -118
  31. package/dist/context.js.map +0 -1
  32. package/dist/contracts.d.ts +0 -17
  33. package/dist/contracts.d.ts.map +0 -1
  34. package/dist/contracts.js +0 -75
  35. package/dist/contracts.js.map +0 -1
  36. package/dist/crosses.d.ts +0 -38
  37. package/dist/crosses.d.ts.map +0 -1
  38. package/dist/crosses.js +0 -223
  39. package/dist/crosses.js.map +0 -1
  40. package/dist/detours.d.ts +0 -13
  41. package/dist/detours.d.ts.map +0 -1
  42. package/dist/detours.js +0 -109
  43. package/dist/detours.js.map +0 -1
  44. package/dist/effective-examples.d.ts +0 -30
  45. package/dist/effective-examples.d.ts.map +0 -1
  46. package/dist/effective-examples.js +0 -227
  47. package/dist/effective-examples.js.map +0 -1
  48. package/dist/examples.d.ts +0 -23
  49. package/dist/examples.d.ts.map +0 -1
  50. package/dist/examples.js +0 -240
  51. package/dist/examples.js.map +0 -1
  52. package/dist/harness-cli.d.ts +0 -21
  53. package/dist/harness-cli.d.ts.map +0 -1
  54. package/dist/harness-cli.js +0 -205
  55. package/dist/harness-cli.js.map +0 -1
  56. package/dist/harness-mcp.d.ts +0 -21
  57. package/dist/harness-mcp.d.ts.map +0 -1
  58. package/dist/harness-mcp.js +0 -54
  59. package/dist/harness-mcp.js.map +0 -1
  60. package/dist/index.d.ts +0 -18
  61. package/dist/index.d.ts.map +0 -1
  62. package/dist/index.js +0 -19
  63. package/dist/index.js.map +0 -1
  64. package/dist/logger.d.ts +0 -15
  65. package/dist/logger.d.ts.map +0 -1
  66. package/dist/logger.js +0 -87
  67. package/dist/logger.js.map +0 -1
  68. package/dist/scenario.d.ts +0 -37
  69. package/dist/scenario.d.ts.map +0 -1
  70. package/dist/scenario.js +0 -235
  71. package/dist/scenario.js.map +0 -1
  72. package/dist/trail.d.ts +0 -20
  73. package/dist/trail.d.ts.map +0 -1
  74. package/dist/trail.js +0 -80
  75. package/dist/trail.js.map +0 -1
  76. package/dist/types.d.ts +0 -113
  77. package/dist/types.d.ts.map +0 -1
  78. package/dist/types.js +0 -5
  79. package/dist/types.js.map +0 -1
  80. package/src/__tests__/all.test.ts +0 -254
  81. package/src/__tests__/context.test.ts +0 -170
  82. package/src/__tests__/contracts.test.ts +0 -239
  83. package/src/__tests__/crosses.test.ts +0 -587
  84. package/src/__tests__/detours.test.ts +0 -212
  85. package/src/__tests__/effective-examples.test.ts +0 -203
  86. package/src/__tests__/examples.test.ts +0 -636
  87. package/src/__tests__/harness-cli.test.ts +0 -90
  88. package/src/__tests__/harness-mcp.test.ts +0 -37
  89. package/src/__tests__/logger.test.ts +0 -136
  90. package/src/__tests__/partial-match.test.ts +0 -126
  91. package/src/__tests__/scenario.test.ts +0 -381
  92. package/src/__tests__/trail.test.ts +0 -99
  93. package/tsconfig.json +0 -9
  94. package/tsconfig.tests.json +0 -10
  95. package/tsconfig.tsbuildinfo +0 -1
@@ -1,587 +0,0 @@
1
- import { describe } from 'bun:test';
2
-
3
- import type { AnyTrail, TrailContext } from '@ontrails/core';
4
- import { InternalError, Result, resource, trail } from '@ontrails/core';
5
- import { z } from 'zod';
6
-
7
- import { testCrosses } from '../crosses.js';
8
-
9
- // ---------------------------------------------------------------------------
10
- // Test trails (trails with crossings)
11
- // ---------------------------------------------------------------------------
12
-
13
- const addTrail = trail('entity.add', {
14
- blaze: (input: { name: string }) => Result.ok({ id: '1', name: input.name }),
15
- description: 'Add an entity',
16
- examples: [
17
- { input: { name: 'Alpha' }, name: 'success' },
18
- {
19
- description: 'duplicate name',
20
- error: 'AlreadyExistsError',
21
- input: { name: '' },
22
- name: 'duplicate',
23
- },
24
- ],
25
- input: z.object({ name: z.string() }),
26
- output: z.object({ id: z.string(), name: z.string() }),
27
- });
28
-
29
- const relateTrail = trail('entity.relate', {
30
- blaze: (input: { from: string; to: string }) =>
31
- Result.ok({ from: input.from, to: input.to }),
32
- description: 'Relate two entities',
33
- input: z.object({ from: z.string(), to: z.string() }),
34
- output: z.object({ from: z.string(), to: z.string() }),
35
- });
36
-
37
- // ---------------------------------------------------------------------------
38
- // Composition trail
39
- // ---------------------------------------------------------------------------
40
-
41
- const onboardTrail = trail('entity.onboard', {
42
- blaze: async (
43
- input: { name: string; relatedTo: string },
44
- ctx: TrailContext
45
- ) => {
46
- if (!ctx.cross) {
47
- return Result.err(new Error('cross not available'));
48
- }
49
- const addResult = await ctx.cross<{ id: string; name: string }>(
50
- 'entity.add',
51
- { name: input.name }
52
- );
53
- if (addResult.isErr()) {
54
- return Result.err(addResult.error);
55
- }
56
-
57
- const relateResult = await ctx.cross<{ from: string; to: string }>(
58
- 'entity.relate',
59
- { from: addResult.value.name, to: input.relatedTo }
60
- );
61
- if (relateResult.isErr()) {
62
- return Result.err(relateResult.error);
63
- }
64
-
65
- return Result.ok({
66
- name: addResult.value.name,
67
- relatedTo: relateResult.value.to,
68
- });
69
- },
70
- crosses: ['entity.add', 'entity.relate'],
71
- input: z.object({ name: z.string(), relatedTo: z.string() }),
72
- output: z.object({ name: z.string(), relatedTo: z.string() }),
73
- });
74
-
75
- const trailsMap = new Map<string, AnyTrail>([
76
- ['entity.add', addTrail],
77
- ['entity.relate', relateTrail],
78
- ]);
79
-
80
- // ---------------------------------------------------------------------------
81
- // Tests
82
- // ---------------------------------------------------------------------------
83
-
84
- const opts = { trails: trailsMap };
85
-
86
- describe('testCrosses: expectOk', () => {
87
- // eslint-disable-next-line jest/require-hook
88
- testCrosses(
89
- onboardTrail,
90
- [
91
- {
92
- description: 'basic onboard succeeds',
93
- expectOk: true,
94
- input: { name: 'Alpha', relatedTo: 'Beta' },
95
- },
96
- ],
97
- opts
98
- );
99
- });
100
-
101
- describe('testCrosses: expectCrossed', () => {
102
- // eslint-disable-next-line jest/require-hook
103
- testCrosses(
104
- onboardTrail,
105
- [
106
- {
107
- description: 'crosses add then relate in order',
108
- expectCrossed: ['entity.add', 'entity.relate'],
109
- expectOk: true,
110
- input: { name: 'Alpha', relatedTo: 'Beta' },
111
- },
112
- ],
113
- opts
114
- );
115
- });
116
-
117
- describe('testCrosses: expectCrossedCount', () => {
118
- // eslint-disable-next-line jest/require-hook
119
- testCrosses(
120
- onboardTrail,
121
- [
122
- {
123
- description: 'each trail crossed exactly once',
124
- expectCrossedCount: { 'entity.add': 1, 'entity.relate': 1 },
125
- expectOk: true,
126
- input: { name: 'Alpha', relatedTo: 'Beta' },
127
- },
128
- ],
129
- opts
130
- );
131
- });
132
-
133
- describe('testCrosses: injectFromExample', () => {
134
- // eslint-disable-next-line jest/require-hook
135
- testCrosses(
136
- onboardTrail,
137
- [
138
- {
139
- description: 'inject duplicate error from add trail example',
140
- expectErr: Error,
141
- expectErrMessage: 'AlreadyExistsError',
142
- injectFromExample: { 'entity.add': 'duplicate' },
143
- input: { name: 'Alpha', relatedTo: 'Beta' },
144
- },
145
- ],
146
- opts
147
- );
148
- });
149
-
150
- describe('testCrosses: expectValue', () => {
151
- // eslint-disable-next-line jest/require-hook
152
- testCrosses(
153
- onboardTrail,
154
- [
155
- {
156
- description: 'exact value match',
157
- expectValue: { name: 'Alpha', relatedTo: 'Beta' },
158
- input: { name: 'Alpha', relatedTo: 'Beta' },
159
- },
160
- ],
161
- opts
162
- );
163
- });
164
-
165
- // ---------------------------------------------------------------------------
166
- // Nested cross chain: A → B → C
167
- // ---------------------------------------------------------------------------
168
-
169
- const leafTrail = trail('step.leaf', {
170
- blaze: (input: { value: string }) => Result.ok({ leaf: input.value }),
171
- description: 'Leaf trail in a nested chain',
172
- input: z.object({ value: z.string() }),
173
- output: z.object({ leaf: z.string() }),
174
- });
175
-
176
- const middleTrail = trail('step.middle', {
177
- blaze: async (input: { value: string }, ctx: TrailContext) => {
178
- if (!ctx.cross) {
179
- return Result.err(new Error('cross not available'));
180
- }
181
- const leafResult = await ctx.cross<{ leaf: string }>('step.leaf', input);
182
- if (leafResult.isErr()) {
183
- return leafResult;
184
- }
185
- return Result.ok({ middle: leafResult.value.leaf });
186
- },
187
- crosses: ['step.leaf'],
188
- description: 'Middle trail that crosses the leaf',
189
- input: z.object({ value: z.string() }),
190
- output: z.object({ middle: z.string() }),
191
- });
192
-
193
- const nestedRootTrail = trail('step.root', {
194
- blaze: async (input: { value: string }, ctx: TrailContext) => {
195
- if (!ctx.cross) {
196
- return Result.err(new Error('cross not available'));
197
- }
198
- const midResult = await ctx.cross<{ middle: string }>('step.middle', input);
199
- if (midResult.isErr()) {
200
- return midResult;
201
- }
202
- return Result.ok({ root: midResult.value.middle });
203
- },
204
- crosses: ['step.middle'],
205
- description: 'Root trail that crosses the middle trail',
206
- input: z.object({ value: z.string() }),
207
- output: z.object({ root: z.string() }),
208
- });
209
-
210
- const nestedTrailsMap = new Map<string, AnyTrail>([
211
- ['step.leaf', leafTrail],
212
- ['step.middle', middleTrail],
213
- ]);
214
-
215
- describe('testCrosses: nested cross chain (A → B → C)', () => {
216
- // eslint-disable-next-line jest/require-hook
217
- testCrosses(
218
- nestedRootTrail,
219
- [
220
- {
221
- description: 'nested ctx.cross works through A → B → C',
222
- expectOk: true,
223
- expectValue: { root: 'hello' },
224
- input: { value: 'hello' },
225
- },
226
- ],
227
- { trails: nestedTrailsMap }
228
- );
229
- });
230
-
231
- const mockDbResource = resource('db.mock.crosses', {
232
- create: () => Result.ok({ source: 'factory' }),
233
- mock: () => ({ source: 'mock' }),
234
- });
235
-
236
- const provisionLeafTrail = trail('resource.leaf', {
237
- blaze: (_input, ctx) =>
238
- Result.ok({ childSource: mockDbResource.from(ctx).source }),
239
- description: 'Leaf trail that reads from a resource',
240
- input: z.object({}),
241
- output: z.object({ childSource: z.string() }),
242
- resources: [mockDbResource],
243
- });
244
-
245
- const provisionRootTrail = trail('resource.root', {
246
- blaze: async (_input, ctx: TrailContext) => {
247
- if (!ctx.cross) {
248
- return Result.err(new Error('cross not available'));
249
- }
250
- const childResult = await ctx.cross<{ childSource: string }>(
251
- 'resource.leaf',
252
- {}
253
- );
254
- if (childResult.isErr()) {
255
- return childResult;
256
- }
257
-
258
- return Result.ok({
259
- childSource: childResult.value.childSource,
260
- rootSource: mockDbResource.from(ctx).source,
261
- });
262
- },
263
- crosses: ['resource.leaf'],
264
- description:
265
- 'Root trail that reads from a resource and crosses a child trail',
266
- input: z.object({}),
267
- output: z.object({ childSource: z.string(), rootSource: z.string() }),
268
- resources: [mockDbResource],
269
- });
270
-
271
- const provisionTrailsMap = new Map<string, AnyTrail>([
272
- ['resource.leaf', provisionLeafTrail],
273
- ]);
274
-
275
- const statefulMockDbResource = resource('db.mock.crosses.stateful', {
276
- create: () => Result.ok({ count: 0 }),
277
- mock: () => ({ count: 0 }),
278
- });
279
-
280
- const statefulResourceLeafTrail = trail('resource.stateful.leaf', {
281
- blaze: (_input, ctx) =>
282
- Result.ok({ childCount: statefulMockDbResource.from(ctx).count }),
283
- description: 'Leaf trail that observes the current mock resource state',
284
- input: z.object({}),
285
- output: z.object({ childCount: z.number() }),
286
- resources: [statefulMockDbResource],
287
- });
288
-
289
- const statefulResourceRootTrail = trail('resource.stateful.root', {
290
- blaze: async (_input, ctx: TrailContext) => {
291
- if (!ctx.cross) {
292
- return Result.err(new Error('cross not available'));
293
- }
294
-
295
- const statefulResource = statefulMockDbResource.from(ctx);
296
- statefulResource.count += 1;
297
-
298
- const childResult = await ctx.cross<{ childCount: number }>(
299
- 'resource.stateful.leaf',
300
- {}
301
- );
302
- if (childResult.isErr()) {
303
- return childResult;
304
- }
305
-
306
- return Result.ok({
307
- childCount: childResult.value.childCount,
308
- rootCount: statefulResource.count,
309
- });
310
- },
311
- crosses: ['resource.stateful.leaf'],
312
- description:
313
- 'Root trail that mutates a mocked resource and crosses a child trail',
314
- input: z.object({}),
315
- output: z.object({ childCount: z.number(), rootCount: z.number() }),
316
- resources: [statefulMockDbResource],
317
- });
318
-
319
- const statefulResourceTrailsMap = new Map<string, AnyTrail>([
320
- ['resource.stateful.leaf', statefulResourceLeafTrail],
321
- ]);
322
-
323
- const scenarioStateResource = resource('db.mock.scenarios', {
324
- create: () => Result.ok({ count: 0 }),
325
- mock: () => ({ count: 0 }),
326
- });
327
-
328
- const scenarioLeafTrail = trail('resource.scenario.leaf', {
329
- blaze: (_input, ctx) =>
330
- Result.ok({ count: scenarioStateResource.from(ctx).count }),
331
- description: 'Leaf trail that reads mutable scenario state',
332
- input: z.object({}),
333
- output: z.object({ count: z.number() }),
334
- resources: [scenarioStateResource],
335
- });
336
-
337
- const scenarioRootTrail = trail('resource.scenario.root', {
338
- blaze: async (_input, ctx: TrailContext) => {
339
- if (!ctx.cross) {
340
- return Result.err(new Error('cross not available'));
341
- }
342
-
343
- const state = scenarioStateResource.from(ctx);
344
- state.count += 1;
345
-
346
- const leafResult = await ctx.cross<{ count: number }>(
347
- 'resource.scenario.leaf',
348
- {}
349
- );
350
- if (leafResult.isErr()) {
351
- return leafResult;
352
- }
353
-
354
- return Result.ok({ count: leafResult.value.count });
355
- },
356
- crosses: ['resource.scenario.leaf'],
357
- description: 'Root trail that mutates scenario state and crosses a leaf',
358
- input: z.object({}),
359
- output: z.object({ count: z.number() }),
360
- resources: [scenarioStateResource],
361
- });
362
-
363
- const scenarioResourceTrailsMap = new Map<string, AnyTrail>([
364
- ['resource.scenario.leaf', scenarioLeafTrail],
365
- ]);
366
-
367
- const transformedCrossLeafTrail = trail('cross.transformed.leaf', {
368
- blaze: (input: { value: number }) => Result.ok({ value: input.value }),
369
- description: 'Leaf trail in a transformed cross chain',
370
- input: z.object({ value: z.number() }),
371
- output: z.object({ value: z.number() }),
372
- });
373
-
374
- const transformedCrossRootTrail = trail('cross.transformed.root', {
375
- blaze: async (input: { value: number }, ctx: TrailContext) => {
376
- if (!ctx.cross) {
377
- return Result.err(new Error('cross not available'));
378
- }
379
-
380
- const leafResult = await ctx.cross<{ value: number }>(
381
- 'cross.transformed.leaf',
382
- { value: input.value }
383
- );
384
- if (leafResult.isErr()) {
385
- return leafResult;
386
- }
387
-
388
- return Result.ok({ root: leafResult.value.value });
389
- },
390
- crosses: ['cross.transformed.leaf'],
391
- description: 'Root trail that transforms input once before crossing',
392
- input: z
393
- .object({ value: z.string() })
394
- .transform(({ value }) => ({ value: Number(value) + 1 })),
395
- output: z.object({ root: z.number() }),
396
- });
397
-
398
- const transformedCrossTrailsMap = new Map<string, AnyTrail>([
399
- ['cross.transformed.leaf', transformedCrossLeafTrail],
400
- ]);
401
-
402
- const undeclaredCrossResource = resource('db.undeclared.crosses', {
403
- create: () => Result.ok({ source: 'factory' }),
404
- mock: () => ({ source: 'mock' }),
405
- });
406
-
407
- const undeclaredResourceLeafTrail = trail('resource.undeclared.leaf', {
408
- blaze: (_input, ctx) =>
409
- Result.ok({ childSource: undeclaredCrossResource.from(ctx).source }),
410
- description: 'Leaf trail that declares the shared resource',
411
- input: z.object({}),
412
- output: z.object({ childSource: z.string() }),
413
- resources: [undeclaredCrossResource],
414
- });
415
-
416
- const undeclaredResourceRootTrail = trail('resource.undeclared.root', {
417
- blaze: async (_input, ctx: TrailContext) => {
418
- if (!ctx.cross) {
419
- return Result.err(new Error('cross not available'));
420
- }
421
-
422
- const childResult = await ctx.cross<{ childSource: string }>(
423
- 'resource.undeclared.leaf',
424
- {}
425
- );
426
- if (childResult.isErr()) {
427
- return childResult;
428
- }
429
-
430
- return Result.ok({
431
- childSource: childResult.value.childSource,
432
- rootSource: undeclaredCrossResource.from(ctx).source,
433
- });
434
- },
435
- crosses: ['resource.undeclared.leaf'],
436
- description: 'Root trail that uses a resource without declaring it',
437
- input: z.object({}),
438
- output: z.object({ childSource: z.string(), rootSource: z.string() }),
439
- });
440
-
441
- const undeclaredResourceTrailsMap = new Map<string, AnyTrail>([
442
- ['resource.undeclared.leaf', undeclaredResourceLeafTrail],
443
- ]);
444
-
445
- const unrelatedCrossResource = resource('db.unrelated.crosses', {
446
- create: () => Result.ok({ source: 'factory' }),
447
- mock: () => {
448
- throw new Error('unrelated mock should not be resolved');
449
- },
450
- });
451
-
452
- const unrelatedResourceTrail = trail('resource.unrelated', {
453
- blaze: (_input, ctx) =>
454
- Result.ok({ source: unrelatedCrossResource.from(ctx).source }),
455
- description: 'Trail that should not be traversed or mocked',
456
- input: z.object({}),
457
- output: z.object({ source: z.string() }),
458
- resources: [unrelatedCrossResource],
459
- });
460
-
461
- const unrelatedResourceTrailsMap = new Map<string, AnyTrail>([
462
- ['resource.unrelated', unrelatedResourceTrail],
463
- ]);
464
-
465
- describe('testCrosses resource mocks', () => {
466
- // eslint-disable-next-line jest/require-hook
467
- testCrosses(
468
- provisionRootTrail,
469
- [
470
- {
471
- description: 'propagates auto-resolved resource mocks through cross',
472
- expectValue: { childSource: 'mock', rootSource: 'mock' },
473
- input: {},
474
- },
475
- ],
476
- { trails: provisionTrailsMap }
477
- );
478
- });
479
-
480
- describe('testCrosses resource mocks are fresh per scenario', () => {
481
- // eslint-disable-next-line jest/require-hook
482
- testCrosses(
483
- scenarioRootTrail,
484
- [
485
- {
486
- description: 'first scenario sees a fresh mutable resource',
487
- expectValue: { count: 1 },
488
- input: {},
489
- },
490
- {
491
- description: 'second scenario also sees a fresh mutable resource',
492
- expectValue: { count: 1 },
493
- input: {},
494
- },
495
- ],
496
- { trails: scenarioResourceTrailsMap }
497
- );
498
- });
499
-
500
- describe('testCrosses explicit resource overrides', () => {
501
- // eslint-disable-next-line jest/require-hook
502
- testCrosses(
503
- provisionRootTrail,
504
- [
505
- {
506
- description: 'propagates explicit resource overrides through cross',
507
- expectValue: { childSource: 'override', rootSource: 'override' },
508
- input: {},
509
- },
510
- ],
511
- {
512
- resources: { 'db.mock.crosses': { source: 'override' } },
513
- trails: provisionTrailsMap,
514
- }
515
- );
516
- });
517
-
518
- describe('testCrosses raw transformed input', () => {
519
- // eslint-disable-next-line jest/require-hook
520
- testCrosses(
521
- transformedCrossRootTrail,
522
- [
523
- {
524
- description: 'raw scenario input is only transformed once',
525
- expectValue: { root: 2 },
526
- input: { value: '1' },
527
- },
528
- ],
529
- { trails: transformedCrossTrailsMap }
530
- );
531
- });
532
-
533
- describe('testCrosses resource declarations', () => {
534
- // eslint-disable-next-line jest/require-hook
535
- testCrosses(
536
- undeclaredResourceRootTrail,
537
- [
538
- {
539
- description: 'fails when the root trail omits a required resource',
540
- expectErr: InternalError,
541
- expectErrMessage: undeclaredCrossResource.id,
542
- input: {},
543
- },
544
- ],
545
- { trails: undeclaredResourceTrailsMap }
546
- );
547
- });
548
-
549
- describe('testCrosses only resolves mocks for trails under test', () => {
550
- // eslint-disable-next-line jest/require-hook
551
- testCrosses(
552
- provisionRootTrail,
553
- [
554
- {
555
- description: 'unrelated resource mocks are not resolved',
556
- expectValue: { childSource: 'mock', rootSource: 'mock' },
557
- input: {},
558
- },
559
- ],
560
- {
561
- trails: new Map<string, AnyTrail>([
562
- ...provisionTrailsMap.entries(),
563
- ...unrelatedResourceTrailsMap.entries(),
564
- ]),
565
- }
566
- );
567
- });
568
-
569
- describe('testCrosses fresh resource mocks per scenario', () => {
570
- // eslint-disable-next-line jest/require-hook
571
- testCrosses(
572
- statefulResourceRootTrail,
573
- [
574
- {
575
- description: 'first scenario gets a fresh resource mock',
576
- expectValue: { childCount: 1, rootCount: 1 },
577
- input: {},
578
- },
579
- {
580
- description: 'second scenario also gets a fresh resource mock',
581
- expectValue: { childCount: 1, rootCount: 1 },
582
- input: {},
583
- },
584
- ],
585
- { trails: statefulResourceTrailsMap }
586
- );
587
- });