swift-sdk/Tests/MCPTests/ClientTests.swift
2025-02-11 15:22:35 -08:00

124 lines
4.1 KiB
Swift

import Testing
@testable import MCP
@Suite("Client Tests")
struct ClientTests {
@Test("Client connect and disconnect")
func testClientConnectAndDisconnect() async throws {
let transport = MockTransport()
let client = Client(name: "TestClient", version: "1.0")
#expect(await transport.isConnected == false)
try await client.connect(transport: transport)
#expect(await transport.isConnected == true)
await client.disconnect()
#expect(await transport.isConnected == false)
}
@Test(
"Initialize request",
.timeLimit(.minutes(1))
)
func testClientInitialize() async throws {
let transport = MockTransport()
let client = Client(name: "TestClient", version: "1.0")
try await client.connect(transport: transport)
// Small delay to ensure message loop is started
try await Task.sleep(nanoseconds: 10_000_000) // 10ms
// Create a task for initialize that we'll cancel
let initTask = Task {
try await client.initialize()
}
// Give it a moment to send the request
try await Task.sleep(nanoseconds: 10_000_000) // 10ms
#expect(await transport.sentMessages.count == 1)
#expect(await transport.sentMessages[0].contains(Initialize.name))
#expect(await transport.sentMessages[0].contains(client.name))
#expect(await transport.sentMessages[0].contains(client.version))
// Cancel the initialize task
initTask.cancel()
// Disconnect client to clean up message loop and give time for continuation cleanup
await client.disconnect()
try await Task.sleep(nanoseconds: 50_000_000) // 50ms
}
@Test(
"Ping request",
.timeLimit(.minutes(1))
)
func testClientPing() async throws {
let transport = MockTransport()
let client = Client(name: "TestClient", version: "1.0")
try await client.connect(transport: transport)
// Small delay to ensure message loop is started
try await Task.sleep(nanoseconds: 10_000_000) // 10ms
// Create a task for the ping that we'll cancel
let pingTask = Task {
try await client.ping()
}
// Give it a moment to send the request
try await Task.sleep(nanoseconds: 10_000_000) // 10ms
#expect(await transport.sentMessages.count == 1)
#expect(await transport.sentMessages[0].contains(Ping.name))
// Cancel the ping task
pingTask.cancel()
// Disconnect client to clean up message loop and give time for continuation cleanup
await client.disconnect()
try await Task.sleep(nanoseconds: 50_000_000) // 50ms
}
@Test("Connection failure handling")
func testClientConnectionFailure() async {
let transport = MockTransport()
await transport.setFailConnect(true)
let client = Client(name: "TestClient", version: "1.0")
do {
try await client.connect(transport: transport)
#expect(Bool(false), "Expected connection to fail")
} catch let error as Error {
if case Error.transportError = error {
#expect(Bool(true))
} else {
#expect(Bool(false), "Expected transport error")
}
} catch {
#expect(Bool(false), "Expected MCP.Error")
}
}
@Test("Send failure handling")
func testClientSendFailure() async throws {
let transport = MockTransport()
await transport.setFailSend(true)
let client = Client(name: "TestClient", version: "1.0")
try await client.connect(transport: transport)
do {
try await client.ping()
#expect(Bool(false), "Expected ping to fail")
} catch let error as Error {
if case Error.transportError = error {
#expect(Bool(true))
} else {
#expect(Bool(false), "Expected transport error")
}
} catch {
#expect(Bool(false), "Expected MCP.Error")
}
}
}