@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.
Files changed (88) hide show
  1. package/CHANGELOG.md +69 -0
  2. package/README.md +12 -12
  3. package/package.json +15 -6
  4. package/src/all.ts +153 -16
  5. package/src/assertions.ts +253 -0
  6. package/src/context.ts +67 -38
  7. package/src/contracts.ts +15 -24
  8. package/src/crosses.ts +93 -51
  9. package/src/detours.ts +155 -18
  10. package/src/effective-examples.ts +350 -0
  11. package/src/examples.ts +139 -63
  12. package/src/harness-cli.ts +19 -11
  13. package/src/harness-mcp.ts +9 -8
  14. package/src/index.ts +14 -4
  15. package/src/logger.ts +3 -1
  16. package/src/scenario.ts +368 -0
  17. package/src/signals.ts +221 -0
  18. package/src/types.ts +64 -6
  19. package/.turbo/turbo-build.log +0 -1
  20. package/.turbo/turbo-lint.log +0 -3
  21. package/.turbo/turbo-typecheck.log +0 -1
  22. package/dist/all.d.ts +0 -31
  23. package/dist/all.d.ts.map +0 -1
  24. package/dist/all.js +0 -47
  25. package/dist/all.js.map +0 -1
  26. package/dist/assertions.d.ts +0 -49
  27. package/dist/assertions.d.ts.map +0 -1
  28. package/dist/assertions.js +0 -84
  29. package/dist/assertions.js.map +0 -1
  30. package/dist/context.d.ts +0 -75
  31. package/dist/context.d.ts.map +0 -1
  32. package/dist/context.js +0 -107
  33. package/dist/context.js.map +0 -1
  34. package/dist/contracts.d.ts +0 -17
  35. package/dist/contracts.d.ts.map +0 -1
  36. package/dist/contracts.js +0 -71
  37. package/dist/contracts.js.map +0 -1
  38. package/dist/crosses.d.ts +0 -38
  39. package/dist/crosses.d.ts.map +0 -1
  40. package/dist/crosses.js +0 -213
  41. package/dist/crosses.js.map +0 -1
  42. package/dist/detours.d.ts +0 -12
  43. package/dist/detours.d.ts.map +0 -1
  44. package/dist/detours.js +0 -30
  45. package/dist/detours.js.map +0 -1
  46. package/dist/examples.d.ts +0 -23
  47. package/dist/examples.d.ts.map +0 -1
  48. package/dist/examples.js +0 -202
  49. package/dist/examples.js.map +0 -1
  50. package/dist/follows.d.ts +0 -38
  51. package/dist/follows.d.ts.map +0 -1
  52. package/dist/follows.js +0 -212
  53. package/dist/follows.js.map +0 -1
  54. package/dist/harness-cli.d.ts +0 -21
  55. package/dist/harness-cli.d.ts.map +0 -1
  56. package/dist/harness-cli.js +0 -200
  57. package/dist/harness-cli.js.map +0 -1
  58. package/dist/harness-mcp.d.ts +0 -21
  59. package/dist/harness-mcp.d.ts.map +0 -1
  60. package/dist/harness-mcp.js +0 -53
  61. package/dist/harness-mcp.js.map +0 -1
  62. package/dist/index.d.ts +0 -16
  63. package/dist/index.d.ts.map +0 -1
  64. package/dist/index.js +0 -16
  65. package/dist/index.js.map +0 -1
  66. package/dist/logger.d.ts +0 -15
  67. package/dist/logger.d.ts.map +0 -1
  68. package/dist/logger.js +0 -87
  69. package/dist/logger.js.map +0 -1
  70. package/dist/trail.d.ts +0 -20
  71. package/dist/trail.d.ts.map +0 -1
  72. package/dist/trail.js +0 -80
  73. package/dist/trail.js.map +0 -1
  74. package/dist/types.d.ts +0 -80
  75. package/dist/types.d.ts.map +0 -1
  76. package/dist/types.js +0 -5
  77. package/dist/types.js.map +0 -1
  78. package/src/__tests__/all.test.ts +0 -135
  79. package/src/__tests__/context.test.ts +0 -150
  80. package/src/__tests__/contracts.test.ts +0 -185
  81. package/src/__tests__/crosses.test.ts +0 -587
  82. package/src/__tests__/detours.test.ts +0 -55
  83. package/src/__tests__/examples.test.ts +0 -534
  84. package/src/__tests__/harness-cli.test.ts +0 -66
  85. package/src/__tests__/logger.test.ts +0 -136
  86. package/src/__tests__/trail.test.ts +0 -99
  87. package/tsconfig.json +0 -9
  88. package/tsconfig.tsbuildinfo +0 -1
