Files
kandev/apps/cli/src/process.test.ts
T

64 lines
2.3 KiB
TypeScript

import { afterAll, describe, expect, it } from "vitest";
import { __resetBrokenPipeGuard, ignoreBrokenPipe } from "./process";
function makeError(code: string, message: string): NodeJS.ErrnoException {
return Object.assign(new Error(message), { code });
}
function lastErrorListener(stream: NodeJS.WriteStream): (err: NodeJS.ErrnoException) => void {
const listeners = stream.listeners("error");
return listeners[listeners.length - 1] as (err: NodeJS.ErrnoException) => void;
}
describe("ignoreBrokenPipe", () => {
// Capture the handler we install so we can both exercise and clean it up.
let installed: ((err: NodeJS.ErrnoException) => void) | undefined;
afterAll(() => {
if (installed) {
process.stdout.removeListener("error", installed);
process.stderr.removeListener("error", installed);
}
// Reset the module guard alongside listener removal so a later
// ignoreBrokenPipe() reattaches instead of hitting a no-op with no
// listeners present (order-independent for other tests in this worker).
__resetBrokenPipeGuard();
});
it("attaches an error handler to stdout and stderr", () => {
const stdoutBefore = process.stdout.listeners("error").length;
const stderrBefore = process.stderr.listeners("error").length;
ignoreBrokenPipe();
expect(process.stdout.listeners("error").length).toBe(stdoutBefore + 1);
expect(process.stderr.listeners("error").length).toBe(stderrBefore + 1);
// stdout and stderr share the same handler reference.
installed = lastErrorListener(process.stdout);
expect(lastErrorListener(process.stderr)).toBe(installed);
});
it("swallows EPIPE errors without throwing", () => {
const handler = lastErrorListener(process.stdout);
expect(() => handler(makeError("EPIPE", "write EPIPE"))).not.toThrow();
});
it("rethrows non-EPIPE errors", () => {
const handler = lastErrorListener(process.stdout);
expect(() => handler(makeError("EACCES", "boom"))).toThrow("boom");
});
it("is idempotent across repeated calls", () => {
const stdoutCount = process.stdout.listeners("error").length;
const stderrCount = process.stderr.listeners("error").length;
ignoreBrokenPipe();
ignoreBrokenPipe();
expect(process.stdout.listeners("error").length).toBe(stdoutCount);
expect(process.stderr.listeners("error").length).toBe(stderrCount);
});
});