@@ -8,10 +8,9 @@ import Testing
88@Suite ( " Roundtrip Tests " )
99struct RoundtripTests {
1010 @Test (
11- " Initialize roundtrip " ,
1211 . timeLimit( . minutes( 1 ) )
1312 )
14- func testInitializeRoundtrip ( ) async throws {
13+ func testRoundtrip ( ) async throws {
1514 let ( clientToServerRead, clientToServerWrite) = try FileDescriptor . pipe ( )
1615 let ( serverToClientRead, serverToClientWrite) = try FileDescriptor . pipe ( )
1716
@@ -36,6 +35,32 @@ struct RoundtripTests {
3635 version: " 1.0.0 " ,
3736 capabilities: . init( prompts: . init( ) , tools: . init( ) )
3837 )
38+ await server. withMethodHandler ( ListTools . self) { _ in
39+ return ListTools . Result ( tools: [
40+ Tool (
41+ name: " add " ,
42+ description: " Adds two numbers together " ,
43+ inputSchema: [
44+ " a " : [ " type " : " integer " , " description " : " The first number " ] ,
45+ " a " : [ " type " : " integer " , " description " : " The second number " ] ,
46+ ] )
47+ ] )
48+ }
49+ await server. withMethodHandler ( CallTool . self) { request in
50+ guard request. name == " add " else {
51+ return CallTool . Result ( content: [ . text( " Invalid tool name " ) ] , isError: true )
52+ }
53+
54+ guard let a = request. arguments ? [ " a " ] ? . intValue,
55+ let b = request. arguments ? [ " b " ] ? . intValue
56+ else {
57+ return CallTool . Result (
58+ content: [ . text( " Did not receive valid arguments " ) ] , isError: true )
59+ }
60+
61+ return CallTool . Result ( content: [ . text( " \( a + b) " ) ] , isError: false )
62+ }
63+
3964 let client = Client ( name: " TestClient " , version: " 1.0 " )
4065
4166 try await server. start ( transport: serverTransport)
@@ -63,6 +88,31 @@ struct RoundtripTests {
6388 group. cancelAll ( )
6489 }
6590
91+ let listToolsTask = Task {
92+ let result = try await client. listTools ( )
93+ #expect( result. count == 1 )
94+ #expect( result [ 0 ] . name == " add " )
95+ }
96+
97+ let callToolTask = Task {
98+ let result = try await client. callTool ( name: " add " , arguments: [ " a " : 1 , " b " : 2 ] )
99+ #expect( result. isError == false )
100+ #expect( result. content == [ . text( " 3 " ) ] )
101+ }
102+
103+ try await withThrowingTaskGroup ( of: Void . self) { group in
104+ group. addTask {
105+ try await Task . sleep ( for: . seconds( 1 ) )
106+ listToolsTask. cancel ( )
107+ throw CancellationError ( )
108+ }
109+ group. addTask {
110+ try await callToolTask. value
111+ }
112+ try await group. next ( )
113+ group. cancelAll ( )
114+ }
115+
66116 await server. stop ( )
67117 await client. disconnect ( )
68118 try ? clientToServerRead. close ( )
0 commit comments