import pytest from pathlib import Path import os import sys # Add project root to sys.path sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) from src.mcp_client import ts_cpp_get_skeleton, ts_cpp_get_code_outline, ts_cpp_get_definition, ts_cpp_update_definition def test_ts_cpp_get_skeleton(tmp_path): cpp_code = """#include #include template class Box { public: Box(T val) : value(val) {} T getValue() { return value; } private: T value; }; void globalFunc() { std::cout << "Global" << std::endl; } """ cpp_file = tmp_path / "test.cpp" cpp_file.write_text(cpp_code) from src import mcp_client original_resolve = mcp_client._resolve_and_check mcp_client._resolve_and_check = lambda path: (Path(path), None) try: skeleton = ts_cpp_get_skeleton(str(cpp_file)) assert "class Box" in skeleton assert "Box(T val) ..." in skeleton assert "T getValue() ..." in skeleton assert "void globalFunc() ..." in skeleton assert "std::cout" not in skeleton finally: mcp_client._resolve_and_check = original_resolve def test_ts_cpp_get_code_outline(tmp_path): cpp_code = """ class MyClass { void method1() { } }; template void templateFunc(T t) { } """ cpp_file = tmp_path / "test.cpp" cpp_file.write_text(cpp_code) from src import mcp_client original_resolve = mcp_client._resolve_and_check mcp_client._resolve_and_check = lambda path: (Path(path), None) try: outline = ts_cpp_get_code_outline(str(cpp_file)) assert "[Class] MyClass (Lines 2-5)" in outline assert "[Method] method1 (Lines 3-4)" in outline assert "[Func] templateFunc (Lines 8-9)" in outline finally: mcp_client._resolve_and_check = original_resolve def test_exhaustive_gencpp_corpus(): base_dir = Path(__file__).parent / "assets" / "gencpp_samples" files_to_test = { "base_component.h": [ "BaseComponent", "BaseComponent::Config", "BaseComponent::Config::Metadata" ], "complex_template.h": [ "MultiBuffer", "MultiBuffer::SetData", "MultiBuffer::Get", "TypeTraits", "Container::Wrapper" ], "component_registry.h": [ "ComponentRegistry", "ComponentRegistry::Iterator", "ComponentRegistry::Iterator::GetType", "ComponentRegistry::Instance" ], "component_registry.cpp": [ "ComponentRegistry::Instance", "ComponentRegistry::Register", "ComponentRegistry::Create" ] } from src import mcp_client original_resolve = mcp_client._resolve_and_check mcp_client._resolve_and_check = lambda path: (Path(path), None) try: for filename, symbols in files_to_test.items(): path = base_dir / filename assert path.exists(), f"{path} does not exist" # 1. Verify skeleton executes without errors skeleton = ts_cpp_get_skeleton(str(path)) assert skeleton and "ERROR" not in skeleton # 2. Verify code outline executes without errors outline = ts_cpp_get_code_outline(str(path)) assert outline and "ERROR" not in outline # 3. Verify specific complex symbols can be retrieved via ts_cpp_get_definition for symbol in symbols: definition = ts_cpp_get_definition(str(path), symbol) assert definition and "ERROR" not in definition, f"Failed to get definition for {symbol} in {filename}: {definition}" # Basic check that the symbol name is in the definition (allowing for namespaces) simple_name = symbol.split("::")[-1] assert simple_name in definition finally: mcp_client._resolve_and_check = original_resolve def test_ts_cpp_update_definition(tmp_path): asset_path = Path(__file__).parent / "assets" / "gencpp_samples" / "component_registry.cpp" cpp_content = asset_path.read_text(encoding="utf-8") cpp_file = tmp_path / "component_registry.cpp" cpp_file.write_text(cpp_content, encoding="utf-8") from src import mcp_client original_resolve = mcp_client._resolve_and_check mcp_client._resolve_and_check = lambda path: (Path(path), None) try: new_register_body = """void ComponentRegistry::Register(const std::string& type, ComponentCreator creator) { // Updated body std::cout << "DEBUG: Registering " << type << std::endl; m_creators[type] = creator; if (type == "secret") { std::cout << "Special component" << std::endl; } }""" result = ts_cpp_update_definition(str(cpp_file), "ComponentRegistry::Register", new_register_body) assert "Successfully updated" in result updated_content = cpp_file.read_text(encoding="utf-8") assert "// Updated body" in updated_content assert "DEBUG: Registering" in updated_content # Verify it still parses by getting definition again definition = ts_cpp_get_definition(str(cpp_file), "ComponentRegistry::Register") assert "// Updated body" in definition assert "DEBUG: Registering" in definition finally: mcp_client._resolve_and_check = original_resolve