Skip to content

Commit 54dc027

Browse files
committed
Parity improvements: tests, schema types, and code organization
Test expansion (~25% parity with Python fastmcp): - Client: 24 tests (api_basic.cpp, api_advanced.cpp) - Server: 20 tests (basic.cpp, patterns.cpp) - Tools: 25 tests (validation.cpp, edge_cases.cpp) - Resources: 25 tests (advanced.cpp) - Prompts: 40 tests (basic.cpp) - Schema: 108 tests (type_basic, type_constraints, type_composite, json_schema, build) New features: - Schema-to-type mapping (json_schema_type.hpp/cpp) with validation and coercion - Client typed data helpers (get_data_as, get_typed_data_as) - Regex pattern caching for schema validation - MCP handler now exposes resources/prompts endpoints Code organization: - Reorganized tests into directory structure (client/, server/, tools/, etc.) - Split large test files for maintainability - Shared test helpers (test_helpers.hpp) - SSE streaming tests enabled by default - Removed emoji characters from tests/examples Bug fixes: - Transports now properly inherit ITransport interface - HTTP transport failure handling - Unicode handling in interop tests 34 test executables, all passing.
1 parent 70f6b39 commit 54dc027

51 files changed

Lines changed: 5758 additions & 1366 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CMakeLists.txt

