






















11// Canvas tests cover cli plugin behavior.
22import { Command } from "commander";
33import { describe, expect, it, vi } from "vitest";
4-import { registerNodesCanvasCommands, type CanvasCliDependencies } from "./cli.js";
4+import {
5+createDefaultCanvasCliDependencies,
6+registerNodesCanvasCommands,
7+type CanvasCliDependencies,
8+} from "./cli.js";
59610function createCanvasCliDeps() {
711const writtenFiles: Array<{ filePath: string; base64: string }> = [];
@@ -47,6 +51,26 @@ function createCanvasCliDeps() {
4751return { deps, runtime, writtenFiles };
4852}
495354+function createCanvasCliDepsWithDefaultParsers() {
55+const baseDeps = createDefaultCanvasCliDependencies();
56+const harness = createCanvasCliDeps();
57+return {
58+ ...harness,
59+deps: {
60+ ...baseDeps,
61+defaultRuntime: harness.runtime,
62+nodesCallOpts: harness.deps.nodesCallOpts,
63+runNodesCommand: harness.deps.runNodesCommand,
64+getNodesTheme: harness.deps.getNodesTheme,
65+resolveNodeId: harness.deps.resolveNodeId,
66+buildNodeInvokeParams: harness.deps.buildNodeInvokeParams,
67+callGatewayCli: harness.deps.callGatewayCli,
68+writeBase64ToFile: harness.deps.writeBase64ToFile,
69+shortenHomePath: harness.deps.shortenHomePath,
70+},
71+};
72+}
73+5074describe("canvas CLI", () => {
5175it("registers under nodes and captures a snapshot media path", async () => {
5276const program = new Command();
@@ -135,6 +159,8 @@ describe("canvas CLI", () => {
135159it.each([
136160["--max-width", "640px", "--max-width must be a positive integer."],
137161["--quality", "0.8x", "--quality must be a number."],
162+["--quality", "-0.1", "--quality must be between 0 and 1."],
163+["--quality", "5", "--quality must be between 0 and 1."],
138164])("rejects partial numeric snapshot %s values", async (flag, value, message) => {
139165const program = new Command();
140166program.exitOverride();
@@ -151,6 +177,62 @@ describe("canvas CLI", () => {
151177expect(deps.callGatewayCli).not.toHaveBeenCalled();
152178});
153179180+it.each(["0", "1"])("accepts snapshot --quality boundary value %s", async (quality) => {
181+const program = new Command();
182+program.exitOverride();
183+const nodes = program.command("nodes");
184+const { deps } = createCanvasCliDeps();
185+186+registerNodesCanvasCommands(nodes, deps);
187+188+await program.parseAsync(
189+["nodes", "canvas", "snapshot", "--node", "ios-node", "--quality", quality],
190+{
191+from: "user",
192+},
193+);
194+expect(deps.callGatewayCli).toHaveBeenCalledWith(
195+"node.invoke",
196+expect.any(Object),
197+expect.objectContaining({
198+params: expect.objectContaining({
199+quality: Number(quality),
200+}),
201+}),
202+);
203+});
204+205+it.each([
206+["snapshot"],
207+["present"],
208+["hide"],
209+["navigate", "https://example.com"],
210+["eval", "1 + 1"],
211+["a2ui", "push", "--text", "hello"],
212+["a2ui", "reset"],
213+])("rejects invalid %s invoke timeouts before invoking the node", async (...args) => {
214+const program = new Command();
215+program.exitOverride();
216+const nodes = program.command("nodes");
217+const { deps } = createCanvasCliDepsWithDefaultParsers();
218+deps.resolveNodeId = vi.fn(async () => {
219+throw new Error("resolveNodeId should not be called");
220+});
221+222+registerNodesCanvasCommands(nodes, deps);
223+224+await expect(
225+program.parseAsync(
226+["nodes", "canvas", ...args, "--node", "ios-node", "--invoke-timeout", "20ms"],
227+{
228+from: "user",
229+},
230+),
231+).rejects.toThrow("--invoke-timeout must be a positive integer.");
232+expect(deps.resolveNodeId).not.toHaveBeenCalled();
233+expect(deps.callGatewayCli).not.toHaveBeenCalled();
234+});
235+154236it.each([
155237["--x", "1x"],
156238["--y", "2px"],
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。