From 46ae2a17af4d331d3076071ed0033bfac0fbb9ef Mon Sep 17 00:00:00 2001 From: zhibisora Date: Sun, 16 Mar 2025 05:15:50 +0800 Subject: [PATCH] Fix test for cross-spawn --- package-lock.json | 24 +++++++++++++++--------- package.json | 1 + src/client/cross-spawn.test.ts | 28 +++++++++++++++++++++++----- 3 files changed, 39 insertions(+), 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index cfd8a622..73f1cbba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,17 @@ { "name": "@modelcontextprotocol/sdk", - "version": "1.5.0", + "version": "1.7.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@modelcontextprotocol/sdk", - "version": "1.5.0", + "version": "1.7.0", "license": "MIT", "dependencies": { "content-type": "^1.0.5", "cors": "^2.8.5", + "cross-spawn": "^7.0.3", "eventsource": "^3.0.2", "express": "^5.0.1", "express-rate-limit": "^7.5.0", @@ -24,6 +25,7 @@ "@jest-mock/express": "^3.0.0", "@types/content-type": "^1.1.8", "@types/cors": "^2.8.17", + "@types/cross-spawn": "^6.0.6", "@types/eslint__js": "^8.42.3", "@types/eventsource": "^1.1.15", "@types/express": "^5.0.0", @@ -1693,6 +1695,16 @@ "@types/node": "*" } }, + "node_modules/@types/cross-spawn": { + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/@types/cross-spawn/-/cross-spawn-6.0.6.tgz", + "integrity": "sha512-fXRhhUkG4H3TQk5dBhQ7m/JDdSNHKwR2BBia62lhwEIq9xGiQKLxd6LymNhn47SjXhsUEPmxi+PKw2OkW4LLjA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/eslint": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", @@ -2809,7 +2821,6 @@ "version": "7.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.5.tgz", "integrity": "sha512-ZVJrKKYunU38/76t0RMOulHOnUcbU9GbpWKAOZ0mhjr7CX6FVrH+4FrAapSOekrgFQ3f/8gwMEuIft0aKq6Hug==", - "dev": true, "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -4156,8 +4167,7 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", @@ -5359,7 +5369,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, "engines": { "node": ">=8" } @@ -5871,7 +5880,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, "dependencies": { "shebang-regex": "^3.0.0" }, @@ -5883,7 +5891,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, "engines": { "node": ">=8" } @@ -6480,7 +6487,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "dependencies": { "isexe": "^2.0.0" }, diff --git a/package.json b/package.json index 51c4e0cd..7302af05 100644 --- a/package.json +++ b/package.json @@ -62,6 +62,7 @@ "@jest-mock/express": "^3.0.0", "@types/content-type": "^1.1.8", "@types/cors": "^2.8.17", + "@types/cross-spawn": "^6.0.6", "@types/eslint__js": "^8.42.3", "@types/eventsource": "^1.1.15", "@types/express": "^5.0.0", diff --git a/src/client/cross-spawn.test.ts b/src/client/cross-spawn.test.ts index d898aeb6..ae0a4fd6 100644 --- a/src/client/cross-spawn.test.ts +++ b/src/client/cross-spawn.test.ts @@ -1,5 +1,6 @@ import { StdioClientTransport } from "./stdio.js"; import spawn from "cross-spawn"; +import { JSONRPCMessage } from "../types.js"; // mock cross-spawn jest.mock("cross-spawn"); @@ -9,8 +10,13 @@ describe("StdioClientTransport using cross-spawn", () => { beforeEach(() => { // mock cross-spawn's return value mockSpawn.mockImplementation(() => { - const mockProcess = { - on: jest.fn((event: string, callback: Function) => { + const mockProcess: { + on: jest.Mock; + stdin?: { on: jest.Mock; write: jest.Mock }; + stdout?: { on: jest.Mock }; + stderr?: null; + } = { + on: jest.fn((event: string, callback: () => void) => { if (event === "spawn") { callback(); } @@ -76,8 +82,19 @@ describe("StdioClientTransport using cross-spawn", () => { }); // get the mock process object - const mockProcess = { - on: jest.fn((event, callback) => { + const mockProcess: { + on: jest.Mock; + stdin: { + on: jest.Mock; + write: jest.Mock; + once: jest.Mock; + }; + stdout: { + on: jest.Mock; + }; + stderr: null; + } = { + on: jest.fn((event: string, callback: () => void) => { if (event === "spawn") { callback(); } @@ -98,7 +115,8 @@ describe("StdioClientTransport using cross-spawn", () => { await transport.start(); - const message = { + // 关键修复:确保 jsonrpc 是字面量 "2.0" + const message: JSONRPCMessage = { jsonrpc: "2.0", id: "test-id", method: "test-method"