@siglo/testing 0.0.0-stage → 1.0.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/LICENSE +21 -0
- package/README.md +189 -2
- package/dist/index.d.ts +115 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +342 -0
- package/dist/index.js.map +1 -0
- package/package.json +51 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2017 Jerico de guzman
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,190 @@
|
|
|
1
|
-
#
|
|
1
|
+
# 09. Testing and Replay
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
`@siglo/testing` provides a comprehensive, zero-flake test harness for deterministic execution, step mocking, spy inspection, virtual timers, execution trace snapshots, and production failure replay.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. The Workflow Harness
|
|
8
|
+
|
|
9
|
+
Create a test harness wrapping any workflow:
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
import { createWorkflowHarness } from '@siglo/testing';
|
|
13
|
+
import { orderWorkflow } from './order.workflow';
|
|
14
|
+
|
|
15
|
+
const harness = createWorkflowHarness(orderWorkflow, {
|
|
16
|
+
services: {
|
|
17
|
+
paymentGateway: mockPaymentGateway
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
const result = await harness.run({ orderId: 'ord-100' });
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## 2. Spies and Assertions
|
|
27
|
+
|
|
28
|
+
Inspect step calls, attempt counts, inputs, and outputs:
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
const spy = harness.spyStep('validateOrder');
|
|
32
|
+
|
|
33
|
+
await harness.run({ orderId: 'ord-100' });
|
|
34
|
+
|
|
35
|
+
console.log(spy.called); // true
|
|
36
|
+
console.log(spy.callCount); // 1
|
|
37
|
+
console.log(spy.firstCall()?.input); // { orderId: 'ord-100' }
|
|
38
|
+
|
|
39
|
+
// Built-in assertions
|
|
40
|
+
harness.assertStepExecuted('validateOrder', 1);
|
|
41
|
+
harness.assertStepRetried('chargeCard', 2);
|
|
42
|
+
harness.assertStepFailed('riskyStep', /timeout/);
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## 3. Step Mocking
|
|
48
|
+
|
|
49
|
+
Replace third-party dependencies or expensive external APIs without modifying workflow code:
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
harness.mockStep('callStripe', async (param) => {
|
|
53
|
+
return { chargeId: 'ch_mock_123', status: 'SUCCESS' };
|
|
54
|
+
});
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## 4. Fake Clock & Virtual Timers
|
|
60
|
+
|
|
61
|
+
Control virtual timestamps for harness trace records without `setTimeout` delays in tests. Note that `FakeClock` advances its own timestamp counter and `tick()` flushes pending microtasks via `setImmediate`; it does not mock Node's global `Date.now` or `setTimeout`.
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
import { FakeClock, createWorkflowHarness } from '@siglo/testing';
|
|
65
|
+
|
|
66
|
+
const clock = new FakeClock(1000);
|
|
67
|
+
const harness = createWorkflowHarness(workflow, { clock });
|
|
68
|
+
|
|
69
|
+
// Advance virtual clock timestamp
|
|
70
|
+
clock.advanceTime(5000);
|
|
71
|
+
|
|
72
|
+
// Advance virtual clock and flush microtask loop
|
|
73
|
+
await clock.tick(1000);
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## 5. Execution Records and Failure Replay
|
|
79
|
+
|
|
80
|
+
Export sanitized execution records from real executions or staging runs and replay them locally:
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
// 1. Export sanitized record from execution
|
|
84
|
+
const record = harness.exportExecutionRecord({
|
|
85
|
+
excludeKeys: ['internalSecret']
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
// 2. Replay execution against workflow definition
|
|
89
|
+
import { replayExecution } from '@siglo/testing';
|
|
90
|
+
|
|
91
|
+
const replayResult = await replayExecution(record, orderWorkflow, {
|
|
92
|
+
substituteFixtures: {
|
|
93
|
+
// Replace flaky third-party API with recorded response
|
|
94
|
+
chargeCard: { success: true, txnId: 'txn_999' }
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
console.log(replayResult.matched); // true or false
|
|
99
|
+
console.log(replayResult.discrepancies); // List of mismatches if any
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## Minimal Example
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
import { expect } from 'chai';
|
|
108
|
+
import { createWorkflowHarness } from '@siglo/testing';
|
|
109
|
+
import { Step, flow } from '@siglo/core';
|
|
110
|
+
|
|
111
|
+
const s1 = Step.create('add', (p: { x: number }) => ({ res: p.x + 5 }));
|
|
112
|
+
const wf = flow(s1);
|
|
113
|
+
|
|
114
|
+
const harness = createWorkflowHarness(wf);
|
|
115
|
+
const res = await harness.run({ x: 10 });
|
|
116
|
+
expect(res.res).to.equal(15);
|
|
117
|
+
harness.assertStepExecuted('add', 1);
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Failure Example: Catching Regressions with Replay
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
import { replayExecution } from '@siglo/testing';
|
|
126
|
+
import { Step, flow } from '@siglo/core';
|
|
127
|
+
|
|
128
|
+
// Modified workflow with a bug: calculates 10% tax instead of 5%
|
|
129
|
+
const buggyWf = flow(
|
|
130
|
+
Step.create('calcTax', (p: { amount: number }) => ({ tax: p.amount * 0.10 }))
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
const recordedBaseline = {
|
|
134
|
+
input: { amount: 100 },
|
|
135
|
+
output: { tax: 5 }, // Expected 5 from baseline
|
|
136
|
+
trace: [],
|
|
137
|
+
recordedAt: new Date().toISOString()
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
const result = await replayExecution(recordedBaseline, buggyWf);
|
|
141
|
+
|
|
142
|
+
if (!result.matched) {
|
|
143
|
+
console.error('Regression Detected:');
|
|
144
|
+
for (const diff of result.discrepancies) {
|
|
145
|
+
console.error(' -', diff);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## Testing Example: Full Mocking & Spying
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
import { expect } from 'chai';
|
|
156
|
+
import { createWorkflowHarness } from '@siglo/testing';
|
|
157
|
+
import { Step, flow } from '@siglo/core';
|
|
158
|
+
|
|
159
|
+
const s1 = Step.create('fetchUser', () => ({ user: 'Alice' }));
|
|
160
|
+
const s2 = Step.create('emailUser', (p: any) => ({ sent: true }));
|
|
161
|
+
const wf = flow(s1, s2);
|
|
162
|
+
|
|
163
|
+
describe('Full Harness Suite', () => {
|
|
164
|
+
it('mocks step and asserts spy calls', async () => {
|
|
165
|
+
const harness = createWorkflowHarness(wf);
|
|
166
|
+
const emailSpy = harness.spyStep('emailUser');
|
|
167
|
+
|
|
168
|
+
harness.mockStep('fetchUser', () => ({ user: 'MockedUser' }));
|
|
169
|
+
|
|
170
|
+
const result = await harness.run();
|
|
171
|
+
expect(result.user).to.equal('MockedUser');
|
|
172
|
+
expect(emailSpy.called).to.be.true;
|
|
173
|
+
expect(emailSpy.firstCall()?.input.user).to.equal('MockedUser');
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## Operational Caveats
|
|
181
|
+
|
|
182
|
+
1. **Secret Redaction**: Always run `sanitizeExecutionRecord()` before writing execution records to bug reports or test fixtures. Defaults automatically redact passwords, API keys, and credit cards.
|
|
183
|
+
2. **Deterministic Randomness**: If steps generate UUIDs or timestamps, inject a deterministic clock or generator via `param.$services` so replays produce matching records.
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## API Reference Links
|
|
188
|
+
|
|
189
|
+
- [TypeScript Reference](../../docs/10-typescript-reference.md)
|
|
190
|
+
- [CLI Reference](../../docs/adapters/cli.md)
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { StorageAdapter } from '@siglo/core';
|
|
2
|
+
export interface StepTraceRecord {
|
|
3
|
+
stepName: string;
|
|
4
|
+
phase: 'start' | 'retry' | 'complete' | 'fail' | 'skip';
|
|
5
|
+
timestamp: number;
|
|
6
|
+
input: any;
|
|
7
|
+
output?: any;
|
|
8
|
+
error?: any;
|
|
9
|
+
attempt?: number;
|
|
10
|
+
}
|
|
11
|
+
export interface ExecutionRecord {
|
|
12
|
+
workflowVersion?: string | number;
|
|
13
|
+
input: any;
|
|
14
|
+
output?: any;
|
|
15
|
+
error?: any;
|
|
16
|
+
trace: StepTraceRecord[];
|
|
17
|
+
recordedAt: string;
|
|
18
|
+
}
|
|
19
|
+
export interface ReplayOptions {
|
|
20
|
+
substituteFixtures?: Record<string, any>;
|
|
21
|
+
excludeKeys?: string[];
|
|
22
|
+
}
|
|
23
|
+
export interface ReplayResult {
|
|
24
|
+
matched: boolean;
|
|
25
|
+
expectedOutput: any;
|
|
26
|
+
actualOutput: any;
|
|
27
|
+
discrepancies: string[];
|
|
28
|
+
}
|
|
29
|
+
export declare class FakeClock {
|
|
30
|
+
private currentTime;
|
|
31
|
+
constructor(initialTime?: number);
|
|
32
|
+
now(): number;
|
|
33
|
+
advanceTime(ms: number): number;
|
|
34
|
+
tick(ms?: number): Promise<void>;
|
|
35
|
+
reset(toTime?: number): void;
|
|
36
|
+
}
|
|
37
|
+
export declare class InMemoryStorageFake implements StorageAdapter {
|
|
38
|
+
readonly name = "in-memory-fake";
|
|
39
|
+
private checkpoints;
|
|
40
|
+
private cache;
|
|
41
|
+
contextChanges: any[];
|
|
42
|
+
onContextChange(event: any): Promise<void>;
|
|
43
|
+
saveCheckpoint(checkpoint: any): Promise<void>;
|
|
44
|
+
getCheckpoint(key: string): Promise<any>;
|
|
45
|
+
getCachedStep(key: string): Promise<any>;
|
|
46
|
+
setCachedStep(key: string, val: any): Promise<void>;
|
|
47
|
+
clear(): void;
|
|
48
|
+
getCheckpoints(): Map<string, any>;
|
|
49
|
+
}
|
|
50
|
+
export declare class StepSpy {
|
|
51
|
+
readonly name: string;
|
|
52
|
+
readonly calls: Array<{
|
|
53
|
+
input: any;
|
|
54
|
+
output?: any;
|
|
55
|
+
error?: any;
|
|
56
|
+
timestamp: number;
|
|
57
|
+
}>;
|
|
58
|
+
constructor(name: string);
|
|
59
|
+
get called(): boolean;
|
|
60
|
+
get callCount(): number;
|
|
61
|
+
firstCall(): {
|
|
62
|
+
input: any;
|
|
63
|
+
output?: any;
|
|
64
|
+
error?: any;
|
|
65
|
+
timestamp: number;
|
|
66
|
+
} | undefined;
|
|
67
|
+
lastCall(): {
|
|
68
|
+
input: any;
|
|
69
|
+
output?: any;
|
|
70
|
+
error?: any;
|
|
71
|
+
timestamp: number;
|
|
72
|
+
} | undefined;
|
|
73
|
+
record(call: {
|
|
74
|
+
input: any;
|
|
75
|
+
output?: any;
|
|
76
|
+
error?: any;
|
|
77
|
+
timestamp: number;
|
|
78
|
+
}): void;
|
|
79
|
+
}
|
|
80
|
+
export declare function sanitizeExecutionRecord(record: ExecutionRecord, options?: {
|
|
81
|
+
excludeKeys?: string[];
|
|
82
|
+
}): ExecutionRecord;
|
|
83
|
+
export interface HarnessOptions {
|
|
84
|
+
services?: Record<string, any>;
|
|
85
|
+
clock?: FakeClock;
|
|
86
|
+
storage?: InMemoryStorageFake;
|
|
87
|
+
recordTrace?: boolean;
|
|
88
|
+
}
|
|
89
|
+
export declare class WorkflowHarness {
|
|
90
|
+
private workflow;
|
|
91
|
+
private options;
|
|
92
|
+
private mocks;
|
|
93
|
+
private spies;
|
|
94
|
+
private trace;
|
|
95
|
+
private lastRunResult;
|
|
96
|
+
clock: FakeClock;
|
|
97
|
+
storage: InMemoryStorageFake;
|
|
98
|
+
constructor(workflow: any, options?: HarnessOptions);
|
|
99
|
+
mockStep(stepName: string, mockImpl: (param: any) => any): this;
|
|
100
|
+
spyStep(stepName: string): StepSpy;
|
|
101
|
+
getTrace(): StepTraceRecord[];
|
|
102
|
+
injectEvent(eventName: string, correlationKey: string, payload?: any): Promise<any>;
|
|
103
|
+
private wrapWorkflowSteps;
|
|
104
|
+
run(input?: any, execOptions?: any): Promise<any>;
|
|
105
|
+
execute(input?: any, execOptions?: any): Promise<any>;
|
|
106
|
+
assertStepExecuted(stepName: string, times?: number): void;
|
|
107
|
+
assertStepRetried(stepName: string, minAttempts?: number): void;
|
|
108
|
+
assertStepFailed(stepName: string, errorPattern?: string | RegExp): void;
|
|
109
|
+
exportExecutionRecord(options?: {
|
|
110
|
+
excludeKeys?: string[];
|
|
111
|
+
}): ExecutionRecord;
|
|
112
|
+
}
|
|
113
|
+
export declare function createWorkflowHarness(workflow: any, options?: HarnessOptions): WorkflowHarness;
|
|
114
|
+
export declare function replayExecution(record: ExecutionRecord, workflow: any, options?: ReplayOptions): Promise<ReplayResult>;
|
|
115
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WorkflowHarness = exports.StepSpy = exports.InMemoryStorageFake = exports.FakeClock = void 0;
|
|
4
|
+
exports.sanitizeExecutionRecord = sanitizeExecutionRecord;
|
|
5
|
+
exports.createWorkflowHarness = createWorkflowHarness;
|
|
6
|
+
exports.replayExecution = replayExecution;
|
|
7
|
+
const core_1 = require("@siglo/core");
|
|
8
|
+
class FakeClock {
|
|
9
|
+
currentTime;
|
|
10
|
+
constructor(initialTime = Date.now()) {
|
|
11
|
+
this.currentTime = initialTime;
|
|
12
|
+
}
|
|
13
|
+
now() {
|
|
14
|
+
return this.currentTime;
|
|
15
|
+
}
|
|
16
|
+
advanceTime(ms) {
|
|
17
|
+
this.currentTime += ms;
|
|
18
|
+
return this.currentTime;
|
|
19
|
+
}
|
|
20
|
+
tick(ms = 0) {
|
|
21
|
+
this.advanceTime(ms);
|
|
22
|
+
return new Promise(resolve => setImmediate(resolve));
|
|
23
|
+
}
|
|
24
|
+
reset(toTime = Date.now()) {
|
|
25
|
+
this.currentTime = toTime;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
exports.FakeClock = FakeClock;
|
|
29
|
+
class InMemoryStorageFake {
|
|
30
|
+
name = 'in-memory-fake';
|
|
31
|
+
checkpoints = new Map();
|
|
32
|
+
cache = new Map();
|
|
33
|
+
contextChanges = [];
|
|
34
|
+
async onContextChange(event) {
|
|
35
|
+
this.contextChanges.push(event);
|
|
36
|
+
}
|
|
37
|
+
async saveCheckpoint(checkpoint) {
|
|
38
|
+
const key = checkpoint.stackId || checkpoint.id || 'default';
|
|
39
|
+
this.checkpoints.set(key, JSON.parse(JSON.stringify(checkpoint)));
|
|
40
|
+
}
|
|
41
|
+
async getCheckpoint(key) {
|
|
42
|
+
const item = this.checkpoints.get(key);
|
|
43
|
+
return item ? JSON.parse(JSON.stringify(item)) : undefined;
|
|
44
|
+
}
|
|
45
|
+
async getCachedStep(key) {
|
|
46
|
+
return this.cache.get(key);
|
|
47
|
+
}
|
|
48
|
+
async setCachedStep(key, val) {
|
|
49
|
+
this.cache.set(key, val);
|
|
50
|
+
}
|
|
51
|
+
clear() {
|
|
52
|
+
this.checkpoints.clear();
|
|
53
|
+
this.cache.clear();
|
|
54
|
+
this.contextChanges = [];
|
|
55
|
+
}
|
|
56
|
+
getCheckpoints() {
|
|
57
|
+
return new Map(this.checkpoints);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
exports.InMemoryStorageFake = InMemoryStorageFake;
|
|
61
|
+
class StepSpy {
|
|
62
|
+
name;
|
|
63
|
+
calls = [];
|
|
64
|
+
constructor(name) {
|
|
65
|
+
this.name = name;
|
|
66
|
+
}
|
|
67
|
+
get called() {
|
|
68
|
+
return this.calls.length > 0;
|
|
69
|
+
}
|
|
70
|
+
get callCount() {
|
|
71
|
+
return this.calls.length;
|
|
72
|
+
}
|
|
73
|
+
firstCall() {
|
|
74
|
+
return this.calls[0];
|
|
75
|
+
}
|
|
76
|
+
lastCall() {
|
|
77
|
+
return this.calls[this.calls.length - 1];
|
|
78
|
+
}
|
|
79
|
+
record(call) {
|
|
80
|
+
this.calls.push(call);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
exports.StepSpy = StepSpy;
|
|
84
|
+
const DEFAULT_SECRET_KEYS = new Set([
|
|
85
|
+
'password',
|
|
86
|
+
'token',
|
|
87
|
+
'secret',
|
|
88
|
+
'authorization',
|
|
89
|
+
'apikey',
|
|
90
|
+
'api_key',
|
|
91
|
+
'creditcard',
|
|
92
|
+
'cardnumber',
|
|
93
|
+
'cvv',
|
|
94
|
+
'ssn',
|
|
95
|
+
'privatekey',
|
|
96
|
+
'private_key'
|
|
97
|
+
]);
|
|
98
|
+
function sanitizeExecutionRecord(record, options = {}) {
|
|
99
|
+
const customExcludes = new Set((options.excludeKeys || []).map(k => k.toLowerCase()));
|
|
100
|
+
const sanitizeVal = (val) => {
|
|
101
|
+
if (!val || typeof val !== 'object') {
|
|
102
|
+
return val;
|
|
103
|
+
}
|
|
104
|
+
if (Array.isArray(val)) {
|
|
105
|
+
return val.map(sanitizeVal);
|
|
106
|
+
}
|
|
107
|
+
const clean = {};
|
|
108
|
+
for (const [k, v] of Object.entries(val)) {
|
|
109
|
+
const lowerKey = k.toLowerCase();
|
|
110
|
+
if (DEFAULT_SECRET_KEYS.has(lowerKey) || customExcludes.has(lowerKey)) {
|
|
111
|
+
clean[k] = '[REDACTED]';
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
clean[k] = sanitizeVal(v);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return clean;
|
|
118
|
+
};
|
|
119
|
+
return {
|
|
120
|
+
workflowVersion: record.workflowVersion,
|
|
121
|
+
recordedAt: record.recordedAt,
|
|
122
|
+
input: sanitizeVal(record.input),
|
|
123
|
+
output: sanitizeVal(record.output),
|
|
124
|
+
error: record.error ? (record.error.message || String(record.error)) : undefined,
|
|
125
|
+
trace: record.trace.map(t => ({
|
|
126
|
+
...t,
|
|
127
|
+
input: sanitizeVal(t.input),
|
|
128
|
+
output: sanitizeVal(t.output)
|
|
129
|
+
}))
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
class WorkflowHarness {
|
|
133
|
+
workflow;
|
|
134
|
+
options;
|
|
135
|
+
mocks = new Map();
|
|
136
|
+
spies = new Map();
|
|
137
|
+
trace = [];
|
|
138
|
+
lastRunResult;
|
|
139
|
+
clock;
|
|
140
|
+
storage;
|
|
141
|
+
constructor(workflow, options = {}) {
|
|
142
|
+
this.workflow = workflow;
|
|
143
|
+
this.options = options;
|
|
144
|
+
this.clock = options.clock || new FakeClock();
|
|
145
|
+
this.storage = options.storage || new InMemoryStorageFake();
|
|
146
|
+
}
|
|
147
|
+
mockStep(stepName, mockImpl) {
|
|
148
|
+
this.mocks.set(stepName, mockImpl);
|
|
149
|
+
return this;
|
|
150
|
+
}
|
|
151
|
+
spyStep(stepName) {
|
|
152
|
+
let spy = this.spies.get(stepName);
|
|
153
|
+
if (!spy) {
|
|
154
|
+
spy = new StepSpy(stepName);
|
|
155
|
+
this.spies.set(stepName, spy);
|
|
156
|
+
}
|
|
157
|
+
return spy;
|
|
158
|
+
}
|
|
159
|
+
getTrace() {
|
|
160
|
+
return [...this.trace];
|
|
161
|
+
}
|
|
162
|
+
async injectEvent(eventName, correlationKey, payload) {
|
|
163
|
+
const res = await (0, core_1.resumeWorkflow)(this.workflow, correlationKey, payload, { pojo: true });
|
|
164
|
+
return (0, core_1.toPOJO)(res);
|
|
165
|
+
}
|
|
166
|
+
wrapWorkflowSteps() {
|
|
167
|
+
const rawSteps = (0, core_1.isFlow)(this.workflow) ? this.workflow.steps : [this.workflow];
|
|
168
|
+
const wrappedSteps = rawSteps.map((origStep) => {
|
|
169
|
+
const name = origStep.name || origStep.func || 'anonymous';
|
|
170
|
+
const mockFn = this.mocks.get(name);
|
|
171
|
+
const spy = this.spies.get(name);
|
|
172
|
+
const instrumentedAction = async (param) => {
|
|
173
|
+
const ts = this.clock.now();
|
|
174
|
+
this.trace.push({
|
|
175
|
+
stepName: name,
|
|
176
|
+
phase: 'start',
|
|
177
|
+
timestamp: ts,
|
|
178
|
+
input: (0, core_1.toPOJO)(param),
|
|
179
|
+
attempt: param?.$attempt || 1
|
|
180
|
+
});
|
|
181
|
+
try {
|
|
182
|
+
let out;
|
|
183
|
+
if (mockFn) {
|
|
184
|
+
out = await mockFn(param);
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
out = await origStep.action(param);
|
|
188
|
+
}
|
|
189
|
+
if (spy) {
|
|
190
|
+
spy.record({ input: (0, core_1.toPOJO)(param), output: out, timestamp: ts });
|
|
191
|
+
}
|
|
192
|
+
this.trace.push({
|
|
193
|
+
stepName: name,
|
|
194
|
+
phase: 'complete',
|
|
195
|
+
timestamp: this.clock.now(),
|
|
196
|
+
input: (0, core_1.toPOJO)(param),
|
|
197
|
+
output: out
|
|
198
|
+
});
|
|
199
|
+
return out;
|
|
200
|
+
}
|
|
201
|
+
catch (err) {
|
|
202
|
+
if (spy) {
|
|
203
|
+
spy.record({ input: (0, core_1.toPOJO)(param), error: err, timestamp: ts });
|
|
204
|
+
}
|
|
205
|
+
this.trace.push({
|
|
206
|
+
stepName: name,
|
|
207
|
+
phase: 'fail',
|
|
208
|
+
timestamp: this.clock.now(),
|
|
209
|
+
input: (0, core_1.toPOJO)(param),
|
|
210
|
+
error: err?.message || String(err)
|
|
211
|
+
});
|
|
212
|
+
throw err;
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
const clone = Object.assign(Object.create(Object.getPrototypeOf(origStep)), origStep);
|
|
216
|
+
clone.action = instrumentedAction;
|
|
217
|
+
return clone;
|
|
218
|
+
});
|
|
219
|
+
return (0, core_1.flow)(...wrappedSteps);
|
|
220
|
+
}
|
|
221
|
+
async run(input = {}, execOptions = {}) {
|
|
222
|
+
(0, core_1.useStorage)(this.storage);
|
|
223
|
+
const instrumented = this.wrapWorkflowSteps();
|
|
224
|
+
const mergedServices = {
|
|
225
|
+
...(this.options.services || {}),
|
|
226
|
+
...(execOptions.services || {})
|
|
227
|
+
};
|
|
228
|
+
const result = await instrumented.run(input, {
|
|
229
|
+
...execOptions,
|
|
230
|
+
services: mergedServices,
|
|
231
|
+
pojo: execOptions.pojo !== false
|
|
232
|
+
});
|
|
233
|
+
this.lastRunResult = result;
|
|
234
|
+
return result;
|
|
235
|
+
}
|
|
236
|
+
async execute(input = {}, execOptions = {}) {
|
|
237
|
+
return this.run(input, execOptions);
|
|
238
|
+
}
|
|
239
|
+
assertStepExecuted(stepName, times) {
|
|
240
|
+
const executions = this.trace.filter(t => t.stepName === stepName && t.phase === 'complete');
|
|
241
|
+
if (times !== undefined) {
|
|
242
|
+
if (executions.length !== times) {
|
|
243
|
+
throw new Error(`Expected step '${stepName}' to be executed ${times} time(s), but was executed ${executions.length} time(s).`);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
if (executions.length === 0) {
|
|
248
|
+
throw new Error(`Expected step '${stepName}' to be executed, but was not found in completed trace.`);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
assertStepRetried(stepName, minAttempts = 2) {
|
|
253
|
+
const attempts = this.trace.filter(t => t.stepName === stepName && (t.phase === 'start' || t.phase === 'retry'));
|
|
254
|
+
if (attempts.length < minAttempts) {
|
|
255
|
+
throw new Error(`Expected step '${stepName}' to have at least ${minAttempts} attempts, but found ${attempts.length}.`);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
assertStepFailed(stepName, errorPattern) {
|
|
259
|
+
const failures = this.trace.filter(t => t.stepName === stepName && t.phase === 'fail');
|
|
260
|
+
if (failures.length === 0) {
|
|
261
|
+
throw new Error(`Expected step '${stepName}' to fail, but no failure was recorded in trace.`);
|
|
262
|
+
}
|
|
263
|
+
if (errorPattern) {
|
|
264
|
+
const matched = failures.some(f => {
|
|
265
|
+
const msg = f.error || '';
|
|
266
|
+
return errorPattern instanceof RegExp ? errorPattern.test(msg) : msg.includes(errorPattern);
|
|
267
|
+
});
|
|
268
|
+
if (!matched) {
|
|
269
|
+
throw new Error(`Step '${stepName}' failed, but error did not match expected pattern '${errorPattern}'.`);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
exportExecutionRecord(options) {
|
|
274
|
+
const lastComplete = [...this.trace].reverse().find(t => t.phase === 'complete');
|
|
275
|
+
const lastFail = [...this.trace].reverse().find(t => t.phase === 'fail');
|
|
276
|
+
const firstStart = this.trace.find(t => t.phase === 'start');
|
|
277
|
+
const rawRecord = {
|
|
278
|
+
workflowVersion: this.workflow?.workflowVersion,
|
|
279
|
+
input: firstStart?.input || {},
|
|
280
|
+
output: this.lastRunResult !== undefined ? this.lastRunResult : lastComplete?.output,
|
|
281
|
+
error: lastFail?.error,
|
|
282
|
+
trace: this.trace,
|
|
283
|
+
recordedAt: new Date(this.clock.now()).toISOString()
|
|
284
|
+
};
|
|
285
|
+
return sanitizeExecutionRecord(rawRecord, options);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
exports.WorkflowHarness = WorkflowHarness;
|
|
289
|
+
function createWorkflowHarness(workflow, options = {}) {
|
|
290
|
+
return new WorkflowHarness(workflow, options);
|
|
291
|
+
}
|
|
292
|
+
function normalizeForComparison(val) {
|
|
293
|
+
if (!val || typeof val !== 'object')
|
|
294
|
+
return val;
|
|
295
|
+
if (Array.isArray(val))
|
|
296
|
+
return val.map(normalizeForComparison);
|
|
297
|
+
const clean = {};
|
|
298
|
+
for (const [k, v] of Object.entries(val)) {
|
|
299
|
+
if (k === 'stackId' || k === '$stackId' || k === '$stepId' || k === '$steps' || k === '$history') {
|
|
300
|
+
continue;
|
|
301
|
+
}
|
|
302
|
+
clean[k] = normalizeForComparison(v);
|
|
303
|
+
}
|
|
304
|
+
return clean;
|
|
305
|
+
}
|
|
306
|
+
async function replayExecution(record, workflow, options = {}) {
|
|
307
|
+
const harness = createWorkflowHarness(workflow);
|
|
308
|
+
if (options.substituteFixtures) {
|
|
309
|
+
for (const [stepName, fixtureOutput] of Object.entries(options.substituteFixtures)) {
|
|
310
|
+
harness.mockStep(stepName, () => fixtureOutput);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
let actualOutput;
|
|
314
|
+
let actualError;
|
|
315
|
+
try {
|
|
316
|
+
actualOutput = await harness.run(record.input);
|
|
317
|
+
}
|
|
318
|
+
catch (err) {
|
|
319
|
+
actualError = err.message || String(err);
|
|
320
|
+
}
|
|
321
|
+
const discrepancies = [];
|
|
322
|
+
const cleanExpected = normalizeForComparison(record.output ?? null);
|
|
323
|
+
const cleanActual = normalizeForComparison(actualOutput ?? null);
|
|
324
|
+
const expectedJson = JSON.stringify(cleanExpected);
|
|
325
|
+
const actualJson = JSON.stringify(cleanActual);
|
|
326
|
+
if (expectedJson !== actualJson) {
|
|
327
|
+
discrepancies.push(`Output mismatch: expected ${expectedJson}, received ${actualJson}`);
|
|
328
|
+
}
|
|
329
|
+
if (record.error && !actualError) {
|
|
330
|
+
discrepancies.push(`Expected execution to fail with error '${record.error}', but succeeded.`);
|
|
331
|
+
}
|
|
332
|
+
else if (!record.error && actualError) {
|
|
333
|
+
discrepancies.push(`Expected execution to succeed, but failed with '${actualError}'.`);
|
|
334
|
+
}
|
|
335
|
+
return {
|
|
336
|
+
matched: discrepancies.length === 0,
|
|
337
|
+
expectedOutput: record.output,
|
|
338
|
+
actualOutput,
|
|
339
|
+
discrepancies
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,53 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@siglo/testing",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "Deterministic test utilities, workflow harness, mocks, fake clock, and replay tooling for Siglo",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"require": "./dist/index.js",
|
|
12
|
+
"default": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./package.json": "./package.json"
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"README.md",
|
|
19
|
+
"LICENSE"
|
|
20
|
+
],
|
|
21
|
+
"publishConfig": {
|
|
22
|
+
"access": "public",
|
|
23
|
+
"registry": "https://registry.npmjs.org/"
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsc -p tsconfig.json",
|
|
27
|
+
"prepublishOnly": "npm run build",
|
|
28
|
+
"test": "npm run build && mocha -r tsx 'src/**/*.test.ts'"
|
|
29
|
+
},
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "git+https://github.com/jsoftgem/siglo.git",
|
|
33
|
+
"directory": "packages/testing"
|
|
34
|
+
},
|
|
35
|
+
"author": "Jerico de Guzman",
|
|
36
|
+
"license": "MIT",
|
|
37
|
+
"bugs": {
|
|
38
|
+
"url": "https://github.com/jsoftgem/siglo/issues"
|
|
39
|
+
},
|
|
40
|
+
"homepage": "https://github.com/jsoftgem/siglo#readme",
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"@siglo/core": "^1.0.0"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@types/chai": "^5.2.3",
|
|
46
|
+
"@types/mocha": "^10.0.10",
|
|
47
|
+
"@types/node": "^26.6.5",
|
|
48
|
+
"chai": "^3.5.0",
|
|
49
|
+
"mocha": "^12.0.3",
|
|
50
|
+
"tsx": "^4.23.15",
|
|
51
|
+
"typescript": "~5.7.0"
|
|
52
|
+
}
|
|
53
|
+
}
|