import { StdioClientTransport } from "./stdio.js"; import spawn from "cross-spawn"; // mock cross-spawn jest.mock("cross-spawn"); const mockSpawn = spawn as jest.MockedFunction; describe("StdioClientTransport using cross-spawn", () => { beforeEach(() => { // mock cross-spawn's return value mockSpawn.mockImplementation(() => { const mockProcess = { on: jest.fn((event: string, callback: Function) => { if (event === "spawn") { callback(); } return mockProcess; }), stdin: { on: jest.fn(), write: jest.fn().mockReturnValue(true) }, stdout: { on: jest.fn() }, stderr: null }; return mockProcess as any; }); }); afterEach(() => { jest.clearAllMocks(); }); test("should call cross-spawn correctly", async () => { const transport = new StdioClientTransport({ command: "test-command", args: ["arg1", "arg2"] }); await transport.start(); // verify spawn is called correctly expect(mockSpawn).toHaveBeenCalledWith( "test-command", ["arg1", "arg2"], expect.objectContaining({ shell: false }) ); }); test("should pass environment variables correctly", async () => { const customEnv = { TEST_VAR: "test-value" }; const transport = new StdioClientTransport({ command: "test-command", env: customEnv }); await transport.start(); // verify environment variables are passed correctly expect(mockSpawn).toHaveBeenCalledWith( "test-command", [], expect.objectContaining({ env: customEnv }) ); }); test("should send messages correctly", async () => { const transport = new StdioClientTransport({ command: "test-command" }); // get the mock process object const mockProcess = { on: jest.fn((event, callback) => { if (event === "spawn") { callback(); } return mockProcess; }), stdin: { on: jest.fn(), write: jest.fn().mockReturnValue(true), once: jest.fn() }, stdout: { on: jest.fn() }, stderr: null }; mockSpawn.mockReturnValue(mockProcess as any); await transport.start(); const message = { jsonrpc: "2.0", id: "test-id", method: "test-method" }; await transport.send(message); // verify message is sent correctly expect(mockProcess.stdin.write).toHaveBeenCalled(); }); });