import { describe, expect, it } from "vitest"; import { runCli } from "../../runner/cli"; import { USAGE } from "../../runner/args"; import type { RunOptions, RunOutcome } from "../../runner/run"; const fakeRun = (outcome: RunOutcome) => { const calls: RunOptions[] = []; return { calls, run: async (o: RunOptions) => (calls.push(o), outcome) }; }; describe("runCli", () => { it("prints the usage for --help and exits 0", async () => { const f = fakeRun({ exitCode: 0, output: "" }); expect(await runCli(["--help"], f)).toEqual({ exitCode: 0, stdout: USAGE, stderr: "" }); expect(f.calls).toEqual([]); }); it("prints a usage error on stderr and exits 2, without running anything", async () => { const f = fakeRun({ exitCode: 0, output: "" }); const r = await runCli(["run"], f); expect(r.exitCode).toBe(2); expect(r.stderr).toContain("run needs a script"); expect(r.stdout).toBe(""); expect(f.calls).toEqual([]); }); it("runs the script with the parsed options, and prints a passing report on stdout", async () => { const f = fakeRun({ exitCode: 0, output: "3 passed" }); const r = await runCli(["run", "a.aite", "--headless"], f); expect(f.calls[0]).toMatchObject({ scriptPath: "a.aite", headless: true }); expect(r).toEqual({ exitCode: 0, stdout: "3 passed", stderr: "" }); }); it("a failing test's report is still a report: stdout, exit 1", async () => { const r = await runCli(["run", "a.aite"], fakeRun({ exitCode: 1, output: "1 failed" })); expect(r).toEqual({ exitCode: 1, stdout: "1 failed", stderr: "" }); }); it.each([2, 3] as const)("exit %s means it could not run: the message goes to stderr", async (code) => { const r = await runCli(["run", "a.aite"], fakeRun({ exitCode: code, output: "cannot read a.aite" })); expect(r).toEqual({ exitCode: code, stdout: "", stderr: "cannot read a.aite" }); }); it("turns an unexpected crash into exit 3 with the message, not a stack trace", async () => { const r = await runCli(["run", "a.aite"], { run: async () => { throw new Error("kaboom"); } }); expect(r).toEqual({ exitCode: 3, stdout: "", stderr: "aite crashed: kaboom" }); }); }); describe("aite report (P4-1)", () => { it("makes the report of a results folder and prints its path", async () => { const r = await runCli(["report", "results/x"], { run: async () => ({ exitCode: 0, output: "" }), report: (d) => ({ exitCode: 0, output: `report: ${d}/report.html` }) }); expect(r).toEqual({ exitCode: 0, stdout: "report: results/x/report.html", stderr: "" }); }); it("a folder that cannot be read is exit code 2 with the reason on stderr", async () => { const r = await runCli(["report", "nope"], { run: async () => ({ exitCode: 0, output: "" }), report: () => ({ exitCode: 2, output: "cannot make a report from nope: ENOENT" }) }); expect(r.exitCode).toBe(2); expect(r.stderr).toContain("ENOENT"); expect(r.stdout).toBe(""); }); }); describe("aite verdict (P4-3)", () => { it("hands its options to the verdict server and returns what it says when it stops", async () => { let seen: unknown; const r = await runCli(["verdict", "results/x", "--by", "qian"], { run: async () => ({ exitCode: 0, output: "" }), verdict: async (o) => ((seen = o), { exitCode: 0, output: "stopped" }) }); expect(seen).toMatchObject({ dir: "results/x", by: "qian" }); expect(r).toEqual({ exitCode: 0, stdout: "stopped", stderr: "" }); }); it("a problem is exit code 2 on stderr", async () => { const r = await runCli(["verdict", "nope"], { run: async () => ({ exitCode: 0, output: "" }), verdict: async () => ({ exitCode: 2, output: "cannot read run.json" }) }); expect(r).toEqual({ exitCode: 2, stdout: "", stderr: "cannot read run.json" }); }); }); describe("aite profile open (P5-1)", () => { it("hands the options to the launcher and returns what it says when Chrome is closed", async () => { let seen: unknown; const r = await runCli(["profile", "open", "test-qian", "--headless"], { run: async () => ({ exitCode: 0, output: "" }), profile: async (o) => ((seen = o), { exitCode: 0, output: "Chrome closed." }) }); expect(seen).toMatchObject({ name: "test-qian", headless: true }); expect(r).toEqual({ exitCode: 0, stdout: "Chrome closed.", stderr: "" }); }); it("a refusal is exit code 3 on stderr", async () => { const r = await runCli(["profile", "open", "x"], { run: async () => ({ exitCode: 0, output: "" }), profile: async () => ({ exitCode: 3, output: "another aite launcher" }) }); expect(r).toEqual({ exitCode: 3, stdout: "", stderr: "another aite launcher" }); }); });