Files
stack/packages/queue/tests/dispatch.test.mjs
T
jason.woltjeandClaude Opus 5.5 6ca116b7ba feat(queue): queue as data A2, migration, render and dispatch (#1508)
Filbert approved round 1 (f167b85e). Manifest 782bcb62, 21 files, plus
the QUEUE.md markers and the TOOLS.md section. Lead decision 35.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-26 20:14:09 -05:00

101 lines
4.4 KiB
JavaScript

// `scripts/mosaic queue` (A2). The dispatch must leave every other call to
// scripts/mosaic exactly as it was: the seat CLI sees the same argv, working
// directory, environment and stdin under the new script as under the pre-A2
// copy in fixtures/mosaic-pre-a2.sh. Both CLIs are fakes that record what
// they got; nothing here runs a seat or touches a queue.
import assert from "node:assert/strict";
import { spawnSync } from "node:child_process";
import { cpSync, existsSync, mkdirSync, mkdtempSync, readFileSync, realpathSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { test } from "node:test";
import { SCRIPTS } from "./helpers.mjs";
const HERE = new URL(".", import.meta.url).pathname;
const FAKE = `import { readFileSync, writeFileSync } from "node:fs";
writeFileSync(process.env.CAPTURE, JSON.stringify({
cli: process.argv[1].slice(process.env.ROOT.length), argv: process.argv.slice(2), cwd: process.cwd(),
env: process.env, stdin: readFileSync(0, "utf8"),
}));
process.stdout.write("fake out\\n");
process.stderr.write("fake err\\n");
process.exitCode = Number(process.env.EXIT);
`;
// A root holding `script` as scripts/mosaic and both fake CLIs.
function root(t, script) {
const r = realpathSync(mkdtempSync(join(tmpdir(), "mosaic-queue-dispatch-")));
t.after(() => rmSync(r, { recursive: true, force: true }));
mkdirSync(join(r, "scripts"));
cpSync(script, join(r, "scripts/mosaic"));
for (const pkg of ["seat", "queue"]) {
mkdirSync(join(r, `packages/${pkg}/src`), { recursive: true });
writeFileSync(join(r, `packages/${pkg}/src/cli.mjs`), FAKE);
}
mkdirSync(join(r, "work"));
return r;
}
// Runs scripts/mosaic from `work` and returns everything the fake saw, with
// the root replaced so two roots compare.
function call(r, args, exit = 7) {
const capture = join(r, "capture.json");
rmSync(capture, { force: true });
const env = { PATH: process.env.PATH, HOME: r, LANG: "C", ROOT: r, CAPTURE: capture, EXIT: String(exit), MOSAIC_AGENT_NAME: "darkwing", SPACED: "a b" };
const p = spawnSync("bash", [join(r, "scripts/mosaic"), ...args], { cwd: join(r, "work"), env, input: "stdin line\nsecond\n", encoding: "utf8" });
if (p.error) throw p.error;
const got = existsSync(capture) ? readFileSync(capture, "utf8") : null;
return { status: p.status, out: p.stdout, err: p.stderr, capture: got === null ? null : got.replaceAll(r, "<ROOT>") };
}
const SEAT_CALLS = [
["launch", "--repo", "/srv/repo", "--harness", "pi", "darkwing"],
["seat", "task", "darkwing", "text with two spaces", ""],
[],
[""],
["launch", "queue"],
["Queue", "list"],
["queue-x"],
["--", "queue"],
["--help"],
];
test("every call but `queue` reaches the seat CLI exactly as before A2", (t) => {
const before = root(t, join(HERE, "fixtures", "mosaic-pre-a2.sh"));
const after = root(t, join(SCRIPTS, "mosaic"));
for (const args of SEAT_CALLS) {
const a = call(before, args);
const b = call(after, args);
assert.notEqual(a.capture, null, `${JSON.stringify(args)}: the pre-A2 script reached no CLI`);
assert.equal(JSON.parse(a.capture).cli, "/packages/seat/src/cli.mjs");
assert.deepEqual(b, a, JSON.stringify(args));
}
});
test("`queue` reaches the queue CLI with the rest of the arguments", (t) => {
const r = root(t, join(SCRIPTS, "mosaic"));
for (const rest of [["list"], [], ["note", "9", "text with spaces", "--op", "note-9-000001"], ["queue"], [""]]) {
const got = call(r, ["queue", ...rest]);
assert.deepEqual([got.status, got.out, got.err], [7, "fake out\n", "fake err\n"]);
const c = JSON.parse(got.capture);
assert.deepEqual([c.cli, c.argv, c.cwd, c.stdin], ["/packages/queue/src/cli.mjs", rest, "<ROOT>/work", "stdin line\nsecond\n"]);
}
// A queue CLI that succeeds must not fall through to the seat CLI.
const ok = call(r, ["queue", "list"], 0);
assert.deepEqual([ok.status, ok.out, JSON.parse(ok.capture).cli], [0, "fake out\n", "/packages/queue/src/cli.mjs"]);
});
test("the pre-A2 fixture is the script A2 changed", () => {
const fixture = readFileSync(join(HERE, "fixtures", "mosaic-pre-a2.sh"), "utf8");
const now = readFileSync(join(SCRIPTS, "mosaic"), "utf8");
// A2 adds lines and removes none.
const lines = now.split("\n");
let i = 0;
for (const l of fixture.split("\n")) {
while (i < lines.length && lines[i] !== l) i++;
assert.ok(i < lines.length, `pre-A2 line missing: ${l}`);
i++;
}
});