murashit_codex-panel/tests/app-server/transport-windows-launch.test.ts
2026-07-01 20:51:01 +09:00

84 lines
2.6 KiB
TypeScript

import { EventEmitter } from "node:events";
import { PassThrough } from "node:stream";
import { afterEach, describe, expect, it, vi } from "vitest";
const spawnMock = vi.fn();
vi.mock("node:child_process", () => ({
spawn: spawnMock,
}));
describe("StdioAppServerTransport Windows launch", () => {
const originalPlatform = process.platform;
afterEach(() => {
Object.defineProperty(process, "platform", { value: originalPlatform });
vi.resetModules();
spawnMock.mockReset();
vi.unstubAllEnvs();
});
it("starts Windows command shims through cmd.exe", async () => {
Object.defineProperty(process, "platform", { value: "win32" });
vi.stubEnv("ComSpec", String.raw`C:\Windows\System32\cmd.exe`);
const { StdioAppServerTransport } = await import("../../src/app-server/connection/transport");
const codexCmd = String.raw`C:\Users\me\AppData\Roaming\npm\codex.cmd`;
const cwd = String.raw`C:\vault`;
spawnMock.mockReturnValue(fakeChildProcess());
new StdioAppServerTransport(codexCmd, cwd, {
onLine: vi.fn(),
onLog: vi.fn(),
onExit: vi.fn(),
onError: vi.fn(),
}).start();
expect(spawnMock).toHaveBeenCalledWith(String.raw`C:\Windows\System32\cmd.exe`, ["/d", "/s", "/c", `""${codexCmd}" app-server"`], {
cwd,
stdio: ["pipe", "pipe", "pipe"],
windowsVerbatimArguments: true,
});
});
it("kills the cmd.exe process tree when stopping Windows command shim launches", async () => {
Object.defineProperty(process, "platform", { value: "win32" });
vi.stubEnv("ComSpec", String.raw`C:\Windows\System32\cmd.exe`);
const { StdioAppServerTransport } = await import("../../src/app-server/connection/transport");
const codexCmd = String.raw`C:\Users\me\AppData\Roaming\npm\codex.cmd`;
const cmdProcess = fakeChildProcess({ pid: 4242 });
spawnMock.mockReturnValue(cmdProcess);
const transport = new StdioAppServerTransport(codexCmd, String.raw`C:\vault`, {
onLine: vi.fn(),
onLog: vi.fn(),
onExit: vi.fn(),
onError: vi.fn(),
});
transport.start();
transport.stop();
expect(cmdProcess.kill).not.toHaveBeenCalled();
expect(spawnMock).toHaveBeenLastCalledWith("taskkill", ["/pid", "4242", "/t", "/f"], {
stdio: "ignore",
windowsHide: true,
});
});
});
function fakeChildProcess(options: { pid?: number } = {}) {
const stdin = Object.assign(new EventEmitter(), {
destroyed: false,
writable: true,
write: vi.fn(),
});
return Object.assign(new EventEmitter(), {
stdout: new PassThrough(),
stderr: new PassThrough(),
stdin,
killed: false,
kill: vi.fn(),
pid: options.pid,
});
}