fix: Fix test fixtures JsonDataNode constructor calls

- Add 'servers' key to mock_mcp.json (MCPClient expects this structure)
- Add 'servers' wrapper to MCPClientTests.cpp test configs
- Fix JsonDataNode constructor calls in test fixtures:
  - JsonDataNode(json) -> JsonDataNode("name", json)
  - Affected: AIModuleTests, MonitoringModuleTests, StorageModuleTests,
    VoiceModuleTests, TimeSimulator

Test results:
- Module tests: 52/60 passing (87%)
- MCP Types tests: 15/15 passing (100%)
- MCP Transport/Client: Require Python server integration fixes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
StillHammer 2025-11-27 13:49:50 +08:00
parent 83d901aaab
commit 64d485729b
7 changed files with 83 additions and 69 deletions

View File

@ -1,4 +1,5 @@
{ {
"servers": {
"mock_server": { "mock_server": {
"command": "python", "command": "python",
"args": ["tests/fixtures/mock_mcp_server.py"], "args": ["tests/fixtures/mock_mcp_server.py"],
@ -14,4 +15,5 @@
"args": ["tests/fixtures/echo_server.py"], "args": ["tests/fixtures/echo_server.py"],
"enabled": true "enabled": true
} }
}
} }

View File

@ -36,11 +36,13 @@ void cleanupTestConfigFile(const std::string& path) {
TEST_CASE("TI_CLIENT_001_LoadConfigValid", "[mcp][client]") { TEST_CASE("TI_CLIENT_001_LoadConfigValid", "[mcp][client]") {
json config = { json config = {
{"servers", {
{"test_server", { {"test_server", {
{"command", "python"}, {"command", "python"},
{"args", json::array({"server.py"})}, {"args", json::array({"server.py"})},
{"enabled", true} {"enabled", true}
}} }}
}}
}; };
auto path = createTestConfigFile(config); auto path = createTestConfigFile(config);
@ -108,6 +110,7 @@ TEST_CASE("TI_CLIENT_004_ConnectAllStartsServers", "[mcp][client]") {
TEST_CASE("TI_CLIENT_005_ConnectAllSkipsDisabled", "[mcp][client]") { TEST_CASE("TI_CLIENT_005_ConnectAllSkipsDisabled", "[mcp][client]") {
json config = { json config = {
{"servers", {
{"enabled_server", { {"enabled_server", {
{"command", "python"}, {"command", "python"},
{"args", json::array({"tests/fixtures/echo_server.py"})}, {"args", json::array({"tests/fixtures/echo_server.py"})},
@ -117,6 +120,7 @@ TEST_CASE("TI_CLIENT_005_ConnectAllSkipsDisabled", "[mcp][client]") {
{"command", "nonexistent"}, {"command", "nonexistent"},
{"enabled", false} {"enabled", false}
}} }}
}}
}; };
auto path = createTestConfigFile(config); auto path = createTestConfigFile(config);
@ -137,6 +141,7 @@ TEST_CASE("TI_CLIENT_005_ConnectAllSkipsDisabled", "[mcp][client]") {
TEST_CASE("TI_CLIENT_006_ConnectSingleServer", "[mcp][client]") { TEST_CASE("TI_CLIENT_006_ConnectSingleServer", "[mcp][client]") {
json config = { json config = {
{"servers", {
{"server1", { {"server1", {
{"command", "python"}, {"command", "python"},
{"args", json::array({"tests/fixtures/echo_server.py"})}, {"args", json::array({"tests/fixtures/echo_server.py"})},
@ -147,6 +152,7 @@ TEST_CASE("TI_CLIENT_006_ConnectSingleServer", "[mcp][client]") {
{"args", json::array({"tests/fixtures/echo_server.py"})}, {"args", json::array({"tests/fixtures/echo_server.py"})},
{"enabled", true} {"enabled", true}
}} }}
}}
}; };
auto path = createTestConfigFile(config); auto path = createTestConfigFile(config);
@ -170,11 +176,13 @@ TEST_CASE("TI_CLIENT_006_ConnectSingleServer", "[mcp][client]") {
TEST_CASE("TI_CLIENT_007_DisconnectSingleServer", "[mcp][client]") { TEST_CASE("TI_CLIENT_007_DisconnectSingleServer", "[mcp][client]") {
json config = { json config = {
{"servers", {
{"server1", { {"server1", {
{"command", "python"}, {"command", "python"},
{"args", json::array({"tests/fixtures/echo_server.py"})}, {"args", json::array({"tests/fixtures/echo_server.py"})},
{"enabled", true} {"enabled", true}
}} }}
}}
}; };
auto path = createTestConfigFile(config); auto path = createTestConfigFile(config);
@ -195,6 +203,7 @@ TEST_CASE("TI_CLIENT_007_DisconnectSingleServer", "[mcp][client]") {
TEST_CASE("TI_CLIENT_008_DisconnectAllCleansUp", "[mcp][client]") { TEST_CASE("TI_CLIENT_008_DisconnectAllCleansUp", "[mcp][client]") {
json config = { json config = {
{"servers", {
{"server1", { {"server1", {
{"command", "python"}, {"command", "python"},
{"args", json::array({"tests/fixtures/echo_server.py"})}, {"args", json::array({"tests/fixtures/echo_server.py"})},
@ -205,6 +214,7 @@ TEST_CASE("TI_CLIENT_008_DisconnectAllCleansUp", "[mcp][client]") {
{"args", json::array({"tests/fixtures/echo_server.py"})}, {"args", json::array({"tests/fixtures/echo_server.py"})},
{"enabled", true} {"enabled", true}
}} }}
}}
}; };
auto path = createTestConfigFile(config); auto path = createTestConfigFile(config);
@ -354,11 +364,13 @@ TEST_CASE("TI_CLIENT_014_ToolCountAccurate", "[mcp][client]") {
TEST_CASE("TI_CLIENT_015_IsConnectedAccurate", "[mcp][client]") { TEST_CASE("TI_CLIENT_015_IsConnectedAccurate", "[mcp][client]") {
json config = { json config = {
{"servers", {
{"test_server", { {"test_server", {
{"command", "python"}, {"command", "python"},
{"args", json::array({"tests/fixtures/echo_server.py"})}, {"args", json::array({"tests/fixtures/echo_server.py"})},
{"enabled", true} {"enabled", true}
}} }}
}}
}; };
auto path = createTestConfigFile(config); auto path = createTestConfigFile(config);

View File

@ -31,12 +31,12 @@ public:
}; };
fullConfig.merge_patch(config); fullConfig.merge_patch(config);
grove::JsonDataNode configNode(fullConfig); grove::JsonDataNode configNode("config", fullConfig);
module.setConfiguration(configNode, &io, nullptr); module.setConfiguration(configNode, &io, nullptr);
} }
void process() { void process() {
grove::JsonDataNode input(time.createInput()); grove::JsonDataNode input("input", time.createInput());
module.process(input); module.process(input);
} }
}; };
@ -259,8 +259,8 @@ TEST_CASE("TI_AI_010_StateSerialization", "[ai][integration]") {
// Restore // Restore
AIModule module2; AIModule module2;
grove::JsonDataNode configNode(json::object()); grove::JsonDataNode configNode2("config", json::object());
module2.setConfiguration(configNode, &f.io, nullptr); module2.setConfiguration(configNode2, &f.io, nullptr);
module2.setState(*state); module2.setState(*state);
auto state2 = module2.getState(); auto state2 = module2.getState();

View File

@ -32,12 +32,12 @@ public:
}; };
fullConfig.merge_patch(config); fullConfig.merge_patch(config);
grove::JsonDataNode configNode(fullConfig); grove::JsonDataNode configNode("config", fullConfig);
module.setConfiguration(configNode, &io, nullptr); module.setConfiguration(configNode, &io, nullptr);
} }
void process() { void process() {
grove::JsonDataNode input(time.createInput()); grove::JsonDataNode input("input", time.createInput());
module.process(input); module.process(input);
} }
}; };
@ -275,8 +275,8 @@ TEST_CASE("TI_MONITOR_010_StateSerialization", "[monitoring][integration]") {
// Restore to new module // Restore to new module
MonitoringModule module2; MonitoringModule module2;
grove::JsonDataNode configNode(json::object()); grove::JsonDataNode configNode2("config", json::object());
module2.setConfiguration(configNode, &f.io, nullptr); module2.setConfiguration(configNode2, &f.io, nullptr);
module2.setState(*state); module2.setState(*state);
auto state2 = module2.getState(); auto state2 = module2.getState();

View File

@ -28,12 +28,12 @@ public:
json fullConfig = json::object(); json fullConfig = json::object();
fullConfig.merge_patch(config); fullConfig.merge_patch(config);
grove::JsonDataNode configNode(fullConfig); grove::JsonDataNode configNode("config", fullConfig);
module.setConfiguration(configNode, &io, nullptr); module.setConfiguration(configNode, &io, nullptr);
} }
void process() { void process() {
grove::JsonDataNode input(time.createInput()); grove::JsonDataNode input("input", time.createInput());
module.process(input); module.process(input);
} }
}; };
@ -283,8 +283,8 @@ TEST_CASE("TI_STORAGE_010_StateSerialization", "[storage][integration]") {
// Restore // Restore
StorageModule module2; StorageModule module2;
grove::JsonDataNode configNode(json::object()); grove::JsonDataNode configNode2("config", json::object());
module2.setConfiguration(configNode, &f.io, nullptr); module2.setConfiguration(configNode2, &f.io, nullptr);
module2.setState(*state); module2.setState(*state);
auto state2 = module2.getState(); auto state2 = module2.getState();

View File

@ -32,12 +32,12 @@ public:
}; };
fullConfig.merge_patch(config); fullConfig.merge_patch(config);
grove::JsonDataNode configNode(fullConfig); grove::JsonDataNode configNode("config", fullConfig);
module.setConfiguration(configNode, &io, nullptr); module.setConfiguration(configNode, &io, nullptr);
} }
void process() { void process() {
grove::JsonDataNode input(time.createInput()); grove::JsonDataNode input("input", time.createInput());
module.process(input); module.process(input);
} }
}; };
@ -248,8 +248,8 @@ TEST_CASE("TI_VOICE_010_StateSerialization", "[voice][integration]") {
// Restore // Restore
VoiceModule module2; VoiceModule module2;
grove::JsonDataNode configNode(json::object()); grove::JsonDataNode configNode2("config", json::object());
module2.setConfiguration(configNode, &f.io, nullptr); module2.setConfiguration(configNode2, &f.io, nullptr);
module2.setState(*state); module2.setState(*state);
auto state2 = module2.getState(); auto state2 = module2.getState();

View File

@ -38,7 +38,7 @@ public:
* @brief Create input as IDataNode * @brief Create input as IDataNode
*/ */
std::unique_ptr<grove::JsonDataNode> createInputNode(float deltaTime = 0.1f) { std::unique_ptr<grove::JsonDataNode> createInputNode(float deltaTime = 0.1f) {
return std::make_unique<grove::JsonDataNode>(createInput(deltaTime)); return std::make_unique<grove::JsonDataNode>("input", createInput(deltaTime));
} }
/** /**