167 lines
4.2 KiB
TypeScript
167 lines
4.2 KiB
TypeScript
import { Command } from "commander";
|
|
import { describe, expect, it, vi } from "vitest";
|
|
|
|
const callGateway = vi.fn(
|
|
async (opts: { method?: string; params?: { command?: string } }) => {
|
|
if (opts.method === "node.list") {
|
|
return {
|
|
nodes: [
|
|
{
|
|
nodeId: "mac-1",
|
|
displayName: "Mac",
|
|
platform: "macos",
|
|
caps: ["canvas"],
|
|
connected: true,
|
|
},
|
|
],
|
|
};
|
|
}
|
|
if (opts.method === "node.invoke") {
|
|
if (opts.params?.command === "canvas.eval") {
|
|
return { payload: { result: "ok" } };
|
|
}
|
|
return { ok: true };
|
|
}
|
|
return { ok: true };
|
|
},
|
|
);
|
|
|
|
const randomIdempotencyKey = vi.fn(() => "rk_test");
|
|
|
|
const runtimeLogs: string[] = [];
|
|
const runtimeErrors: string[] = [];
|
|
const defaultRuntime = {
|
|
log: (msg: string) => runtimeLogs.push(msg),
|
|
error: (msg: string) => runtimeErrors.push(msg),
|
|
exit: (code: number) => {
|
|
throw new Error(`__exit__:${code}`);
|
|
},
|
|
};
|
|
|
|
vi.mock("../gateway/call.js", () => ({
|
|
callGateway: (opts: unknown) => callGateway(opts as { method?: string }),
|
|
randomIdempotencyKey: () => randomIdempotencyKey(),
|
|
}));
|
|
|
|
vi.mock("../runtime.js", () => ({
|
|
defaultRuntime,
|
|
}));
|
|
|
|
describe("canvas-cli coverage", () => {
|
|
it("invokes canvas.present with placement and target", async () => {
|
|
runtimeLogs.length = 0;
|
|
runtimeErrors.length = 0;
|
|
callGateway.mockClear();
|
|
randomIdempotencyKey.mockClear();
|
|
|
|
const { registerCanvasCli } = await import("./canvas-cli.js");
|
|
const program = new Command();
|
|
program.exitOverride();
|
|
registerCanvasCli(program);
|
|
|
|
await program.parseAsync(
|
|
[
|
|
"canvas",
|
|
"present",
|
|
"--node",
|
|
"mac-1",
|
|
"--target",
|
|
"https://example.com",
|
|
"--x",
|
|
"10",
|
|
"--y",
|
|
"20",
|
|
"--width",
|
|
"800",
|
|
"--height",
|
|
"600",
|
|
],
|
|
{ from: "user" },
|
|
);
|
|
|
|
const invoke = callGateway.mock.calls.find(
|
|
(call) => call[0]?.method === "node.invoke",
|
|
)?.[0];
|
|
|
|
expect(invoke).toBeTruthy();
|
|
expect(invoke?.params?.command).toBe("canvas.present");
|
|
expect(invoke?.params?.idempotencyKey).toBe("rk_test");
|
|
expect(invoke?.params?.params).toEqual({
|
|
url: "https://example.com",
|
|
placement: { x: 10, y: 20, width: 800, height: 600 },
|
|
});
|
|
});
|
|
|
|
it("prints canvas.eval result", async () => {
|
|
runtimeLogs.length = 0;
|
|
runtimeErrors.length = 0;
|
|
callGateway.mockClear();
|
|
|
|
const { registerCanvasCli } = await import("./canvas-cli.js");
|
|
const program = new Command();
|
|
program.exitOverride();
|
|
registerCanvasCli(program);
|
|
|
|
await program.parseAsync(["canvas", "eval", "1+1"], { from: "user" });
|
|
|
|
expect(runtimeErrors).toHaveLength(0);
|
|
expect(runtimeLogs.join("\n")).toContain("ok");
|
|
});
|
|
|
|
it("pushes A2UI text payload", async () => {
|
|
runtimeLogs.length = 0;
|
|
runtimeErrors.length = 0;
|
|
callGateway.mockClear();
|
|
|
|
const { registerCanvasCli } = await import("./canvas-cli.js");
|
|
const program = new Command();
|
|
program.exitOverride();
|
|
registerCanvasCli(program);
|
|
|
|
await program.parseAsync(
|
|
["canvas", "a2ui", "push", "--node", "mac-1", "--text", "Hello A2UI"],
|
|
{ from: "user" },
|
|
);
|
|
|
|
const invoke = callGateway.mock.calls.find(
|
|
(call) => call[0]?.method === "node.invoke",
|
|
)?.[0];
|
|
|
|
expect(invoke?.params?.command).toBe("canvas.a2ui.pushJSONL");
|
|
expect(invoke?.params?.params?.jsonl).toContain("Hello A2UI");
|
|
});
|
|
|
|
it("rejects invalid A2UI JSONL", async () => {
|
|
runtimeLogs.length = 0;
|
|
runtimeErrors.length = 0;
|
|
callGateway.mockClear();
|
|
|
|
vi.resetModules();
|
|
vi.doMock("node:fs/promises", () => ({
|
|
default: { readFile: vi.fn(async () => "{broken") },
|
|
}));
|
|
|
|
const { registerCanvasCli } = await import("./canvas-cli.js");
|
|
const program = new Command();
|
|
program.exitOverride();
|
|
registerCanvasCli(program);
|
|
|
|
await expect(
|
|
program.parseAsync(
|
|
[
|
|
"canvas",
|
|
"a2ui",
|
|
"push",
|
|
"--node",
|
|
"mac-1",
|
|
"--jsonl",
|
|
"/tmp/a2ui.jsonl",
|
|
],
|
|
{ from: "user" },
|
|
),
|
|
).rejects.toThrow("__exit__:1");
|
|
|
|
expect(runtimeErrors.join("\n")).toContain("Invalid A2UI JSONL");
|
|
});
|
|
});
|