@directive-run/core 0.4.0 → 0.4.1
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/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +829 -185
- package/dist/index.d.ts +829 -185
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/migration.cjs.map +1 -1
- package/dist/migration.js.map +1 -1
- package/dist/plugins/index.cjs.map +1 -1
- package/dist/plugins/index.d.cts +85 -18
- package/dist/plugins/index.d.ts +85 -18
- package/dist/plugins/index.js.map +1 -1
- package/dist/testing.cjs +1 -1
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +142 -26
- package/dist/testing.d.ts +142 -26
- package/dist/testing.js +1 -1
- package/dist/testing.js.map +1 -1
- package/dist/worker.cjs +1 -1
- package/dist/worker.cjs.map +1 -1
- package/dist/worker.js +1 -1
- package/dist/worker.js.map +1 -1
- package/package.json +3 -2
package/dist/testing.d.cts
CHANGED
|
@@ -12,8 +12,12 @@ import { p as ModulesMap, q as CreateSystemOptionsNamed, R as Requirement, N as
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
|
-
* Flush all pending microtasks.
|
|
16
|
-
*
|
|
15
|
+
* Flush all pending microtasks by awaiting multiple rounds of `Promise.resolve()`.
|
|
16
|
+
*
|
|
17
|
+
* Call this after advancing fake timers to ensure all Promise callbacks
|
|
18
|
+
* (including nested microtasks) have run before making assertions.
|
|
19
|
+
*
|
|
20
|
+
* @returns A promise that resolves after all pending microtasks have been drained.
|
|
17
21
|
*
|
|
18
22
|
* @example
|
|
19
23
|
* ```typescript
|
|
@@ -24,15 +28,22 @@ import { p as ModulesMap, q as CreateSystemOptionsNamed, R as Requirement, N as
|
|
|
24
28
|
* vi.advanceTimersByTime(100); // Advance resolver delay
|
|
25
29
|
* await flushMicrotasks(); // Let resolver complete
|
|
26
30
|
* ```
|
|
31
|
+
*
|
|
32
|
+
* @public
|
|
27
33
|
*/
|
|
28
34
|
declare function flushMicrotasks(): Promise<void>;
|
|
29
35
|
/**
|
|
30
36
|
* Wait for the system to settle with fake timers enabled.
|
|
31
|
-
* Combines timer advancement with microtask flushing.
|
|
32
37
|
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
38
|
+
* Repeatedly advances fake timers in discrete steps while flushing microtasks,
|
|
39
|
+
* until no resolvers remain inflight or the time budget is exhausted.
|
|
40
|
+
*
|
|
41
|
+
* @param system - The Directive system to wait on (must expose {@link SystemInspection} via `inspect()`).
|
|
42
|
+
* @param advanceTime - Function that advances fake timers by a given number of milliseconds (e.g., `vi.advanceTimersByTime`).
|
|
43
|
+
* @param options - Configuration for total time budget, step size, and iteration limit.
|
|
44
|
+
* @returns A promise that resolves once the system is idle.
|
|
45
|
+
*
|
|
46
|
+
* @throws Error if the system does not settle within the configured time budget.
|
|
36
47
|
*
|
|
37
48
|
* @example
|
|
38
49
|
* ```typescript
|
|
@@ -48,6 +59,8 @@ declare function flushMicrotasks(): Promise<void>;
|
|
|
48
59
|
*
|
|
49
60
|
* expect(system.facts.result).toBe("done");
|
|
50
61
|
* ```
|
|
62
|
+
*
|
|
63
|
+
* @public
|
|
51
64
|
*/
|
|
52
65
|
declare function settleWithFakeTimers(system: {
|
|
53
66
|
inspect(): SystemInspection;
|
|
@@ -59,41 +72,77 @@ declare function settleWithFakeTimers(system: {
|
|
|
59
72
|
/** Maximum iterations before giving up (default: 1000) */
|
|
60
73
|
maxIterations?: number;
|
|
61
74
|
}): Promise<void>;
|
|
75
|
+
/**
|
|
76
|
+
* Standalone fake timer controller for tests that do not use Vitest/Jest fake timers.
|
|
77
|
+
*
|
|
78
|
+
* @remarks
|
|
79
|
+
* For most tests, prefer Vitest's `vi.useFakeTimers()` paired with
|
|
80
|
+
* {@link settleWithFakeTimers} for better integration. Use this interface
|
|
81
|
+
* only when you need a lightweight, framework-independent timer mock.
|
|
82
|
+
*
|
|
83
|
+
* @public
|
|
84
|
+
*/
|
|
62
85
|
interface FakeTimers {
|
|
63
|
-
/** Advance time by a number of milliseconds */
|
|
86
|
+
/** Advance time by a number of milliseconds, firing any timers that fall within the window. */
|
|
64
87
|
advance(ms: number): Promise<void>;
|
|
65
|
-
/** Advance to the next scheduled timer */
|
|
88
|
+
/** Advance to the next scheduled timer and fire its callback. */
|
|
66
89
|
next(): Promise<void>;
|
|
67
|
-
/** Run all pending timers */
|
|
90
|
+
/** Run all pending timers in chronological order. */
|
|
68
91
|
runAll(): Promise<void>;
|
|
69
|
-
/** Get current fake time */
|
|
92
|
+
/** Get the current fake time in milliseconds. */
|
|
70
93
|
now(): number;
|
|
71
|
-
/** Reset to time 0 */
|
|
94
|
+
/** Reset the clock to time 0 and discard all scheduled timers. */
|
|
72
95
|
reset(): void;
|
|
73
96
|
}
|
|
74
97
|
/**
|
|
75
|
-
* Create standalone fake timers for testing.
|
|
76
|
-
*
|
|
77
|
-
*
|
|
98
|
+
* Create standalone fake timers for testing without a framework timer mock.
|
|
99
|
+
*
|
|
100
|
+
* @remarks
|
|
101
|
+
* For most tests, prefer Vitest's `vi.useFakeTimers()` paired with
|
|
102
|
+
* {@link settleWithFakeTimers}. This factory is useful when you need an
|
|
103
|
+
* isolated timer that does not interfere with global timer state.
|
|
104
|
+
*
|
|
105
|
+
* @returns A {@link FakeTimers} controller with `advance`, `next`, `runAll`, `now`, and `reset` methods.
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* ```typescript
|
|
109
|
+
* const timers = createFakeTimers();
|
|
110
|
+
* // schedule work, then:
|
|
111
|
+
* await timers.advance(500);
|
|
112
|
+
* expect(timers.now()).toBe(500);
|
|
113
|
+
* ```
|
|
114
|
+
*
|
|
115
|
+
* @public
|
|
78
116
|
*/
|
|
79
117
|
declare function createFakeTimers(): FakeTimers;
|
|
80
|
-
/**
|
|
118
|
+
/**
|
|
119
|
+
* Context passed to mock resolver resolve functions.
|
|
120
|
+
*
|
|
121
|
+
* @public
|
|
122
|
+
*/
|
|
81
123
|
interface MockResolverContext {
|
|
82
124
|
/** Facts object (use type assertion for specific facts) */
|
|
83
125
|
facts: any;
|
|
84
126
|
/** Abort signal for cancellation */
|
|
85
127
|
signal: AbortSignal;
|
|
86
128
|
}
|
|
129
|
+
/**
|
|
130
|
+
* Configuration for a simple mock resolver created via {@link createMockResolver}.
|
|
131
|
+
*
|
|
132
|
+
* @typeParam R - The requirement type this resolver handles.
|
|
133
|
+
*
|
|
134
|
+
* @public
|
|
135
|
+
*/
|
|
87
136
|
interface MockResolverOptions<R extends Requirement = Requirement> {
|
|
88
|
-
/** Predicate to check if this resolver handles a requirement */
|
|
137
|
+
/** Predicate to check if this resolver handles a given requirement. */
|
|
89
138
|
requirement?: (req: Requirement) => req is R;
|
|
90
|
-
/** Mock implementation */
|
|
139
|
+
/** Mock implementation invoked when the resolver runs. */
|
|
91
140
|
resolve?: (req: R, ctx: MockResolverContext) => void | Promise<void>;
|
|
92
|
-
/**
|
|
141
|
+
/** Artificial delay in milliseconds before the resolver completes. */
|
|
93
142
|
delay?: number;
|
|
94
|
-
/**
|
|
143
|
+
/** Error (or message string) to throw, simulating a resolver failure. */
|
|
95
144
|
error?: Error | string;
|
|
96
|
-
/**
|
|
145
|
+
/** Array that receives every requirement passed to this resolver. */
|
|
97
146
|
calls?: R[];
|
|
98
147
|
}
|
|
99
148
|
/** Internal resolver definition type for mock resolvers */
|
|
@@ -102,12 +151,32 @@ interface MockResolverDef {
|
|
|
102
151
|
resolve: (req: Requirement, ctx: MockResolverContext) => Promise<void>;
|
|
103
152
|
}
|
|
104
153
|
/**
|
|
105
|
-
* Create a mock resolver
|
|
154
|
+
* Create a simple mock resolver that matches requirements by type and optionally
|
|
155
|
+
* records calls, injects delays, or throws errors.
|
|
156
|
+
*
|
|
157
|
+
* @param typeOrOptions - A requirement type string, or a full {@link MockResolverOptions} object.
|
|
158
|
+
* @returns A resolver definition that can be spread into a module's `resolvers` map.
|
|
159
|
+
*
|
|
160
|
+
* @example
|
|
161
|
+
* ```typescript
|
|
162
|
+
* const calls: Requirement[] = [];
|
|
163
|
+
* const mock = createMockResolver({ requirement: (r): r is MyReq => r.type === "LOAD", calls });
|
|
164
|
+
* ```
|
|
165
|
+
*
|
|
166
|
+
* @public
|
|
106
167
|
*/
|
|
107
168
|
declare function createMockResolver<R extends Requirement = Requirement>(typeOrOptions: string | MockResolverOptions<R>): MockResolverDef;
|
|
108
169
|
/**
|
|
109
170
|
* A mock resolver that captures requirements for manual resolution.
|
|
110
|
-
*
|
|
171
|
+
*
|
|
172
|
+
* @remarks
|
|
173
|
+
* Use this when you need fine-grained control over when and how requirements
|
|
174
|
+
* resolve. Requirements are queued in `pending` and stay unresolved until you
|
|
175
|
+
* explicitly call `resolve()` or `reject()`.
|
|
176
|
+
*
|
|
177
|
+
* @typeParam R - The requirement type this resolver handles.
|
|
178
|
+
*
|
|
179
|
+
* @public
|
|
111
180
|
*/
|
|
112
181
|
interface MockResolver<R extends Requirement = Requirement> {
|
|
113
182
|
/** All requirements received by this resolver */
|
|
@@ -130,8 +199,11 @@ interface MockResolver<R extends Requirement = Requirement> {
|
|
|
130
199
|
reset(): void;
|
|
131
200
|
}
|
|
132
201
|
/**
|
|
133
|
-
* Create a mock resolver that captures requirements instead of resolving them
|
|
134
|
-
*
|
|
202
|
+
* Create a mock resolver that captures requirements instead of resolving them,
|
|
203
|
+
* giving you manual control over when and how each requirement completes.
|
|
204
|
+
*
|
|
205
|
+
* @param _requirementType - The requirement `type` string this mock handles (used for documentation; matching is done by the test harness).
|
|
206
|
+
* @returns A {@link MockResolver} with a `handler` function suitable for passing to {@link createTestSystem} mocks.
|
|
135
207
|
*
|
|
136
208
|
* @example
|
|
137
209
|
* ```typescript
|
|
@@ -159,12 +231,18 @@ interface MockResolver<R extends Requirement = Requirement> {
|
|
|
159
231
|
*
|
|
160
232
|
* expect(system.facts.user).toEqual({ name: "John" });
|
|
161
233
|
* ```
|
|
234
|
+
*
|
|
235
|
+
* @public
|
|
162
236
|
*/
|
|
163
237
|
declare function mockResolver<R extends Requirement = Requirement>(_requirementType: string): MockResolver<R> & {
|
|
164
238
|
/** Handler that can be passed to createTestSystem mocks */
|
|
165
239
|
handler: (req: Requirement, ctx: MockResolverContext) => Promise<void>;
|
|
166
240
|
};
|
|
167
|
-
/**
|
|
241
|
+
/**
|
|
242
|
+
* Record of a single fact change captured by the test tracking plugin.
|
|
243
|
+
*
|
|
244
|
+
* @public
|
|
245
|
+
*/
|
|
168
246
|
interface FactChangeRecord {
|
|
169
247
|
/** The fact key that changed (without namespace prefix for namespaced systems) */
|
|
170
248
|
key: string;
|
|
@@ -179,6 +257,17 @@ interface FactChangeRecord {
|
|
|
179
257
|
/** Timestamp of the change */
|
|
180
258
|
timestamp: number;
|
|
181
259
|
}
|
|
260
|
+
/**
|
|
261
|
+
* A Directive system augmented with testing utilities.
|
|
262
|
+
*
|
|
263
|
+
* @remarks
|
|
264
|
+
* Extends {@link NamespacedSystem} with event/resolver/fact tracking, idle
|
|
265
|
+
* waiting, and assertion helpers. Created via {@link createTestSystem}.
|
|
266
|
+
*
|
|
267
|
+
* @typeParam Modules - The modules map that defines the system's schema.
|
|
268
|
+
*
|
|
269
|
+
* @public
|
|
270
|
+
*/
|
|
182
271
|
interface TestSystem<Modules extends ModulesMap> extends NamespacedSystem<Modules> {
|
|
183
272
|
/**
|
|
184
273
|
* Wait for all pending operations to complete.
|
|
@@ -219,6 +308,14 @@ interface TestSystem<Modules extends ModulesMap> extends NamespacedSystem<Module
|
|
|
219
308
|
*/
|
|
220
309
|
assertFactChanges(key: string, times: number): void;
|
|
221
310
|
}
|
|
311
|
+
/**
|
|
312
|
+
* Options for {@link createTestSystem}, extending the standard system options
|
|
313
|
+
* with mock resolver injection and automatic tracking.
|
|
314
|
+
*
|
|
315
|
+
* @typeParam Modules - The modules map that defines the system's schema.
|
|
316
|
+
*
|
|
317
|
+
* @public
|
|
318
|
+
*/
|
|
222
319
|
interface CreateTestSystemOptions<Modules extends ModulesMap> extends Omit<CreateSystemOptionsNamed<Modules>, "plugins"> {
|
|
223
320
|
/** Mock resolvers by type */
|
|
224
321
|
mocks?: {
|
|
@@ -228,7 +325,26 @@ interface CreateTestSystemOptions<Modules extends ModulesMap> extends Omit<Creat
|
|
|
228
325
|
plugins?: Array<any>;
|
|
229
326
|
}
|
|
230
327
|
/**
|
|
231
|
-
* Create a
|
|
328
|
+
* Create a Directive system instrumented for testing.
|
|
329
|
+
*
|
|
330
|
+
* Wraps {@link createSystem} with an automatic tracking plugin that records
|
|
331
|
+
* dispatched events, resolver calls, fact changes, and generated requirements.
|
|
332
|
+
* Mock resolvers can be injected via `options.mocks.resolvers` to replace
|
|
333
|
+
* real resolvers by requirement type.
|
|
334
|
+
*
|
|
335
|
+
* @param options - System configuration with optional mock resolvers and additional plugins.
|
|
336
|
+
* @returns A {@link TestSystem} with assertion helpers, idle waiting, and history tracking.
|
|
337
|
+
*
|
|
338
|
+
* @example
|
|
339
|
+
* ```typescript
|
|
340
|
+
* const system = createTestSystem({
|
|
341
|
+
* modules: { counter: counterModule },
|
|
342
|
+
* mocks: { resolvers: { INCREMENT: { resolve: (req, context) => { context.facts.count++; } } } },
|
|
343
|
+
* });
|
|
344
|
+
* system.start();
|
|
345
|
+
* ```
|
|
346
|
+
*
|
|
347
|
+
* @public
|
|
232
348
|
*/
|
|
233
349
|
declare function createTestSystem<Modules extends ModulesMap>(options: CreateTestSystemOptions<Modules>): TestSystem<Modules>;
|
|
234
350
|
|
package/dist/testing.d.ts
CHANGED
|
@@ -12,8 +12,12 @@ import { p as ModulesMap, q as CreateSystemOptionsNamed, R as Requirement, N as
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
|
-
* Flush all pending microtasks.
|
|
16
|
-
*
|
|
15
|
+
* Flush all pending microtasks by awaiting multiple rounds of `Promise.resolve()`.
|
|
16
|
+
*
|
|
17
|
+
* Call this after advancing fake timers to ensure all Promise callbacks
|
|
18
|
+
* (including nested microtasks) have run before making assertions.
|
|
19
|
+
*
|
|
20
|
+
* @returns A promise that resolves after all pending microtasks have been drained.
|
|
17
21
|
*
|
|
18
22
|
* @example
|
|
19
23
|
* ```typescript
|
|
@@ -24,15 +28,22 @@ import { p as ModulesMap, q as CreateSystemOptionsNamed, R as Requirement, N as
|
|
|
24
28
|
* vi.advanceTimersByTime(100); // Advance resolver delay
|
|
25
29
|
* await flushMicrotasks(); // Let resolver complete
|
|
26
30
|
* ```
|
|
31
|
+
*
|
|
32
|
+
* @public
|
|
27
33
|
*/
|
|
28
34
|
declare function flushMicrotasks(): Promise<void>;
|
|
29
35
|
/**
|
|
30
36
|
* Wait for the system to settle with fake timers enabled.
|
|
31
|
-
* Combines timer advancement with microtask flushing.
|
|
32
37
|
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
38
|
+
* Repeatedly advances fake timers in discrete steps while flushing microtasks,
|
|
39
|
+
* until no resolvers remain inflight or the time budget is exhausted.
|
|
40
|
+
*
|
|
41
|
+
* @param system - The Directive system to wait on (must expose {@link SystemInspection} via `inspect()`).
|
|
42
|
+
* @param advanceTime - Function that advances fake timers by a given number of milliseconds (e.g., `vi.advanceTimersByTime`).
|
|
43
|
+
* @param options - Configuration for total time budget, step size, and iteration limit.
|
|
44
|
+
* @returns A promise that resolves once the system is idle.
|
|
45
|
+
*
|
|
46
|
+
* @throws Error if the system does not settle within the configured time budget.
|
|
36
47
|
*
|
|
37
48
|
* @example
|
|
38
49
|
* ```typescript
|
|
@@ -48,6 +59,8 @@ declare function flushMicrotasks(): Promise<void>;
|
|
|
48
59
|
*
|
|
49
60
|
* expect(system.facts.result).toBe("done");
|
|
50
61
|
* ```
|
|
62
|
+
*
|
|
63
|
+
* @public
|
|
51
64
|
*/
|
|
52
65
|
declare function settleWithFakeTimers(system: {
|
|
53
66
|
inspect(): SystemInspection;
|
|
@@ -59,41 +72,77 @@ declare function settleWithFakeTimers(system: {
|
|
|
59
72
|
/** Maximum iterations before giving up (default: 1000) */
|
|
60
73
|
maxIterations?: number;
|
|
61
74
|
}): Promise<void>;
|
|
75
|
+
/**
|
|
76
|
+
* Standalone fake timer controller for tests that do not use Vitest/Jest fake timers.
|
|
77
|
+
*
|
|
78
|
+
* @remarks
|
|
79
|
+
* For most tests, prefer Vitest's `vi.useFakeTimers()` paired with
|
|
80
|
+
* {@link settleWithFakeTimers} for better integration. Use this interface
|
|
81
|
+
* only when you need a lightweight, framework-independent timer mock.
|
|
82
|
+
*
|
|
83
|
+
* @public
|
|
84
|
+
*/
|
|
62
85
|
interface FakeTimers {
|
|
63
|
-
/** Advance time by a number of milliseconds */
|
|
86
|
+
/** Advance time by a number of milliseconds, firing any timers that fall within the window. */
|
|
64
87
|
advance(ms: number): Promise<void>;
|
|
65
|
-
/** Advance to the next scheduled timer */
|
|
88
|
+
/** Advance to the next scheduled timer and fire its callback. */
|
|
66
89
|
next(): Promise<void>;
|
|
67
|
-
/** Run all pending timers */
|
|
90
|
+
/** Run all pending timers in chronological order. */
|
|
68
91
|
runAll(): Promise<void>;
|
|
69
|
-
/** Get current fake time */
|
|
92
|
+
/** Get the current fake time in milliseconds. */
|
|
70
93
|
now(): number;
|
|
71
|
-
/** Reset to time 0 */
|
|
94
|
+
/** Reset the clock to time 0 and discard all scheduled timers. */
|
|
72
95
|
reset(): void;
|
|
73
96
|
}
|
|
74
97
|
/**
|
|
75
|
-
* Create standalone fake timers for testing.
|
|
76
|
-
*
|
|
77
|
-
*
|
|
98
|
+
* Create standalone fake timers for testing without a framework timer mock.
|
|
99
|
+
*
|
|
100
|
+
* @remarks
|
|
101
|
+
* For most tests, prefer Vitest's `vi.useFakeTimers()` paired with
|
|
102
|
+
* {@link settleWithFakeTimers}. This factory is useful when you need an
|
|
103
|
+
* isolated timer that does not interfere with global timer state.
|
|
104
|
+
*
|
|
105
|
+
* @returns A {@link FakeTimers} controller with `advance`, `next`, `runAll`, `now`, and `reset` methods.
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* ```typescript
|
|
109
|
+
* const timers = createFakeTimers();
|
|
110
|
+
* // schedule work, then:
|
|
111
|
+
* await timers.advance(500);
|
|
112
|
+
* expect(timers.now()).toBe(500);
|
|
113
|
+
* ```
|
|
114
|
+
*
|
|
115
|
+
* @public
|
|
78
116
|
*/
|
|
79
117
|
declare function createFakeTimers(): FakeTimers;
|
|
80
|
-
/**
|
|
118
|
+
/**
|
|
119
|
+
* Context passed to mock resolver resolve functions.
|
|
120
|
+
*
|
|
121
|
+
* @public
|
|
122
|
+
*/
|
|
81
123
|
interface MockResolverContext {
|
|
82
124
|
/** Facts object (use type assertion for specific facts) */
|
|
83
125
|
facts: any;
|
|
84
126
|
/** Abort signal for cancellation */
|
|
85
127
|
signal: AbortSignal;
|
|
86
128
|
}
|
|
129
|
+
/**
|
|
130
|
+
* Configuration for a simple mock resolver created via {@link createMockResolver}.
|
|
131
|
+
*
|
|
132
|
+
* @typeParam R - The requirement type this resolver handles.
|
|
133
|
+
*
|
|
134
|
+
* @public
|
|
135
|
+
*/
|
|
87
136
|
interface MockResolverOptions<R extends Requirement = Requirement> {
|
|
88
|
-
/** Predicate to check if this resolver handles a requirement */
|
|
137
|
+
/** Predicate to check if this resolver handles a given requirement. */
|
|
89
138
|
requirement?: (req: Requirement) => req is R;
|
|
90
|
-
/** Mock implementation */
|
|
139
|
+
/** Mock implementation invoked when the resolver runs. */
|
|
91
140
|
resolve?: (req: R, ctx: MockResolverContext) => void | Promise<void>;
|
|
92
|
-
/**
|
|
141
|
+
/** Artificial delay in milliseconds before the resolver completes. */
|
|
93
142
|
delay?: number;
|
|
94
|
-
/**
|
|
143
|
+
/** Error (or message string) to throw, simulating a resolver failure. */
|
|
95
144
|
error?: Error | string;
|
|
96
|
-
/**
|
|
145
|
+
/** Array that receives every requirement passed to this resolver. */
|
|
97
146
|
calls?: R[];
|
|
98
147
|
}
|
|
99
148
|
/** Internal resolver definition type for mock resolvers */
|
|
@@ -102,12 +151,32 @@ interface MockResolverDef {
|
|
|
102
151
|
resolve: (req: Requirement, ctx: MockResolverContext) => Promise<void>;
|
|
103
152
|
}
|
|
104
153
|
/**
|
|
105
|
-
* Create a mock resolver
|
|
154
|
+
* Create a simple mock resolver that matches requirements by type and optionally
|
|
155
|
+
* records calls, injects delays, or throws errors.
|
|
156
|
+
*
|
|
157
|
+
* @param typeOrOptions - A requirement type string, or a full {@link MockResolverOptions} object.
|
|
158
|
+
* @returns A resolver definition that can be spread into a module's `resolvers` map.
|
|
159
|
+
*
|
|
160
|
+
* @example
|
|
161
|
+
* ```typescript
|
|
162
|
+
* const calls: Requirement[] = [];
|
|
163
|
+
* const mock = createMockResolver({ requirement: (r): r is MyReq => r.type === "LOAD", calls });
|
|
164
|
+
* ```
|
|
165
|
+
*
|
|
166
|
+
* @public
|
|
106
167
|
*/
|
|
107
168
|
declare function createMockResolver<R extends Requirement = Requirement>(typeOrOptions: string | MockResolverOptions<R>): MockResolverDef;
|
|
108
169
|
/**
|
|
109
170
|
* A mock resolver that captures requirements for manual resolution.
|
|
110
|
-
*
|
|
171
|
+
*
|
|
172
|
+
* @remarks
|
|
173
|
+
* Use this when you need fine-grained control over when and how requirements
|
|
174
|
+
* resolve. Requirements are queued in `pending` and stay unresolved until you
|
|
175
|
+
* explicitly call `resolve()` or `reject()`.
|
|
176
|
+
*
|
|
177
|
+
* @typeParam R - The requirement type this resolver handles.
|
|
178
|
+
*
|
|
179
|
+
* @public
|
|
111
180
|
*/
|
|
112
181
|
interface MockResolver<R extends Requirement = Requirement> {
|
|
113
182
|
/** All requirements received by this resolver */
|
|
@@ -130,8 +199,11 @@ interface MockResolver<R extends Requirement = Requirement> {
|
|
|
130
199
|
reset(): void;
|
|
131
200
|
}
|
|
132
201
|
/**
|
|
133
|
-
* Create a mock resolver that captures requirements instead of resolving them
|
|
134
|
-
*
|
|
202
|
+
* Create a mock resolver that captures requirements instead of resolving them,
|
|
203
|
+
* giving you manual control over when and how each requirement completes.
|
|
204
|
+
*
|
|
205
|
+
* @param _requirementType - The requirement `type` string this mock handles (used for documentation; matching is done by the test harness).
|
|
206
|
+
* @returns A {@link MockResolver} with a `handler` function suitable for passing to {@link createTestSystem} mocks.
|
|
135
207
|
*
|
|
136
208
|
* @example
|
|
137
209
|
* ```typescript
|
|
@@ -159,12 +231,18 @@ interface MockResolver<R extends Requirement = Requirement> {
|
|
|
159
231
|
*
|
|
160
232
|
* expect(system.facts.user).toEqual({ name: "John" });
|
|
161
233
|
* ```
|
|
234
|
+
*
|
|
235
|
+
* @public
|
|
162
236
|
*/
|
|
163
237
|
declare function mockResolver<R extends Requirement = Requirement>(_requirementType: string): MockResolver<R> & {
|
|
164
238
|
/** Handler that can be passed to createTestSystem mocks */
|
|
165
239
|
handler: (req: Requirement, ctx: MockResolverContext) => Promise<void>;
|
|
166
240
|
};
|
|
167
|
-
/**
|
|
241
|
+
/**
|
|
242
|
+
* Record of a single fact change captured by the test tracking plugin.
|
|
243
|
+
*
|
|
244
|
+
* @public
|
|
245
|
+
*/
|
|
168
246
|
interface FactChangeRecord {
|
|
169
247
|
/** The fact key that changed (without namespace prefix for namespaced systems) */
|
|
170
248
|
key: string;
|
|
@@ -179,6 +257,17 @@ interface FactChangeRecord {
|
|
|
179
257
|
/** Timestamp of the change */
|
|
180
258
|
timestamp: number;
|
|
181
259
|
}
|
|
260
|
+
/**
|
|
261
|
+
* A Directive system augmented with testing utilities.
|
|
262
|
+
*
|
|
263
|
+
* @remarks
|
|
264
|
+
* Extends {@link NamespacedSystem} with event/resolver/fact tracking, idle
|
|
265
|
+
* waiting, and assertion helpers. Created via {@link createTestSystem}.
|
|
266
|
+
*
|
|
267
|
+
* @typeParam Modules - The modules map that defines the system's schema.
|
|
268
|
+
*
|
|
269
|
+
* @public
|
|
270
|
+
*/
|
|
182
271
|
interface TestSystem<Modules extends ModulesMap> extends NamespacedSystem<Modules> {
|
|
183
272
|
/**
|
|
184
273
|
* Wait for all pending operations to complete.
|
|
@@ -219,6 +308,14 @@ interface TestSystem<Modules extends ModulesMap> extends NamespacedSystem<Module
|
|
|
219
308
|
*/
|
|
220
309
|
assertFactChanges(key: string, times: number): void;
|
|
221
310
|
}
|
|
311
|
+
/**
|
|
312
|
+
* Options for {@link createTestSystem}, extending the standard system options
|
|
313
|
+
* with mock resolver injection and automatic tracking.
|
|
314
|
+
*
|
|
315
|
+
* @typeParam Modules - The modules map that defines the system's schema.
|
|
316
|
+
*
|
|
317
|
+
* @public
|
|
318
|
+
*/
|
|
222
319
|
interface CreateTestSystemOptions<Modules extends ModulesMap> extends Omit<CreateSystemOptionsNamed<Modules>, "plugins"> {
|
|
223
320
|
/** Mock resolvers by type */
|
|
224
321
|
mocks?: {
|
|
@@ -228,7 +325,26 @@ interface CreateTestSystemOptions<Modules extends ModulesMap> extends Omit<Creat
|
|
|
228
325
|
plugins?: Array<any>;
|
|
229
326
|
}
|
|
230
327
|
/**
|
|
231
|
-
* Create a
|
|
328
|
+
* Create a Directive system instrumented for testing.
|
|
329
|
+
*
|
|
330
|
+
* Wraps {@link createSystem} with an automatic tracking plugin that records
|
|
331
|
+
* dispatched events, resolver calls, fact changes, and generated requirements.
|
|
332
|
+
* Mock resolvers can be injected via `options.mocks.resolvers` to replace
|
|
333
|
+
* real resolvers by requirement type.
|
|
334
|
+
*
|
|
335
|
+
* @param options - System configuration with optional mock resolvers and additional plugins.
|
|
336
|
+
* @returns A {@link TestSystem} with assertion helpers, idle waiting, and history tracking.
|
|
337
|
+
*
|
|
338
|
+
* @example
|
|
339
|
+
* ```typescript
|
|
340
|
+
* const system = createTestSystem({
|
|
341
|
+
* modules: { counter: counterModule },
|
|
342
|
+
* mocks: { resolvers: { INCREMENT: { resolve: (req, context) => { context.facts.count++; } } } },
|
|
343
|
+
* });
|
|
344
|
+
* system.start();
|
|
345
|
+
* ```
|
|
346
|
+
*
|
|
347
|
+
* @public
|
|
232
348
|
*/
|
|
233
349
|
declare function createTestSystem<Modules extends ModulesMap>(options: CreateTestSystemOptions<Modules>): TestSystem<Modules>;
|
|
234
350
|
|