@dudousxd/nestjs-durable-testing 0.1.0

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.
@@ -0,0 +1,10 @@
1
+ import type { RunStatus, StateStore } from '@dudousxd/nestjs-durable-core';
2
+ export declare function assertRunStatus(store: StateStore, runId: string, status: RunStatus): Promise<void>;
3
+ export declare function assertOutput(store: StateStore, runId: string, expected: unknown): Promise<void>;
4
+ /** The names of the steps that have run, in order. */
5
+ export declare function recordedSteps(store: StateStore, runId: string): Promise<string[]>;
6
+ /** Assert every named step ran (in any order). */
7
+ export declare function assertStepsRan(store: StateStore, runId: string, names: string[]): Promise<void>;
8
+ /** Assert a step ran exactly the given number of attempts (e.g. to verify retries). */
9
+ export declare function assertStepAttempts(store: StateStore, runId: string, name: string, attempts: number): Promise<void>;
10
+ //# sourceMappingURL=assertions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assertions.d.ts","sourceRoot":"","sources":["../src/assertions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAQ3E,wBAAsB,eAAe,CACnC,KAAK,EAAE,UAAU,EACjB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,SAAS,GAChB,OAAO,CAAC,IAAI,CAAC,CAKf;AAED,wBAAsB,YAAY,CAChC,KAAK,EAAE,UAAU,EACjB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,OAAO,GAChB,OAAO,CAAC,IAAI,CAAC,CAOf;AAED,sDAAsD;AACtD,wBAAsB,aAAa,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAEvF;AAED,kDAAkD;AAClD,wBAAsB,cAAc,CAClC,KAAK,EAAE,UAAU,EACjB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EAAE,GACd,OAAO,CAAC,IAAI,CAAC,CAOf;AAED,uFAAuF;AACvF,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,UAAU,EACjB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAMf"}
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.assertRunStatus = assertRunStatus;
4
+ exports.assertOutput = assertOutput;
5
+ exports.recordedSteps = recordedSteps;
6
+ exports.assertStepsRan = assertStepsRan;
7
+ exports.assertStepAttempts = assertStepAttempts;
8
+ async function requireRun(store, runId) {
9
+ const run = await store.getRun(runId);
10
+ if (!run)
11
+ throw new Error(`assertion failed: run ${runId} not found`);
12
+ return run;
13
+ }
14
+ async function assertRunStatus(store, runId, status) {
15
+ const run = await requireRun(store, runId);
16
+ if (run.status !== status) {
17
+ throw new Error(`expected run ${runId} to be "${status}", but it was "${run.status}"`);
18
+ }
19
+ }
20
+ async function assertOutput(store, runId, expected) {
21
+ const run = await requireRun(store, runId);
22
+ if (JSON.stringify(run.output) !== JSON.stringify(expected)) {
23
+ throw new Error(`expected run ${runId} output ${JSON.stringify(expected)}, got ${JSON.stringify(run.output)}`);
24
+ }
25
+ }
26
+ /** The names of the steps that have run, in order. */
27
+ async function recordedSteps(store, runId) {
28
+ return (await store.listCheckpoints(runId)).map((cp) => cp.name);
29
+ }
30
+ /** Assert every named step ran (in any order). */
31
+ async function assertStepsRan(store, runId, names) {
32
+ const ran = await recordedSteps(store, runId);
33
+ for (const name of names) {
34
+ if (!ran.includes(name)) {
35
+ throw new Error(`expected step "${name}" to have run; ran: [${ran.join(', ')}]`);
36
+ }
37
+ }
38
+ }
39
+ /** Assert a step ran exactly the given number of attempts (e.g. to verify retries). */
40
+ async function assertStepAttempts(store, runId, name, attempts) {
41
+ const cp = (await store.listCheckpoints(runId)).find((c) => c.name === name);
42
+ if (!cp)
43
+ throw new Error(`expected step "${name}" to have run, but it did not`);
44
+ if (cp.attempts !== attempts) {
45
+ throw new Error(`expected step "${name}" to take ${attempts} attempt(s), took ${cp.attempts}`);
46
+ }
47
+ }
48
+ //# sourceMappingURL=assertions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assertions.js","sourceRoot":"","sources":["../src/assertions.ts"],"names":[],"mappings":";;AAQA,0CASC;AAED,oCAWC;AAGD,sCAEC;AAGD,wCAWC;AAGD,gDAWC;AA7DD,KAAK,UAAU,UAAU,CAAC,KAAiB,EAAE,KAAa;IACxD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACtC,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,KAAK,YAAY,CAAC,CAAC;IACtE,OAAO,GAAG,CAAC;AACb,CAAC;AAEM,KAAK,UAAU,eAAe,CACnC,KAAiB,EACjB,KAAa,EACb,MAAiB;IAEjB,MAAM,GAAG,GAAG,MAAM,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAC3C,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,gBAAgB,KAAK,WAAW,MAAM,kBAAkB,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC;IACzF,CAAC;AACH,CAAC;AAEM,KAAK,UAAU,YAAY,CAChC,KAAiB,EACjB,KAAa,EACb,QAAiB;IAEjB,MAAM,GAAG,GAAG,MAAM,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAC3C,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5D,MAAM,IAAI,KAAK,CACb,gBAAgB,KAAK,WAAW,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAC9F,CAAC;IACJ,CAAC;AACH,CAAC;AAED,sDAAsD;AAC/C,KAAK,UAAU,aAAa,CAAC,KAAiB,EAAE,KAAa;IAClE,OAAO,CAAC,MAAM,KAAK,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;AACnE,CAAC;AAED,kDAAkD;AAC3C,KAAK,UAAU,cAAc,CAClC,KAAiB,EACjB,KAAa,EACb,KAAe;IAEf,MAAM,GAAG,GAAG,MAAM,aAAa,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAC9C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,kBAAkB,IAAI,wBAAwB,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACnF,CAAC;IACH,CAAC;AACH,CAAC;AAED,uFAAuF;AAChF,KAAK,UAAU,kBAAkB,CACtC,KAAiB,EACjB,KAAa,EACb,IAAY,EACZ,QAAgB;IAEhB,MAAM,EAAE,GAAG,CAAC,MAAM,KAAK,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;IAC7E,IAAI,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,kBAAkB,IAAI,+BAA+B,CAAC,CAAC;IAChF,IAAI,EAAE,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,kBAAkB,IAAI,aAAa,QAAQ,qBAAqB,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;IACjG,CAAC;AACH,CAAC"}
@@ -0,0 +1,23 @@
1
+ import { InMemoryStateStore, InMemoryTransport, type RunResult, WorkflowEngine } from '@dudousxd/nestjs-durable-core';
2
+ /** A clock you control, for testing durable sleeps without real time. */
3
+ export declare class MutableClock {
4
+ private current;
5
+ constructor(current?: number);
6
+ readonly now: () => number;
7
+ set(ms: number): void;
8
+ advance(ms: number): void;
9
+ }
10
+ export interface TestEngine {
11
+ engine: WorkflowEngine;
12
+ store: InMemoryStateStore;
13
+ transport: InMemoryTransport;
14
+ clock: MutableClock;
15
+ /** Advance the clock by `ms` and resume any durable sleeps now due. */
16
+ tick(ms: number): Promise<RunResult[]>;
17
+ }
18
+ /**
19
+ * A self-contained engine wired to in-memory store + transport and a controllable clock — run a
20
+ * whole workflow in a unit test, with no Postgres, no Redis, and no real time.
21
+ */
22
+ export declare function createTestEngine(): TestEngine;
23
+ //# sourceMappingURL=harness.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"harness.d.ts","sourceRoot":"","sources":["../src/harness.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,KAAK,SAAS,EACd,cAAc,EACf,MAAM,+BAA+B,CAAC;AAEvC,yEAAyE;AACzE,qBAAa,YAAY;IACX,OAAO,CAAC,OAAO;gBAAP,OAAO,SAAQ;IACnC,QAAQ,CAAC,GAAG,QAAO,MAAM,CAAiB;IAC1C,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAGrB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;CAG1B;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,cAAc,CAAC;IACvB,KAAK,EAAE,kBAAkB,CAAC;IAC1B,SAAS,EAAE,iBAAiB,CAAC;IAC7B,KAAK,EAAE,YAAY,CAAC;IACpB,uEAAuE;IACvE,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;CACxC;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,UAAU,CAe7C"}
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MutableClock = void 0;
4
+ exports.createTestEngine = createTestEngine;
5
+ const nestjs_durable_core_1 = require("@dudousxd/nestjs-durable-core");
6
+ /** A clock you control, for testing durable sleeps without real time. */
7
+ class MutableClock {
8
+ current;
9
+ constructor(current = 1_000) {
10
+ this.current = current;
11
+ }
12
+ now = () => this.current;
13
+ set(ms) {
14
+ this.current = ms;
15
+ }
16
+ advance(ms) {
17
+ this.current += ms;
18
+ }
19
+ }
20
+ exports.MutableClock = MutableClock;
21
+ /**
22
+ * A self-contained engine wired to in-memory store + transport and a controllable clock — run a
23
+ * whole workflow in a unit test, with no Postgres, no Redis, and no real time.
24
+ */
25
+ function createTestEngine() {
26
+ const store = new nestjs_durable_core_1.InMemoryStateStore();
27
+ const transport = new nestjs_durable_core_1.InMemoryTransport();
28
+ const clock = new MutableClock();
29
+ const engine = new nestjs_durable_core_1.WorkflowEngine({ store, transport, clock: clock.now });
30
+ return {
31
+ engine,
32
+ store,
33
+ transport,
34
+ clock,
35
+ async tick(ms) {
36
+ clock.advance(ms);
37
+ return engine.resumeDueTimers(clock.now());
38
+ },
39
+ };
40
+ }
41
+ //# sourceMappingURL=harness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"harness.js","sourceRoot":"","sources":["../src/harness.ts"],"names":[],"mappings":";;;AAgCA,4CAeC;AA/CD,uEAKuC;AAEvC,yEAAyE;AACzE,MAAa,YAAY;IACH;IAApB,YAAoB,UAAU,KAAK;QAAf,YAAO,GAAP,OAAO,CAAQ;IAAG,CAAC;IAC9B,GAAG,GAAG,GAAW,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC;IAC1C,GAAG,CAAC,EAAU;QACZ,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;IACpB,CAAC;IACD,OAAO,CAAC,EAAU;QAChB,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;IACrB,CAAC;CACF;AATD,oCASC;AAWD;;;GAGG;AACH,SAAgB,gBAAgB;IAC9B,MAAM,KAAK,GAAG,IAAI,wCAAkB,EAAE,CAAC;IACvC,MAAM,SAAS,GAAG,IAAI,uCAAiB,EAAE,CAAC;IAC1C,MAAM,KAAK,GAAG,IAAI,YAAY,EAAE,CAAC;IACjC,MAAM,MAAM,GAAG,IAAI,oCAAc,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;IAC1E,OAAO;QACL,MAAM;QACN,KAAK;QACL,SAAS;QACT,KAAK;QACL,KAAK,CAAC,IAAI,CAAC,EAAU;YACnB,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAClB,OAAO,MAAM,CAAC,eAAe,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;QAC7C,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,5 @@
1
+ export * from './assertions';
2
+ export * from './harness';
3
+ export * from './steps';
4
+ export * from './transport-conformance';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,yBAAyB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./assertions"), exports);
18
+ __exportStar(require("./harness"), exports);
19
+ __exportStar(require("./steps"), exports);
20
+ __exportStar(require("./transport-conformance"), exports);
21
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,+CAA6B;AAC7B,4CAA0B;AAC1B,0CAAwB;AACxB,0DAAwC"}
@@ -0,0 +1,5 @@
1
+ /** A step body that throws once, then returns `value` — drives a retry, or a crash-then-resume. */
2
+ export declare function failOnce<T>(value: T, error?: Error): () => Promise<T>;
3
+ /** A step body that throws the first `n` times, then returns `value`. */
4
+ export declare function failTimes<T>(n: number, value: T, error?: Error): () => Promise<T>;
5
+ //# sourceMappingURL=steps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"steps.d.ts","sourceRoot":"","sources":["../src/steps.ts"],"names":[],"mappings":"AAAA,mGAAmG;AACnG,wBAAgB,QAAQ,CAAC,CAAC,EACxB,KAAK,EAAE,CAAC,EACR,KAAK,GAAE,KAAqC,GAC3C,MAAM,OAAO,CAAC,CAAC,CAAC,CAElB;AAED,yEAAyE;AACzE,wBAAgB,SAAS,CAAC,CAAC,EACzB,CAAC,EAAE,MAAM,EACT,KAAK,EAAE,CAAC,EACR,KAAK,GAAE,KAAqC,GAC3C,MAAM,OAAO,CAAC,CAAC,CAAC,CAOlB"}
package/dist/steps.js ADDED
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.failOnce = failOnce;
4
+ exports.failTimes = failTimes;
5
+ /** A step body that throws once, then returns `value` — drives a retry, or a crash-then-resume. */
6
+ function failOnce(value, error = new Error('injected failure')) {
7
+ return failTimes(1, value, error);
8
+ }
9
+ /** A step body that throws the first `n` times, then returns `value`. */
10
+ function failTimes(n, value, error = new Error('injected failure')) {
11
+ let calls = 0;
12
+ return async () => {
13
+ calls += 1;
14
+ if (calls <= n)
15
+ throw error;
16
+ return value;
17
+ };
18
+ }
19
+ //# sourceMappingURL=steps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"steps.js","sourceRoot":"","sources":["../src/steps.ts"],"names":[],"mappings":";;AACA,4BAKC;AAGD,8BAWC;AApBD,mGAAmG;AACnG,SAAgB,QAAQ,CACtB,KAAQ,EACR,QAAe,IAAI,KAAK,CAAC,kBAAkB,CAAC;IAE5C,OAAO,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;AACpC,CAAC;AAED,yEAAyE;AACzE,SAAgB,SAAS,CACvB,CAAS,EACT,KAAQ,EACR,QAAe,IAAI,KAAK,CAAC,kBAAkB,CAAC;IAE5C,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,OAAO,KAAK,IAAI,EAAE;QAChB,KAAK,IAAI,CAAC,CAAC;QACX,IAAI,KAAK,IAAI,CAAC;YAAE,MAAM,KAAK,CAAC;QAC5B,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { type Transport } from '@dudousxd/nestjs-durable-core';
2
+ /** A transport that can register worker handlers (every shipped transport does). */
3
+ export type HandleableTransport = Transport & {
4
+ handle(name: string, fn: (input: unknown) => Promise<unknown>): void;
5
+ close?(): Promise<void>;
6
+ };
7
+ /**
8
+ * The contract every `Transport` must satisfy: a remote step dispatched through it round-trips to a
9
+ * worker and back (success), and a throwing handler surfaces as a failed run (failure). Point it at
10
+ * a freshly constructed transport (engine-side + worker `group` in one instance) to prove parity —
11
+ * useful when adding a new transport. Throws on any mismatch; closes the transport when done.
12
+ *
13
+ * `idPrefix` keeps run ids unique across invocations against real, shared infra (queues/tables).
14
+ */
15
+ export declare function assertTransportConformance(transport: HandleableTransport, idPrefix?: string): Promise<void>;
16
+ //# sourceMappingURL=transport-conformance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport-conformance.d.ts","sourceRoot":"","sources":["../src/transport-conformance.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,SAAS,EAEf,MAAM,+BAA+B,CAAC;AAGvC,oFAAoF;AACpF,MAAM,MAAM,mBAAmB,GAAG,SAAS,GAAG;IAC5C,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;IACrE,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB,CAAC;AAUF;;;;;;;GAOG;AACH,wBAAsB,0BAA0B,CAC9C,SAAS,EAAE,mBAAmB,EAC9B,QAAQ,SAAS,GAChB,OAAO,CAAC,IAAI,CAAC,CA2Bf"}
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.assertTransportConformance = assertTransportConformance;
4
+ const nestjs_durable_core_1 = require("@dudousxd/nestjs-durable-core");
5
+ const zod_1 = require("zod");
6
+ const echo = {
7
+ name: 'conformance.echo',
8
+ group: 'conformance',
9
+ input: zod_1.z.object({ n: zod_1.z.number() }),
10
+ output: zod_1.z.object({ doubled: zod_1.z.number() }),
11
+ __remote: true,
12
+ };
13
+ /**
14
+ * The contract every `Transport` must satisfy: a remote step dispatched through it round-trips to a
15
+ * worker and back (success), and a throwing handler surfaces as a failed run (failure). Point it at
16
+ * a freshly constructed transport (engine-side + worker `group` in one instance) to prove parity —
17
+ * useful when adding a new transport. Throws on any mismatch; closes the transport when done.
18
+ *
19
+ * `idPrefix` keeps run ids unique across invocations against real, shared infra (queues/tables).
20
+ */
21
+ async function assertTransportConformance(transport, idPrefix = 'conf') {
22
+ try {
23
+ // success: the worker doubles the input
24
+ transport.handle('conformance.echo', async (input) => ({
25
+ doubled: input.n * 2,
26
+ }));
27
+ const engine = new nestjs_durable_core_1.WorkflowEngine({ store: new nestjs_durable_core_1.InMemoryStateStore(), transport });
28
+ engine.register('conf-ok', '1', async (ctx) => (await ctx.call(echo, { n: 21 })).doubled);
29
+ const ok = await engine.start('conf-ok', {}, `${idPrefix}-ok`);
30
+ if (ok.status !== 'completed' || ok.output !== 42) {
31
+ throw new Error(`expected completed/42, got ${JSON.stringify(ok)}`);
32
+ }
33
+ // failure: a throwing handler fails the run
34
+ const failTransport = transport; // same instance, re-register the handler to throw
35
+ failTransport.handle('conformance.echo', async () => {
36
+ throw new Error('handler boom');
37
+ });
38
+ const failEngine = new nestjs_durable_core_1.WorkflowEngine({ store: new nestjs_durable_core_1.InMemoryStateStore(), transport });
39
+ failEngine.register('conf-fail', '1', async (ctx) => ctx.call(echo, { n: 1 }));
40
+ const failed = await failEngine.start('conf-fail', {}, `${idPrefix}-fail`);
41
+ if (failed.status !== 'failed') {
42
+ throw new Error(`expected failed, got ${JSON.stringify(failed)}`);
43
+ }
44
+ }
45
+ finally {
46
+ await transport.close?.();
47
+ }
48
+ }
49
+ //# sourceMappingURL=transport-conformance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport-conformance.js","sourceRoot":"","sources":["../src/transport-conformance.ts"],"names":[],"mappings":";;AA8BA,gEA8BC;AA5DD,uEAKuC;AACvC,6BAAwB;AAQxB,MAAM,IAAI,GAAsD;IAC9D,IAAI,EAAE,kBAAkB;IACxB,KAAK,EAAE,aAAa;IACpB,KAAK,EAAE,OAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,OAAC,CAAC,MAAM,EAAE,EAAE,CAAC;IAClC,MAAM,EAAE,OAAC,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE,EAAE,CAAC;IACzC,QAAQ,EAAE,IAAI;CACf,CAAC;AAEF;;;;;;;GAOG;AACI,KAAK,UAAU,0BAA0B,CAC9C,SAA8B,EAC9B,QAAQ,GAAG,MAAM;IAEjB,IAAI,CAAC;QACH,wCAAwC;QACxC,SAAS,CAAC,MAAM,CAAC,kBAAkB,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;YACrD,OAAO,EAAG,KAAuB,CAAC,CAAC,GAAG,CAAC;SACxC,CAAC,CAAC,CAAC;QACJ,MAAM,MAAM,GAAG,IAAI,oCAAc,CAAC,EAAE,KAAK,EAAE,IAAI,wCAAkB,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;QAClF,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QAC1F,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,SAAS,EAAE,EAAE,EAAE,GAAG,QAAQ,KAAK,CAAC,CAAC;QAC/D,IAAI,EAAE,CAAC,MAAM,KAAK,WAAW,IAAI,EAAE,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;YAClD,MAAM,IAAI,KAAK,CAAC,8BAA8B,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACtE,CAAC;QAED,4CAA4C;QAC5C,MAAM,aAAa,GAAG,SAAS,CAAC,CAAC,kDAAkD;QACnF,aAAa,CAAC,MAAM,CAAC,kBAAkB,EAAE,KAAK,IAAI,EAAE;YAClD,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC;QAClC,CAAC,CAAC,CAAC;QACH,MAAM,UAAU,GAAG,IAAI,oCAAc,CAAC,EAAE,KAAK,EAAE,IAAI,wCAAkB,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;QACtF,UAAU,CAAC,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAC/E,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,EAAE,GAAG,QAAQ,OAAO,CAAC,CAAC;QAC3E,IAAI,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,wBAAwB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;YAAS,CAAC;QACT,MAAM,SAAS,CAAC,KAAK,EAAE,EAAE,CAAC;IAC5B,CAAC;AACH,CAAC"}
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "@dudousxd/nestjs-durable-testing",
3
+ "version": "0.1.0",
4
+ "description": "Testing utilities for nestjs-durable — a test engine harness, crash/flaky-step injection, and replay assertions",
5
+ "license": "MIT",
6
+ "author": "Davide Carvalho",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/DavideCarvalho/nestjs-durable.git",
10
+ "directory": "packages/testing"
11
+ },
12
+ "type": "commonjs",
13
+ "main": "dist/index.js",
14
+ "types": "dist/index.d.ts",
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "peerDependencies": {
19
+ "@dudousxd/nestjs-durable-core": ">=0.1.0 <1.0.0"
20
+ },
21
+ "devDependencies": {
22
+ "typescript": "5.9.3",
23
+ "@dudousxd/nestjs-durable-core": "^0.1.0"
24
+ },
25
+ "scripts": {
26
+ "build": "tsc -p tsconfig.json",
27
+ "typecheck": "tsc -p tsconfig.json --noEmit"
28
+ }
29
+ }