import { EventEmitter } from "node:events"; import { beforeEach, describe, expect, it, vi } from "vitest"; vi.mock("node:child_process", () => { const spawn = vi.fn((_cmd: string, _args: string[]) => { const proc = new EventEmitter() as EventEmitter & { kill: ReturnType; }; queueMicrotask(() => { proc.emit("exit", 0); }); proc.kill = vi.fn(); return proc; }); return { spawn }; }); const { spawnRelayTmux } = await import("./relay_tmux.js"); const { spawn } = await import("node:child_process"); describe("spawnRelayTmux", () => { beforeEach(() => { vi.clearAllMocks(); }); it("kills old session, starts new one, and attaches", async () => { const session = await spawnRelayTmux("echo hi", true, true); expect(session).toBe("clawdis-relay"); const spawnMock = spawn as unknown as vi.Mock; expect(spawnMock.mock.calls.length).toBe(3); const calls = spawnMock.mock.calls as Array<[string, string[], unknown]>; expect(calls[0][0]).toBe("tmux"); // kill-session expect(calls[1][2]?.cmd ?? "").not.toBeUndefined(); // new session expect(calls[2][1][0]).toBe("attach-session"); }); it("can skip attach", async () => { await spawnRelayTmux("echo hi", false, true); const spawnMock = spawn as unknown as vi.Mock; const hasAttach = spawnMock.mock.calls.some( (c) => Array.isArray(c[1]) && (c[1] as string[]).includes("attach-session"), ); expect(hasAttach).toBe(false); }); });