diff --git a/src/cli/program.nodes-basic.e2e.test.ts b/src/cli/program.nodes-basic.e2e.test.ts index 7e778132c28..ae9c2439ce9 100644 --- a/src/cli/program.nodes-basic.e2e.test.ts +++ b/src/cli/program.nodes-basic.e2e.test.ts @@ -5,6 +5,23 @@ installBaseProgramMocks(); const { buildProgram } = await import("./program.js"); +function formatRuntimeLogCallArg(value: unknown): string { + if (typeof value === "string") { + return value; + } + if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") { + return String(value); + } + if (value == null) { + return ""; + } + try { + return JSON.stringify(value); + } catch { + return "[unserializable]"; + } +} + describe("cli program (nodes basics)", () => { beforeEach(() => { vi.clearAllMocks(); @@ -57,7 +74,7 @@ describe("cli program (nodes basics)", () => { await program.parseAsync(["nodes", "list", "--connected"], { from: "user" }); expect(callGateway).toHaveBeenCalledWith(expect.objectContaining({ method: "node.list" })); - const output = runtime.log.mock.calls.map((c) => String(c[0] ?? "")).join("\n"); + const output = runtime.log.mock.calls.map((c) => formatRuntimeLogCallArg(c[0])).join("\n"); expect(output).toContain("One"); expect(output).not.toContain("Two"); }); @@ -92,7 +109,7 @@ describe("cli program (nodes basics)", () => { }); expect(callGateway).toHaveBeenCalledWith(expect.objectContaining({ method: "node.pair.list" })); - const output = runtime.log.mock.calls.map((c) => String(c[0] ?? "")).join("\n"); + const output = runtime.log.mock.calls.map((c) => formatRuntimeLogCallArg(c[0])).join("\n"); expect(output).toContain("One"); expect(output).not.toContain("Two"); }); @@ -121,7 +138,7 @@ describe("cli program (nodes basics)", () => { expect.objectContaining({ method: "node.list", params: {} }), ); - const output = runtime.log.mock.calls.map((c) => String(c[0] ?? "")).join("\n"); + const output = runtime.log.mock.calls.map((c) => formatRuntimeLogCallArg(c[0])).join("\n"); expect(output).toContain("Known: 1 · Paired: 1 · Connected: 1"); expect(output).toContain("iOS Node"); expect(output).toContain("Detail"); @@ -154,7 +171,7 @@ describe("cli program (nodes basics)", () => { runtime.log.mockClear(); await program.parseAsync(["nodes", "status"], { from: "user" }); - const output = runtime.log.mock.calls.map((c) => String(c[0] ?? "")).join("\n"); + const output = runtime.log.mock.calls.map((c) => formatRuntimeLogCallArg(c[0])).join("\n"); expect(output).toContain("Known: 1 · Paired: 0 · Connected: 1"); expect(output).toContain("Peter's Tab"); expect(output).toContain("S10 Ultra"); @@ -214,7 +231,7 @@ describe("cli program (nodes basics)", () => { }), ); - const out = runtime.log.mock.calls.map((c) => String(c[0] ?? "")).join("\n"); + const out = runtime.log.mock.calls.map((c) => formatRuntimeLogCallArg(c[0])).join("\n"); expect(out).toContain("Commands"); expect(out).toContain("canvas.eval"); }); diff --git a/src/cli/program.test-mocks.ts b/src/cli/program.test-mocks.ts index efc4d3f46f8..524c6b3a88e 100644 --- a/src/cli/program.test-mocks.ts +++ b/src/cli/program.test-mocks.ts @@ -1,19 +1,25 @@ -import { vi, type Mock } from "vitest"; +import { Mock, vi } from "vitest"; -export const messageCommand: Mock = vi.fn(); -export const statusCommand: Mock = vi.fn(); -export const configureCommand: Mock = vi.fn(); -export const configureCommandWithSections: Mock = vi.fn(); -export const setupCommand: Mock = vi.fn(); -export const onboardCommand: Mock = vi.fn(); -export const callGateway: Mock = vi.fn(); -export const runChannelLogin: Mock = vi.fn(); -export const runChannelLogout: Mock = vi.fn(); -export const runTui: Mock = vi.fn(); -export const loadAndMaybeMigrateDoctorConfig: Mock = vi.fn(); -export const ensureConfigReady: Mock = vi.fn(); -export const ensurePluginRegistryLoaded: Mock = vi.fn(); -export const runtime: { log: Mock; error: Mock; exit: Mock<() => never> } = { +export const messageCommand: Mock<(...args: unknown[]) => unknown> = vi.fn(); +export const statusCommand: Mock<(...args: unknown[]) => unknown> = vi.fn(); +export const configureCommand: Mock<(...args: unknown[]) => unknown> = vi.fn(); +export const configureCommandWithSections: Mock<(...args: unknown[]) => unknown> = vi.fn(); +export const setupCommand: Mock<(...args: unknown[]) => unknown> = vi.fn(); +export const onboardCommand: Mock<(...args: unknown[]) => unknown> = vi.fn(); +export const callGateway: Mock<(...args: unknown[]) => unknown> = vi.fn(); +export const runChannelLogin: Mock<(...args: unknown[]) => unknown> = vi.fn(); +export const runChannelLogout: Mock<(...args: unknown[]) => unknown> = vi.fn(); +export const runTui: Mock<(...args: unknown[]) => unknown> = vi.fn(); + +export const loadAndMaybeMigrateDoctorConfig: Mock<(...args: unknown[]) => unknown> = vi.fn(); +export const ensureConfigReady: Mock<(...args: unknown[]) => unknown> = vi.fn(); +export const ensurePluginRegistryLoaded: Mock<(...args: unknown[]) => unknown> = vi.fn(); + +export const runtime: { + log: Mock<(...args: unknown[]) => void>; + error: Mock<(...args: unknown[]) => void>; + exit: Mock<(...args: unknown[]) => never>; +} = { log: vi.fn(), error: vi.fn(), exit: vi.fn(() => {