Files
SnapOtter/packages/doc-engine/tests/helpers/fake-child.ts
T
SnapOtterandGitHub 301e6eb01a test: coverage campaign and mutation testing across five packages (#628)
Coverage 83.6 to 87.36% lines, 81.63 to 84.14% branches. Mutation testing across five packages: image-engine 85, media-engine 92, doc-engine 87, shared+enterprise 86, apps/api security and jobs slice. Runs all five lanes weekly. Fixes the silently-broken mutation CI (babel pin), a redact-pdf envelope-shape test bug, an untested enterprise license valid-signature path, and an audit test that only exercised a hand-copied reproduction. Test and config only, no product code changes beyond the babel pin and one test-only oidc export. Full suite: 16,712 pass, 0 fail.
2026-07-24 17:36:57 +08:00

54 lines
1.8 KiB
TypeScript

import { EventEmitter } from "node:events";
/**
* A stand-in for a spawned ChildProcess. stdout/stderr are EventEmitters and the
* process itself is an EventEmitter, matching how the doc-engine wrappers wire up
* `child.stdout.on("data")`, `child.stderr.on("data")`, `child.on("close")`, and
* `child.on("error")`.
*/
export interface FakeChild extends EventEmitter {
stdout: EventEmitter;
stderr: EventEmitter;
kill: (signal?: string) => boolean;
killed: boolean;
killSignals: string[];
}
export function createFakeChild(): FakeChild {
const proc = new EventEmitter() as FakeChild;
proc.stdout = new EventEmitter();
proc.stderr = new EventEmitter();
proc.killed = false;
proc.killSignals = [];
proc.kill = (signal?: string) => {
proc.killed = true;
proc.killSignals.push(signal ?? "SIGTERM");
return true;
};
return proc;
}
/**
* Emit stdout chunks then close with the given exit code on the next microtask,
* so the wrapper's Promise settles after the caller has awaited it.
*/
export function settleClose(
child: FakeChild,
opts: { stdout?: string; stderr?: string; code?: number | null; signal?: string | null } = {},
): void {
queueMicrotask(() => {
if (opts.stdout !== undefined) child.stdout.emit("data", Buffer.from(opts.stdout, "utf8"));
if (opts.stderr !== undefined) child.stderr.emit("data", Buffer.from(opts.stderr, "utf8"));
// Preserve an explicit `code: null` (signal-only exit) instead of coercing it to 0.
const code = "code" in opts ? (opts.code ?? null) : 0;
child.emit("close", code, opts.signal ?? null);
});
}
/** Emit an "error" event (spawn ENOENT style) on the next microtask. */
export function settleError(child: FakeChild, err: Error): void {
queueMicrotask(() => {
child.emit("error", err);
});
}