From b5eb214e4e2327eb219a5741932a2b86276fa206 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Tue, 12 May 2026 04:42:36 +0100 Subject: [PATCH] test: guard launchd handoff mock calls --- src/daemon/launchd-restart-handoff.test.ts | 29 ++++++++++++++++------ 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/src/daemon/launchd-restart-handoff.test.ts b/src/daemon/launchd-restart-handoff.test.ts index ac30996875ef..45e18ea971cb 100644 --- a/src/daemon/launchd-restart-handoff.test.ts +++ b/src/daemon/launchd-restart-handoff.test.ts @@ -13,6 +13,25 @@ vi.mock("node:child_process", async () => { import { scheduleDetachedLaunchdRestartHandoff } from "./launchd-restart-handoff.js"; +type SpawnCall = [string, string[], { env: Record }]; + +function requireSpawnCall(callIndex = 0): SpawnCall { + const call = spawnMock.mock.calls.at(callIndex); + if (!call) { + throw new Error(`expected spawn call ${callIndex}`); + } + const [command, args, options] = call; + if ( + typeof command !== "string" || + !Array.isArray(args) || + !options || + typeof options !== "object" + ) { + throw new Error(`expected spawn call ${callIndex} with command, args, and options`); + } + return [command, args as string[], options as SpawnCall[2]]; +} + afterEach(() => { spawnMock.mockReset(); unrefMock.mockReset(); @@ -35,7 +54,7 @@ describe("scheduleDetachedLaunchdRestartHandoff", () => { expect(result).toEqual({ ok: true, pid: 4242 }); expect(spawnMock).toHaveBeenCalledTimes(1); - const [, args] = spawnMock.mock.calls[0] as [string, string[]]; + const [, args] = requireSpawnCall(); expect(args[0]).toBe("-c"); expect(args[2]).toBe("openclaw-launchd-restart-handoff"); expect(args[6]).toBe("9876"); @@ -64,7 +83,7 @@ describe("scheduleDetachedLaunchdRestartHandoff", () => { mode: "start-after-exit", }); - const [, args] = spawnMock.mock.calls[0] as [string, string[]]; + const [, args] = requireSpawnCall(); expect(args[7]).toBe("ai.openclaw.gateway"); expect(args[1]).toContain('if launchctl print "$service_target" >/dev/null 2>&1; then'); expect(args[1]).toContain("reason=launchd-auto-reload"); @@ -89,11 +108,7 @@ describe("scheduleDetachedLaunchdRestartHandoff", () => { mode: "kickstart", }); - const [, args, options] = spawnMock.mock.calls[0] as [ - string, - string[], - { env: Record }, - ]; + const [, args, options] = requireSpawnCall(); expect(args[1]).toContain("exec >>'/Users/test/.openclaw/logs/gateway-restart.log' 2>&1"); expect(args[1]).not.toContain("/tmp/evil-bin"); expect(args[1]).not.toContain("/tmp/evil.dylib");