






















@@ -82,6 +82,29 @@ const startWatchRun = ({
8282return { watcher, createWatcher, fakeProcess, runPromise };
8383};
848485+function requireRecord(value: unknown, label: string): Record<string, unknown> {
86+if (!value || typeof value !== "object") {
87+throw new Error(`expected ${label} to be an object`);
88+}
89+return value as Record<string, unknown>;
90+}
91+92+function requireMockCall(mock: ReturnType<typeof vi.fn>, callIndex: number): unknown[] {
93+const call = mock.mock.calls[callIndex] as unknown[] | undefined;
94+if (!call) {
95+throw new Error(`expected mock call ${callIndex}`);
96+}
97+return call;
98+}
99+100+function requireSpawnOptions(spawn: ReturnType<typeof vi.fn>, callIndex: number) {
101+return requireRecord(requireMockCall(spawn, callIndex)[2], "spawn options");
102+}
103+104+function requireSpawnEnv(spawn: ReturnType<typeof vi.fn>, callIndex: number) {
105+return requireRecord(requireSpawnOptions(spawn, callIndex).env, "spawn env");
106+}
107+85108describe("watch-node script", () => {
86109it("wires chokidar watch to run-node with watched source/config paths", async () => {
87110const { child, spawn, watcher, createWatcher, fakeProcess } = createWatchHarness();
@@ -134,30 +157,19 @@ describe("watch-node script", () => {
134157expect(watchOptions.ignored("tsconfig.json")).toBe(false);
135158136159expect(spawn).toHaveBeenCalledTimes(1);
137-expect(spawn).toHaveBeenCalledWith(
138-"/usr/local/bin/node",
139-["scripts/run-node.mjs", "gateway", "--force"],
140-expect.objectContaining({
141- cwd,
142-stdio: "inherit",
143-env: expect.objectContaining({
144-PATH: "/usr/bin",
145-OPENCLAW_WATCH_MODE: "1",
146-OPENCLAW_WATCH_SESSION: "1700000000000-4242",
147-OPENCLAW_NO_RESPAWN: "1",
148-OPENCLAW_WATCH_COMMAND: "gateway --force",
149-}),
150-}),
151-);
152-expect(spawn).toHaveBeenCalledWith(
153-"/usr/local/bin/node",
154-["scripts/run-node.mjs", "gateway", "--force"],
155-expect.objectContaining({
156-env: expect.not.objectContaining({
157-OPENCLAW_TRACE_SYNC_IO: expect.any(String),
158-}),
159-}),
160-);
160+const spawnCall = requireMockCall(spawn, 0);
161+expect(spawnCall[0]).toBe("/usr/local/bin/node");
162+expect(spawnCall[1]).toEqual(["scripts/run-node.mjs", "gateway", "--force"]);
163+const spawnOptions = requireSpawnOptions(spawn, 0);
164+expect(spawnOptions.cwd).toBe(cwd);
165+expect(spawnOptions.stdio).toBe("inherit");
166+const spawnEnv = requireSpawnEnv(spawn, 0);
167+expect(spawnEnv.PATH).toBe("/usr/bin");
168+expect(spawnEnv.OPENCLAW_WATCH_MODE).toBe("1");
169+expect(spawnEnv.OPENCLAW_WATCH_SESSION).toBe("1700000000000-4242");
170+expect(spawnEnv.OPENCLAW_NO_RESPAWN).toBe("1");
171+expect(spawnEnv.OPENCLAW_WATCH_COMMAND).toBe("gateway --force");
172+expect(spawnEnv.OPENCLAW_TRACE_SYNC_IO).toBeUndefined();
161173fakeProcess.emit("SIGINT");
162174const exitCode = await runPromise;
163175expect(exitCode).toBe(130);
@@ -179,15 +191,10 @@ describe("watch-node script", () => {
179191 spawn,
180192});
181193182-expect(spawn).toHaveBeenCalledWith(
183-"/usr/local/bin/node",
184-["scripts/run-node.mjs", "gateway", "--force"],
185-expect.objectContaining({
186-env: expect.objectContaining({
187-OPENCLAW_TRACE_SYNC_IO: "0",
188-}),
189-}),
190-);
194+const spawnCall = requireMockCall(spawn, 0);
195+expect(spawnCall[0]).toBe("/usr/local/bin/node");
196+expect(spawnCall[1]).toEqual(["scripts/run-node.mjs", "gateway", "--force"]);
197+expect(requireSpawnEnv(spawn, 0).OPENCLAW_TRACE_SYNC_IO).toBe("0");
191198192199fakeProcess.emit("SIGINT");
193200await runPromise;
@@ -315,23 +322,24 @@ describe("watch-node script", () => {
315322await new Promise((resolve) => setImmediate(resolve));
316323317324expect(spawn).toHaveBeenCalledTimes(2);
318-expect(spawn).toHaveBeenNthCalledWith(
319-2,
320-"/usr/local/bin/node",
321-["scripts/run-node.mjs", "doctor", "--fix", "--non-interactive"],
322-expect.objectContaining({ stdio: "inherit" }),
323-);
325+const doctorSpawnCall = requireMockCall(spawn, 1);
326+expect(doctorSpawnCall[0]).toBe("/usr/local/bin/node");
327+expect(doctorSpawnCall[1]).toEqual([
328+"scripts/run-node.mjs",
329+"doctor",
330+"--fix",
331+"--non-interactive",
332+]);
333+expect(requireSpawnOptions(spawn, 1).stdio).toBe("inherit");
324334325335doctor.emit("exit", 0, null);
326336await new Promise((resolve) => setImmediate(resolve));
327337328338expect(spawn).toHaveBeenCalledTimes(3);
329-expect(spawn).toHaveBeenNthCalledWith(
330-3,
331-"/usr/local/bin/node",
332-["scripts/run-node.mjs", "gateway", "--force"],
333-expect.objectContaining({ stdio: "inherit" }),
334-);
339+const restartedGatewaySpawnCall = requireMockCall(spawn, 2);
340+expect(restartedGatewaySpawnCall[0]).toBe("/usr/local/bin/node");
341+expect(restartedGatewaySpawnCall[1]).toEqual(["scripts/run-node.mjs", "gateway", "--force"]);
342+expect(requireSpawnOptions(spawn, 2).stdio).toBe("inherit");
335343336344fakeProcess.emit("SIGINT");
337345const exitCode = await runPromise;
@@ -396,16 +404,12 @@ describe("watch-node script", () => {
396404 spawn,
397405});
398406399-expect(spawn).toHaveBeenCalledWith(
400-"/usr/local/bin/node",
401-["scripts/run-node.mjs", "gateway", "--force"],
402-expect.objectContaining({
403-env: expect.objectContaining({
404-LAUNCH_JOB_LABEL: "ai.openclaw.gateway",
405-OPENCLAW_NO_RESPAWN: "1",
406-}),
407-}),
408-);
407+const spawnCall = requireMockCall(spawn, 0);
408+expect(spawnCall[0]).toBe("/usr/local/bin/node");
409+expect(spawnCall[1]).toEqual(["scripts/run-node.mjs", "gateway", "--force"]);
410+const spawnEnv = requireSpawnEnv(spawn, 0);
411+expect(spawnEnv.LAUNCH_JOB_LABEL).toBe("ai.openclaw.gateway");
412+expect(spawnEnv.OPENCLAW_NO_RESPAWN).toBe("1");
409413410414fakeProcess.emit("SIGINT");
411415const exitCode = await runPromise;
@@ -612,11 +616,10 @@ describe("watch-node script", () => {
612616613617expect(signalProcess).toHaveBeenCalledWith(2121, "SIGTERM");
614618expect(spawn).toHaveBeenCalledTimes(1);
615-expect(JSON.parse(fs.readFileSync(lockPath, "utf8"))).toMatchObject({
616-pid: 4242,
617-command: "gateway --force",
618-watchSession: "1700000000000-4242",
619-});
619+const lockRecord = requireRecord(JSON.parse(fs.readFileSync(lockPath, "utf8")), "watch lock");
620+expect(lockRecord.pid).toBe(4242);
621+expect(lockRecord.command).toBe("gateway --force");
622+expect(lockRecord.watchSession).toBe("1700000000000-4242");
620623621624fakeProcess.emit("SIGINT");
622625const exitCode = await runPromise;
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。