@@ -1,136 +0,0 @@
1
- import { describe, expect, test } from 'bun:test';
2
-
3
- import { createTestLogger } from '../logger.js';
4
-
5
- // ---------------------------------------------------------------------------
6
- // Tests
7
- // ---------------------------------------------------------------------------
8
-
9
- describe('createTestLogger: basic operations', () => {
10
- test('captures info entries', () => {
11
- const logger = createTestLogger();
12
- logger.info('hello');
13
- logger.warn('world');
14
- expect(logger.entries).toHaveLength(2);
15
- const [first] = logger.entries;
16
- expect(first).toBeDefined();
17
- expect(first?.level).toBe('info');
18
- expect(first?.message).toBe('hello');
19
- });
20
-
21
- test('captures warn entries', () => {
22
- const logger = createTestLogger();
23
- logger.info('hello');
24
- logger.warn('world');
25
- const [, second] = logger.entries;
26
- expect(second).toBeDefined();
27
- expect(second?.level).toBe('warn');
28
- expect(second?.message).toBe('world');
29
- });
30
-
31
- test('entries contain all logged records', () => {
32
- const logger = createTestLogger();
33
- logger.trace('t');
34
- logger.debug('d');
35
- logger.info('i');
36
- logger.warn('w');
37
- logger.error('e');
38
- logger.fatal('f');
39
- expect(logger.entries).toHaveLength(6);
40
- });
41
-
42
- test('clear() empties the entries array', () => {
43
- const logger = createTestLogger();
44
- logger.info('one');
45
- logger.info('two');
46
- expect(logger.entries).toHaveLength(2);
47
- logger.clear();
48
- expect(logger.entries).toHaveLength(0);
49
- });
50
-
51
- test('find() filters entries by predicate', () => {
52
- const logger = createTestLogger();
53
- logger.info('alpha');
54
- logger.warn('beta');
55
- logger.info('gamma');
56
-
57
- const warnings = logger.find((r) => r.level === 'warn');
58
- expect(warnings).toHaveLength(1);
59
- expect(warnings[0]?.message).toBe('beta');
60
- });
61
- });
62
-
63
- describe('createTestLogger: assertLogged', () => {
64
- test('passes when matching entry exists', () => {
65
- const logger = createTestLogger();
66
- logger.info('operation completed');
67
- expect(() => logger.assertLogged('info', 'completed')).not.toThrow();
68
- });
69
-
70
- test('fails when no matching entry exists', () => {
71
- const logger = createTestLogger();
72
- logger.info('something else');
73
- expect(() => logger.assertLogged('error', 'not found')).toThrow(
74
- /Expected a log entry/
75
- );
76
- });
77
- });
78
-
79
- describe('createTestLogger: child loggers', () => {
80
- test('child() captures to the same entries array', () => {
81
- const logger = createTestLogger();
82
- const child = logger.child({ component: 'db' });
83
-
84
- logger.info('parent message');
85
- child.info('child message');
86
-
87
- expect(logger.entries).toHaveLength(2);
88
- expect(logger.entries[0]?.message).toBe('parent message');
89
- expect(logger.entries[1]?.message).toBe('child message');
90
- expect(logger.entries[1]?.metadata).toEqual({ component: 'db' });
91
- });
92
-
93
- test('child logger inherits parent metadata', () => {
94
- const logger = createTestLogger();
95
- const child = logger.child({ requestId: 'abc' });
96
- const grandchild = child.child({ trailId: 'greet' });
97
-
98
- grandchild.info('deep log');
99
-
100
- expect(logger.entries).toHaveLength(1);
101
- expect(logger.entries[0]?.metadata).toEqual({
102
- requestId: 'abc',
103
- trailId: 'greet',
104
- });
105
- });
106
- });
107
-
108
- describe('createTestLogger: configuration', () => {
109
- test('respects minimum log level', () => {
110
- const logger = createTestLogger({ level: 'warn' });
111
- logger.debug('should be filtered');
112
- logger.info('also filtered');
113
- logger.warn('should appear');
114
- logger.error('also appears');
115
- expect(logger.entries).toHaveLength(2);
116
- expect(logger.entries[0]?.level).toBe('warn');
117
- expect(logger.entries[1]?.level).toBe('error');
118
- });
119
-
120
- test('has name property', () => {
121
- const logger = createTestLogger();
122
- expect(logger.name).toBe('test');
123
- });
124
-
125
- test('entries have timestamps', () => {
126
- const logger = createTestLogger();
127
- logger.info('timestamped');
128
- expect(logger.entries[0]?.timestamp).toBeInstanceOf(Date);
129
- });
130
-
131
- test('entries have category matching logger name', () => {
132
- const logger = createTestLogger();
133
- logger.info('categorized');
134
- expect(logger.entries[0]?.category).toBe('test');
135
- });
136
- });
@@ -1,99 +0,0 @@
1
- import { describe } from 'bun:test';
2
-
3
- import { NotFoundError, Result, ValidationError, trail } from '@ontrails/core';
4
- import { z } from 'zod';
5
-
6
- import { testTrail } from '../trail.js';
7
-
8
- // ---------------------------------------------------------------------------
9
- // Test trails
10
- // ---------------------------------------------------------------------------
11
-
12
- const greetTrail = trail('greet', {
13
- blaze: (input: { name: string }) =>
14
- Result.ok({ greeting: `Hello, ${input.name}` }),
15
- input: z.object({ name: z.string() }),
16
- output: z.object({ greeting: z.string() }),
17
- });
18
-
19
- const failTrail = trail('fail', {
20
- blaze: (input: { id: string }) => {
21
- if (input.id === 'missing') {
22
- return Result.err(new NotFoundError('Not found: missing'));
23
- }
24
- return Result.ok({ id: input.id });
25
- },
26
- input: z.object({ id: z.string() }),
27
- });
28
-
29
- // ---------------------------------------------------------------------------
30
- // Tests
31
- //
32
- // Each call to testTrail registers describe/test blocks.
33
- // We call them at the describe scope so bun:test can discover them.
34
- // ---------------------------------------------------------------------------
35
-
36
- describe('testTrail: expectOk', () => {
37
- // eslint-disable-next-line jest/require-hook
38
- testTrail(greetTrail, [
39
- { description: 'valid greeting', expectOk: true, input: { name: 'Bob' } },
40
- ]);
41
- });
42
-
43
- describe('testTrail: expectValue', () => {
44
- // eslint-disable-next-line jest/require-hook
45
- testTrail(greetTrail, [
46
- {
47
- description: 'exact match',
48
- expectValue: { greeting: 'Hello, Charlie' },
49
- input: { name: 'Charlie' },
50
- },
51
- ]);
52
- });
53
-
54
- describe('testTrail: expectErr', () => {
55
- // eslint-disable-next-line jest/require-hook
56
- testTrail(failTrail, [
57
- {
58
- description: 'not found error',
59
- expectErr: NotFoundError,
60
- input: { id: 'missing' },
61
- },
62
- ]);
63
- });
64
-
65
- describe('testTrail: expectErrMessage', () => {
66
- // eslint-disable-next-line jest/require-hook
67
- testTrail(failTrail, [
68
- {
69
- description: 'error message contains substring',
70
- expectErr: NotFoundError,
71
- expectErrMessage: 'Not found',
72
- input: { id: 'missing' },
73
- },
74
- ]);
75
- });
76
-
77
- describe('testTrail: invalid input with ValidationError', () => {
78
- // eslint-disable-next-line jest/require-hook
79
- testTrail(greetTrail, [
80
- {
81
- description: 'invalid input caught by validation',
82
- expectErr: ValidationError,
83
- input: { name: 123 },
84
- },
85
- ]);
86
- });
87
-
88
- describe('testTrail: multiple scenarios', () => {
89
- // eslint-disable-next-line jest/require-hook
90
- testTrail(greetTrail, [
91
- { description: 'scenario 1', expectOk: true, input: { name: 'A' } },
92
- { description: 'scenario 2', expectOk: true, input: { name: 'B' } },
93
- {
94
- description: 'scenario 3',
95
- expectValue: { greeting: 'Hello, C' },
96
- input: { name: 'C' },
97
- },
98
- ]);
99
- });
package/tsconfig.json DELETED
@@ -1,9 +0,0 @@
1
- {
2
- "extends": "../../tsconfig.json",
3
- "compilerOptions": {
4
- "outDir": "dist",
5
- "rootDir": "src"
6
- },
7
- "include": ["src"],
8
- "exclude": ["**/__tests__/**", "**/*.test.ts", "dist"]
9
- }
@@ -1 +0,0 @@
1
- {"root":["./src/all.ts","./src/assertions.ts","./src/context.ts","./src/contracts.ts","./src/crosses.ts","./src/detours.ts","./src/examples.ts","./src/harness-cli.ts","./src/harness-mcp.ts","./src/index.ts","./src/logger.ts","./src/trail.ts","./src/types.ts"],"version":"5.9.3"}