/** * Tests for `run` in `src/cli-run.ts`, which every CLI command goes through. */ import { PassThrough } from "node:stream"; import { describe, it, expect } from "vitest"; import { run } from "../../src/cli-run.js"; // A stream whose written text is kept in `text`; writes finish at once, so // nothing is left waiting to drain. const collector = (): { stream: PassThrough; text: () => string } => { const stream = new PassThrough(); const chunks: string[] = []; stream.on("data", (chunk: Buffer) => chunks.push(chunk.toString())); return { stream, text: () => chunks.join("") }; }; const runToExit = async ( command: Promise, ): Promise<{ code: number; stdout: string; stderr: string }> => { const stdout = collector(); const stderr = collector(); const code = await new Promise((resolve) => { void run(command, stdout.stream, stderr.stream, resolve); }); return { code, stdout: stdout.text(), stderr: stderr.text() }; }; describe("run", () => { it("exits with the code the command returns", async () => { const result = await runToExit(Promise.resolve(3)); expect(result).toEqual({ code: 3, stdout: "", stderr: "" }); }); it("prints a thrown error as one line without a stack trace and exits 1", async () => { const failing = async (): Promise => { throw new Error( "ENOTDIR: not a directory, mkdir '/dev/null/x/originals'", ); }; const result = await runToExit(failing()); expect(result.code).toBe(1); expect(result.stdout).toBe(""); expect(result.stderr).toBe( "quak: ENOTDIR: not a directory, mkdir '/dev/null/x/originals'\n", ); }); it("prints a thrown value that is not an Error", async () => { const result = await runToExit(Promise.reject("offline")); expect(result).toEqual({ code: 1, stdout: "", stderr: "quak: offline\n", }); }); });