check / check (push) Successful in 1m27s
An error a command throws now reaches the user as one `quak: MESSAGE` line on stderr, and the CLI exits 1 once output has drained. The wrapper moved from bin/quak.ts to src/cli-run.ts so it can be tested, and bin/quak.ts awaits program.parseAsync() so async actions are awaited. Model: opus-5-5
59 lines
2.0 KiB
TypeScript
59 lines
2.0 KiB
TypeScript
/**
|
|
* 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<number>,
|
|
): Promise<{ code: number; stdout: string; stderr: string }> => {
|
|
const stdout = collector();
|
|
const stderr = collector();
|
|
const code = await new Promise<number>((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<number> => {
|
|
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",
|
|
});
|
|
});
|
|
});
|