Files
whetstone_DSL/editor/tests/step417_test.cpp

160 lines
6.5 KiB
C++

// Step 417: MCP Server Configuration + Discovery Tests (12 tests)
#include "MCPServerConfig.h"
#include <filesystem>
#include <fstream>
#include <iostream>
#include <string>
static int passed = 0, failed = 0;
#define TEST(name) { std::cout << " " << #name << "... "; }
#define PASS() { std::cout << "PASS\n"; ++passed; }
#define FAIL(msg) { std::cout << "FAIL: " << msg << "\n"; ++failed; }
#define CHECK(cond, msg) if (!(cond)) { FAIL(msg); return; } else {}
static std::string makeTempDir(const std::string& name) {
auto dir = std::filesystem::temp_directory_path() / ("whetstone_" + name);
std::filesystem::create_directories(dir);
return dir.string();
}
void test_resolve_binary_path_from_candidate() {
TEST(resolve_binary_path_from_candidate);
std::string path = MCPServerConfig::resolveBinaryPath({"editor/build-native/whetstone_mcp"});
CHECK(!path.empty(), "expected binary path from explicit candidate");
PASS();
}
void test_resolve_binary_path_from_defaults() {
TEST(resolve_binary_path_from_defaults);
std::string path = MCPServerConfig::resolveBinaryPath();
CHECK(!path.empty(), "expected binary path from default discovery");
PASS();
}
void test_detect_workspace_root_from_repo() {
TEST(detect_workspace_root_from_repo);
std::string root = MCPServerConfig::detectWorkspaceRoot(".");
CHECK(!root.empty(), "workspace root empty");
CHECK(std::filesystem::exists(std::filesystem::path(root) / "progress.md"),
"expected progress.md at workspace root");
PASS();
}
void test_detect_primary_language_cpp_majority() {
TEST(detect_primary_language_cpp_majority);
auto dir = std::filesystem::path(makeTempDir("lang_cpp"));
std::ofstream(dir / "a.cpp") << "int main() {}\n";
std::ofstream(dir / "b.cpp") << "int add(int a,int b){return a+b;}\n";
std::ofstream(dir / "c.py") << "print('x')\n";
std::string lang = MCPServerConfig::detectPrimaryLanguage(dir.string());
CHECK(lang == "cpp", "expected cpp primary language");
PASS();
}
void test_detect_primary_language_python_majority() {
TEST(detect_primary_language_python_majority);
auto dir = std::filesystem::path(makeTempDir("lang_py"));
std::ofstream(dir / "a.py") << "print('a')\n";
std::ofstream(dir / "b.py") << "print('b')\n";
std::ofstream(dir / "c.cpp") << "int main(){}\n";
std::string lang = MCPServerConfig::detectPrimaryLanguage(dir.string());
CHECK(lang == "python", "expected python primary language");
PASS();
}
void test_build_mcp_config_structure() {
TEST(build_mcp_config_structure);
json cfg = MCPServerConfig::buildMcpConfig("/bin/whetstone_mcp", "/repo", "cpp");
CHECK(cfg.contains("mcpServers"), "missing mcpServers");
CHECK(cfg["mcpServers"].contains("whetstone"), "missing whetstone server key");
CHECK(cfg["mcpServers"]["whetstone"]["command"] == "/bin/whetstone_mcp",
"wrong command field");
PASS();
}
void test_build_mcp_config_args_contains_workspace_language() {
TEST(build_mcp_config_args_contains_workspace_language);
json cfg = MCPServerConfig::buildMcpConfig("/bin/whetstone_mcp", "/repo", "python");
auto args = cfg["mcpServers"]["whetstone"]["args"];
std::string dumped = args.dump();
CHECK(dumped.find("--workspace") != std::string::npos, "missing workspace arg");
CHECK(dumped.find("--language") != std::string::npos, "missing language arg");
CHECK(dumped.find("python") != std::string::npos, "missing language value");
PASS();
}
void test_write_mcp_config_file() {
TEST(write_mcp_config_file);
auto dir = std::filesystem::path(makeTempDir("mcp_cfg"));
auto path = (dir / ".mcp.json").string();
json cfg = MCPServerConfig::buildMcpConfig("/bin/whetstone_mcp", "/repo", "cpp");
CHECK(MCPServerConfig::writeMcpConfigFile(path, cfg), "write config failed");
CHECK(std::filesystem::exists(path), "config file not created");
PASS();
}
void test_manifest_tool_count_at_least_68() {
TEST(manifest_tool_count_at_least_68);
MCPServer server;
json manifest = MCPServerConfig::buildServerManifest(server);
CHECK(manifest["toolCount"].get<int>() >= 68, "expected at least 68 tools");
PASS();
}
void test_manifest_required_categories_present() {
TEST(manifest_required_categories_present);
MCPServer server;
json manifest = MCPServerConfig::buildServerManifest(server);
auto cats = manifest["categories"];
CHECK(cats.contains("AST"), "missing AST category");
CHECK(cats.contains("Diagnostics"), "missing Diagnostics category");
CHECK(cats.contains("Project"), "missing Project category");
CHECK(cats.contains("FileOps"), "missing FileOps category");
PASS();
}
void test_categorize_tool_names() {
TEST(categorize_tool_names);
CHECK(MCPServerConfig::categorizeTool("whetstone_get_ast") == "AST", "ast category");
CHECK(MCPServerConfig::categorizeTool("whetstone_get_diagnostics") == "Diagnostics",
"diagnostics category");
CHECK(MCPServerConfig::categorizeTool("whetstone_workspace_list") == "Project",
"project category");
CHECK(MCPServerConfig::categorizeTool("whetstone_file_write") == "FileOps",
"fileops category");
PASS();
}
void test_discover_end_to_end() {
TEST(discover_end_to_end);
auto d = MCPServerConfig::discover(".");
CHECK(!d.workspaceRoot.empty(), "workspace missing");
CHECK(!d.binaryPath.empty(), "binary path missing");
CHECK(d.toolCount >= 68, "expected at least 68 tools in discovery");
CHECK(!d.primaryLanguage.empty(), "primary language missing");
PASS();
}
int main() {
std::cout << "Step 417: MCP Server Configuration + Discovery Tests\n";
test_resolve_binary_path_from_candidate(); // 1
test_resolve_binary_path_from_defaults(); // 2
test_detect_workspace_root_from_repo(); // 3
test_detect_primary_language_cpp_majority(); // 4
test_detect_primary_language_python_majority(); // 5
test_build_mcp_config_structure(); // 6
test_build_mcp_config_args_contains_workspace_language(); // 7
test_write_mcp_config_file(); // 8
test_manifest_tool_count_at_least_68(); // 9
test_manifest_required_categories_present(); // 10
test_categorize_tool_names(); // 11
test_discover_end_to_end(); // 12
std::cout << "\nResults: " << passed << "/" << (passed + failed)
<< " passed\n";
return failed == 0 ? 0 : 1;
}