Lines changed: 60 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ add_library(fastmcpp_core
3131
src/client/client.cpp
3232
src/client/transports.cpp
3333
src/util/json_schema.cpp
34+
src/util/json_schema_type.cpp
3435
src/settings.cpp
3536
)
3637
target_include_directories(fastmcpp_core PUBLIC
@@ -128,15 +129,15 @@ if(FASTMCPP_BUILD_TESTS)
128129
target_link_libraries(fastmcp_json_types PRIVATE fastmcpp_core)
129130
add_test(NAME fastmcp_json_types COMMAND fastmcp_json_types)
130131

131-
add_executable(fastmcpp_resources tests/resources.cpp)
132+
add_executable(fastmcpp_resources tests/resources/basic.cpp)
132133
target_link_libraries(fastmcpp_resources PRIVATE fastmcpp_core)
133134
add_test(NAME fastmcpp_resources COMMAND fastmcpp_resources)
134135

135-
add_executable(fastmcpp_prompts tests/prompts.cpp)
136+
add_executable(fastmcpp_prompts tests/prompts/basic.cpp)
136137
target_link_libraries(fastmcpp_prompts PRIVATE fastmcpp_core)
137138
add_test(NAME fastmcpp_prompts COMMAND fastmcpp_prompts)
138139

139-
add_executable(fastmcpp_tools tests/tools.cpp)
140+
add_executable(fastmcpp_tools tests/tools/basic.cpp)
140141
target_link_libraries(fastmcpp_tools PRIVATE fastmcpp_core)
141142
add_test(NAME fastmcpp_tools COMMAND fastmcpp_tools)
142143

@@ -146,91 +147,111 @@ if(FASTMCPP_BUILD_TESTS)
146147

147148
add_test(NAME fastmcpp_cli_sum COMMAND fastmcpp client sum 2 3)
148149

149-
add_executable(fastmcpp_http_integration tests/http_integration.cpp)
150+
add_executable(fastmcpp_http_integration tests/server/http_integration.cpp)
150151
target_link_libraries(fastmcpp_http_integration PRIVATE fastmcpp_core)
151152
add_test(NAME fastmcpp_http_integration COMMAND fastmcpp_http_integration)
152-
153-
add_executable(fastmcpp_json_schema tests/json_schema.cpp)
153+
154+
add_executable(fastmcpp_json_schema tests/schema/json_schema.cpp)
154155
target_link_libraries(fastmcpp_json_schema PRIVATE fastmcpp_core)
155156
add_test(NAME fastmcpp_json_schema COMMAND fastmcpp_json_schema)
156157

157-
add_executable(fastmcpp_schema_build tests/schema_build.cpp)
158+
add_executable(fastmcpp_type_basic tests/schema/type_basic.cpp)
159+
target_link_libraries(fastmcpp_type_basic PRIVATE fastmcpp_core)
160+
add_test(NAME fastmcpp_type_basic COMMAND fastmcpp_type_basic)
161+
162+
add_executable(fastmcpp_type_constraints tests/schema/type_constraints.cpp)
163+
target_link_libraries(fastmcpp_type_constraints PRIVATE fastmcpp_core)
164+
add_test(NAME fastmcpp_type_constraints COMMAND fastmcpp_type_constraints)
165+
166+
add_executable(fastmcpp_type_composite tests/schema/type_composite.cpp)
167+
target_link_libraries(fastmcpp_type_composite PRIVATE fastmcpp_core)
168+
add_test(NAME fastmcpp_type_composite COMMAND fastmcpp_type_composite)
169+
170+
add_executable(fastmcpp_schema_build tests/schema/build.cpp)
158171
target_link_libraries(fastmcpp_schema_build PRIVATE fastmcpp_core)
159172
add_test(NAME fastmcpp_schema_build COMMAND fastmcpp_schema_build)
160173

161174
add_executable(fastmcpp_content tests/content.cpp)
162175
target_link_libraries(fastmcpp_content PRIVATE fastmcpp_core)
163176
add_test(NAME fastmcpp_content COMMAND fastmcpp_content)
164177

165-
add_executable(fastmcpp_mcp_server tests/mcp_server.cpp)
178+
add_executable(fastmcpp_mcp_server tests/mcp/server.cpp)
166179
target_link_libraries(fastmcpp_mcp_server PRIVATE fastmcpp_core)
167180
add_test(NAME fastmcpp_mcp_server COMMAND fastmcpp_mcp_server)
168181

169-
add_executable(fastmcpp_mcp_handler tests/mcp_handler.cpp)
182+
add_executable(fastmcpp_mcp_handler tests/mcp/handler.cpp)
170183
target_link_libraries(fastmcpp_mcp_handler PRIVATE fastmcpp_core)
171184
add_test(NAME fastmcpp_mcp_handler COMMAND fastmcpp_mcp_handler)
172185

173-
add_executable(fastmcpp_mcp_server_handler tests/mcp_server_handler.cpp)
186+
add_executable(fastmcpp_mcp_server_handler tests/mcp/server_handler.cpp)
174187
target_link_libraries(fastmcpp_mcp_server_handler PRIVATE fastmcpp_core)
175188
add_test(NAME fastmcpp_mcp_server_handler COMMAND fastmcpp_mcp_server_handler)
176189

177-
add_executable(fastmcpp_mcp_server_toolmanager tests/mcp_server_toolmanager.cpp)
190+
add_executable(fastmcpp_mcp_server_toolmanager tests/mcp/server_toolmanager.cpp)
178191
target_link_libraries(fastmcpp_mcp_server_toolmanager PRIVATE fastmcpp_core)
179192
add_test(NAME fastmcpp_mcp_server_toolmanager COMMAND fastmcpp_mcp_server_toolmanager)
180193

181194
add_executable(fastmcpp_settings tests/settings.cpp)
182195
target_link_libraries(fastmcpp_settings PRIVATE fastmcpp_core)
183196
add_test(NAME fastmcpp_settings COMMAND fastmcpp_settings)
184197

185-
add_executable(fastmcpp_stdio_server tests/stdio_server.cpp)
198+
add_executable(fastmcpp_stdio_server tests/transports/stdio_server.cpp)
186199
target_link_libraries(fastmcpp_stdio_server PRIVATE fastmcpp_core)
187200
add_test(NAME fastmcpp_stdio_server COMMAND fastmcpp_stdio_server)
188201

189-
add_executable(fastmcpp_sse_server tests/server_sse.cpp)
202+
add_executable(fastmcpp_sse_server tests/server/sse.cpp)
190203
target_link_libraries(fastmcpp_sse_server PRIVATE fastmcpp_core)
191204
add_test(NAME fastmcpp_sse_server COMMAND fastmcpp_sse_server)
192-
# Gate SSE server test behind streaming option; disabled by default
193-
if(NOT FASTMCPP_ENABLE_STREAMING_TESTS)
194-
set_tests_properties(fastmcpp_sse_server PROPERTIES DISABLED TRUE)
195-
endif()
196205

197206
# MCP SSE format compliance test (regression test for GitHub Issue #1)
198-
add_executable(fastmcpp_sse_mcp_format tests/server_sse_mcp_format.cpp)
207+
add_executable(fastmcpp_sse_mcp_format tests/server/sse_mcp_format.cpp)
199208
target_link_libraries(fastmcpp_sse_mcp_format PRIVATE fastmcpp_core)
200209
add_test(NAME fastmcpp_sse_mcp_format COMMAND fastmcpp_sse_mcp_format)
201-
# This test takes ~17 seconds; disabled by default
202-
if(NOT FASTMCPP_ENABLE_STREAMING_TESTS)
203-
set_tests_properties(fastmcpp_sse_mcp_format PROPERTIES DISABLED TRUE)
204-
endif()
205210

206211
# Advanced test suites (Task 3.4)
207-
add_executable(fastmcpp_tools_advanced tests/more/tools_advanced.cpp)
208-
target_link_libraries(fastmcpp_tools_advanced PRIVATE fastmcpp_core)
209-
add_test(NAME fastmcpp_tools_advanced COMMAND fastmcpp_tools_advanced)
212+
add_executable(fastmcpp_tools_validation tests/tools/validation.cpp)
213+
target_link_libraries(fastmcpp_tools_validation PRIVATE fastmcpp_core)
214+
add_test(NAME fastmcpp_tools_validation COMMAND fastmcpp_tools_validation)
210215

211-
add_executable(fastmcpp_resources_advanced tests/more/resources_advanced.cpp)
216+
add_executable(fastmcpp_tools_edge_cases tests/tools/edge_cases.cpp)
217+
target_link_libraries(fastmcpp_tools_edge_cases PRIVATE fastmcpp_core)
218+
add_test(NAME fastmcpp_tools_edge_cases COMMAND fastmcpp_tools_edge_cases)
219+
220+
add_executable(fastmcpp_resources_advanced tests/resources/advanced.cpp)
212221
target_link_libraries(fastmcpp_resources_advanced PRIVATE fastmcpp_core)
213222
add_test(NAME fastmcpp_resources_advanced COMMAND fastmcpp_resources_advanced)
214223

215-
add_executable(fastmcpp_server_lifecycle tests/server_lifecycle.cpp)
216-
target_link_libraries(fastmcpp_server_lifecycle PRIVATE fastmcpp_core)
217-
add_test(NAME fastmcpp_server_lifecycle COMMAND fastmcpp_server_lifecycle)
224+
add_executable(fastmcpp_server_basic tests/server/basic.cpp)
225+
target_link_libraries(fastmcpp_server_basic PRIVATE fastmcpp_core)
226+
add_test(NAME fastmcpp_server_basic COMMAND fastmcpp_server_basic)
227+
228+
add_executable(fastmcpp_server_patterns tests/server/patterns.cpp)
229+
target_link_libraries(fastmcpp_server_patterns PRIVATE fastmcpp_core)
230+
add_test(NAME fastmcpp_server_patterns COMMAND fastmcpp_server_patterns)
218231

219-
add_executable(fastmcpp_client_transports tests/client_transports.cpp)
232+
add_executable(fastmcpp_client_transports tests/client/transports.cpp)
220233
target_link_libraries(fastmcpp_client_transports PRIVATE fastmcpp_core)
221234
add_test(NAME fastmcpp_client_transports COMMAND fastmcpp_client_transports)
222235

223-
add_executable(fastmcpp_client_api tests/client_api.cpp)
224-
target_link_libraries(fastmcpp_client_api PRIVATE fastmcpp_core)
225-
add_test(NAME fastmcpp_client_api COMMAND fastmcpp_client_api)
236+
add_executable(fastmcpp_client_api_basic tests/client/api_basic.cpp)
237+
target_link_libraries(fastmcpp_client_api_basic PRIVATE fastmcpp_core)
238+
add_test(NAME fastmcpp_client_api_basic COMMAND fastmcpp_client_api_basic)
239+
240+
add_executable(fastmcpp_client_api_advanced tests/client/api_advanced.cpp)
241+
target_link_libraries(fastmcpp_client_api_advanced PRIVATE fastmcpp_core)
242+
add_test(NAME fastmcpp_client_api_advanced COMMAND fastmcpp_client_api_advanced)
226243

227-
add_executable(fastmcpp_server_middleware tests/server_middleware.cpp)
244+
add_executable(fastmcpp_server_middleware tests/server/middleware.cpp)
228245
target_link_libraries(fastmcpp_server_middleware PRIVATE fastmcpp_core)
229246
add_test(NAME fastmcpp_server_middleware COMMAND fastmcpp_server_middleware)
230247

231-
add_executable(fastmcpp_stdio_client tests/stdio_client.cpp)
248+
add_executable(fastmcpp_stdio_client tests/transports/stdio_client.cpp)
232249
target_link_libraries(fastmcpp_stdio_client PRIVATE fastmcpp_core)
233250
add_test(NAME fastmcpp_stdio_client COMMAND fastmcpp_stdio_client)
251+
252+
add_executable(fastmcpp_stdio_failure tests/transports/stdio_failure.cpp)
253+
target_link_libraries(fastmcpp_stdio_failure PRIVATE fastmcpp_core)
254+
add_test(NAME fastmcpp_stdio_failure COMMAND fastmcpp_stdio_failure)
234255
set_tests_properties(fastmcpp_stdio_client PROPERTIES
235256
LABELS "conformance"
236257
WORKING_DIRECTORY "$<TARGET_FILE_DIR:fastmcpp_stdio_client>"
@@ -244,21 +265,21 @@ if(FASTMCPP_BUILD_TESTS)
244265

245266
option(FASTMCPP_ENABLE_STREAMING_TESTS "Enable streaming SSE tests (experimental)" OFF)
246267
if(FASTMCPP_ENABLE_STREAMING_TESTS)
247-
add_executable(fastmcpp_streaming_sse tests/streaming_sse.cpp)
268+
add_executable(fastmcpp_streaming_sse tests/server/streaming_sse.cpp)
248269
target_link_libraries(fastmcpp_streaming_sse PRIVATE fastmcpp_core)
249270
add_test(NAME fastmcpp_streaming_sse COMMAND fastmcpp_streaming_sse)
250271
# Avoid port conflicts with other HTTP tests when running in parallel; currently unstable on some hosts
251272
set_tests_properties(fastmcpp_streaming_sse PROPERTIES RUN_SERIAL TRUE)
252273
endif()
253274

254275
if(FASTMCPP_ENABLE_WS_STREAMING_TESTS)
255-
add_executable(fastmcpp_ws_streaming tests/ws_streaming.cpp)
276+
add_executable(fastmcpp_ws_streaming tests/transports/ws_streaming.cpp)
256277
target_link_libraries(fastmcpp_ws_streaming PRIVATE fastmcpp_core)
257278
add_test(NAME fastmcpp_ws_streaming COMMAND fastmcpp_ws_streaming)
258279
# Test auto-skips if FASTMCPP_WS_URL is not set
259-
280+
260281
if(FASTMCPP_ENABLE_LOCAL_WS_TEST)
261-
add_executable(fastmcpp_ws_streaming_local tests/ws_streaming_local.cpp)
282+
add_executable(fastmcpp_ws_streaming_local tests/transports/ws_streaming_local.cpp)
262283
target_link_libraries(fastmcpp_ws_streaming_local PRIVATE fastmcpp_core)
263284
add_test(NAME fastmcpp_ws_streaming_local COMMAND fastmcpp_ws_streaming_local)
264285
set_tests_properties(fastmcpp_ws_streaming_local PROPERTIES RUN_SERIAL TRUE)

examples/server_metadata.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Example demonstrating Server Metadata Fields (v2.13.0+)
1+
// Example demonstrating Server Metadata Fields (v2.13.0+)
22
//
33
// This example shows how to configure server metadata that appears in the
44
// MCP initialize response. Metadata helps clients display server information
@@ -37,7 +37,7 @@ int main() {
3737
}
3838
};
3939

40-
std::cout << " Created 2 icons:\n";
40+
std::cout << " [OK] Created 2 icons:\n";
4141
std::cout << " - PNG icon (48x48) from URL\n";
4242
std::cout << " - SVG icon (any size) from data URI\n\n";
4343

@@ -57,7 +57,7 @@ int main() {
5757
true // strict_input_validation (optional)
5858
);
5959

60-
std::cout << " Server created with:\n";
60+
std::cout << " [OK] Server created with:\n";
6161
std::cout << " - name: " << server->name() << "\n";
6262
std::cout << " - version: " << server->version() << "\n";
6363
std::cout << " - website_url: " << *server->website_url() << "\n";
@@ -87,7 +87,7 @@ int main() {
8787
};
8888
tool_mgr.register_tool(echo);
8989

90-
std::cout << " Registered 'echo' tool\n\n";
90+
std::cout << " [OK] Registered 'echo' tool\n\n";
9191

9292
// ============================================================================
9393
// Step 4: Create MCP Handler
@@ -109,7 +109,7 @@ int main() {
109109
descriptions
110110
);
111111

112-
std::cout << " MCP handler created\n\n";
112+
std::cout << " [OK] MCP handler created\n\n";
113113

114114
// ============================================================================
115115
// Step 5: Test Initialize Request
@@ -147,7 +147,7 @@ int main() {
147147

148148
auto& server_info = init_response["result"]["serverInfo"];
149149

150-
std::cout << " serverInfo fields:\n";
150+
std::cout << "[OK] serverInfo fields:\n";
151151
std::cout << " - name: " << server_info["name"] << "\n";
152152
std::cout << " - version: " << server_info["version"] << "\n";
153153

@@ -221,11 +221,11 @@ int main() {
221221

222222
std::cout << "=== Summary ===\n\n";
223223
std::cout << "Server metadata fields (v2.13.0+):\n";
224-
std::cout << " name: Required, identifies the server\n";
225-
std::cout << " version: Required, server version string\n";
226-
std::cout << " website_url: Optional, URL for documentation/homepage\n";
227-
std::cout << " icons: Optional, list of Icon objects for UI display\n";
228-
std::cout << " strict_input_validation: Optional, controls validation behavior\n\n";
224+
std::cout << " [OK] name: Required, identifies the server\n";
225+
std::cout << " [OK] version: Required, server version string\n";
226+
std::cout << " [OK] website_url: Optional, URL for documentation/homepage\n";
227+
std::cout << " [OK] icons: Optional, list of Icon objects for UI display\n";
228+
std::cout << " [OK] strict_input_validation: Optional, controls validation behavior\n\n";
229229

230230
std::cout << "Icon structure:\n";
231231
std::cout << " - src: URL or data URI (required)\n";

examples/sse_inspector_test.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Simple SSE server for MCP Inspector testing
1+
// Simple SSE server for MCP Inspector testing
22
// Runs indefinitely until Ctrl+C
33

44
#include "fastmcpp/server/sse_server.hpp"
@@ -64,13 +64,13 @@ int main() {
6464
return 1;
6565
}
6666

67-
std::cout << " Server started successfully\n";
67+
std::cout << "[OK] Server started successfully\n";
6868
std::cout << " Host: " << sse_server.host() << "\n";
6969
std::cout << " Port: " << sse_server.port() << "\n";
7070
std::cout << " SSE endpoint: " << sse_server.sse_path() << " (GET)\n";
7171
std::cout << " Message endpoint: " << sse_server.message_path() << " (POST)\n\n";
7272

73-
std::cout << "🔗 Connect MCP Inspector with:\n";
73+
std::cout << "Connect MCP Inspector with:\n";
7474
std::cout << " npx @modelcontextprotocol/inspector http://127.0.0.1:18106/sse\n\n";
7575

7676
std::cout << "Press Ctrl+C to stop the server...\n\n";
@@ -82,7 +82,7 @@ int main() {
8282

8383
std::cout << "Stopping server...\n";
8484
sse_server.stop();
85-
std::cout << " Server stopped\n";
85+
std::cout << "[OK] Server stopped\n";
8686

8787
return 0;
8888
}

0 commit comments

Comments
 (0)