diff --git a/src/shared/protocol.test.ts b/src/shared/protocol.test.ts new file mode 100644 index 0000000..9423a2a --- /dev/null +++ b/src/shared/protocol.test.ts @@ -0,0 +1,63 @@ +import { Protocol } from "./protocol.js"; +import { Transport } from "./transport.js"; +import { + McpError, + ErrorCode, + Request, + Result, + Notification, +} from "../types.js"; +import { ZodType, z } from "zod"; + +// Mock Transport class +class MockTransport implements Transport { + onclose?: () => void; + onerror?: (error: Error) => void; + onmessage?: (message: unknown) => void; + + async start(): Promise {} + async close(): Promise { + this.onclose?.(); + } + async send(_message: unknown): Promise {} +} + +describe("protocol tests", () => { + let protocol: Protocol; + let transport: MockTransport; + + beforeEach(() => { + transport = new MockTransport(); + protocol = new (class extends Protocol { + protected assertCapabilityForMethod(): void {} + protected assertNotificationCapability(): void {} + protected assertRequestHandlerCapability(): void {} + })(); + }); + + test("should throw a timeout error if the request exceeds the timeout", async () => { + await protocol.connect(transport); + const request = { method: "example", params: {} }; + try { + const mockSchema: ZodType<{ result: string }> = z.object({ + result: z.string(), + }); + await protocol.request(request, mockSchema, { + timeout: 0, + }); + } catch (error) { + expect(error).toBeInstanceOf(McpError); + if (error instanceof McpError) { + expect(error.code).toBe(ErrorCode.RequestTimeout); + } + } + }); + + test("should invoke onclose when the connection is closed", async () => { + const oncloseMock = jest.fn(); + protocol.onclose = oncloseMock; + await protocol.connect(transport); + await transport.close(); + expect(oncloseMock).toHaveBeenCalled(); + }); +}); diff --git a/src/types.ts b/src/types.ts index 44a44d8..59b055a 100644 --- a/src/types.ts +++ b/src/types.ts @@ -100,13 +100,13 @@ export const JSONRPCResponseSchema = z .strict(); /** - * An incomplete set of error codes that may appear in JSON-RPC responses. + * Error codes defined by the JSON-RPC specification. */ export enum ErrorCode { // SDK error codes - ConnectionClosed = -1, - RequestTimeout = -2, - + ConnectionClosed = -32000, + RequestTimeout = -32001, + // Standard JSON-RPC error codes ParseError = -32700, InvalidRequest = -32600, @@ -1237,4 +1237,4 @@ export type ClientResult = z.infer; /* Server messages */ export type ServerRequest = z.infer; export type ServerNotification = z.infer; -export type ServerResult = z.infer; +export type ServerResult = z.infer; \ No newline at end of file