Initial implementation
This commit is contained in:
parent
cc603d35fe
commit
be1e9583f8
1 changed files with 4304 additions and 884 deletions
124
Tests/MCPTests/ClientTests.swift
Normal file
124
Tests/MCPTests/ClientTests.swift
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
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")
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue