import { spawn } from "node:child_process"; import { expect, test } from "vite-plus/test"; import { isNotFound } from "./errors.ts"; import { exitCode } from "./child.ts"; test("reports the exit code", async () => { expect(await exitCode(spawn("/bin/sh", ["-c", "exit 0"], { stdio: "ignore" }))).toBe(0); expect(await exitCode(spawn("/bin/sh", ["-c", "exit 3"], { stdio: "ignore" }))).toBe(3); }); test("reports a signal as 128 plus its number", async () => { const child = spawn("/bin/sh", ["-c", "kill -KILL $$"], { stdio: "ignore" }); expect(await exitCode(child)).toBe(137); }); test("resolves on exit while a grandchild still holds the output open", async () => { const child = spawn("/bin/sh", ["-c", "sleep 2 & exit 5"], { stdio: ["ignore", "pipe", "pipe"] }); const started = Date.now(); expect(await exitCode(child)).toBe(5); expect(Date.now() - started).toBeLessThan(1500); child.stdout.destroy(); child.stderr.destroy(); }); test("rejects when the command does not exist", async () => { const child = spawn("/nonexistent/command", [], { stdio: "ignore" }); const code = exitCode(child); // The rejection must stay unhandled-safe until it is awaited. await new Promise((resolve) => { setTimeout(resolve, 50); }); await expect(code).rejects.toSatisfy(isNotFound); });