From 6a31d24b7250edd85788a5237851b3e9096a5ed0 Mon Sep 17 00:00:00 2001 From: Bill Date: Mon, 9 Feb 2026 15:27:02 -0700 Subject: [PATCH] Add integration test coverage policy --- ARCHITECTURE.md | 1 + editor/CMakeLists.txt | 10 +++++ editor/tests/step125_integration_test.cpp | 54 +++++++++++++++++++++++ 3 files changed, 65 insertions(+) create mode 100644 editor/tests/step125_integration_test.cpp diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 287524e..8dbbe7f 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -60,6 +60,7 @@ If a struct exceeds 50 fields, group related fields into sub-structs (e.g., `Dif - **No print-only tests:** `std::cout << "PASS"` without a preceding assertion is forbidden. - **Test pattern:** Use the standard `expect()` helper, `int passed/failed` counters, `return failed ? 1 : 0`. - **Edge cases:** At least 1 edge case test per step (empty input, null, boundary). +- **Coverage continuity:** If a test is removed or simplified, add equivalent coverage in a new unit or integration test and note the replacement in the commit/progress log. --- diff --git a/editor/CMakeLists.txt b/editor/CMakeLists.txt index 7305178..f7eedc0 100644 --- a/editor/CMakeLists.txt +++ b/editor/CMakeLists.txt @@ -706,6 +706,16 @@ add_executable(step125_test tests/step125_test.cpp) target_include_directories(step125_test PRIVATE src) target_link_libraries(step125_test PRIVATE nlohmann_json::nlohmann_json) +add_executable(step125_integration_test tests/step125_integration_test.cpp) +target_include_directories(step125_integration_test PRIVATE src) +target_link_libraries(step125_integration_test PRIVATE + imgui::imgui + nlohmann_json::nlohmann_json + unofficial::tree-sitter::tree-sitter + tree_sitter_python + tree_sitter_cpp + tree_sitter_elisp) + find_package(SDL2 CONFIG REQUIRED) find_package(OpenGL REQUIRED) find_package(glad CONFIG REQUIRED) diff --git a/editor/tests/step125_integration_test.cpp b/editor/tests/step125_integration_test.cpp new file mode 100644 index 0000000..5c9c38f --- /dev/null +++ b/editor/tests/step125_integration_test.cpp @@ -0,0 +1,54 @@ +// Step 125 Integration Test: EditorState agent mutation flow +#include "EditorUtils.h" +#include "imgui.h" +#include + +static void expect(bool cond, const std::string& name, int& passed, int& failed) { + if (cond) { + std::cout << "Test " << (passed + failed + 1) << " PASS: " << name << "\n"; + ++passed; + } else { + std::cout << "Test " << (passed + failed + 1) << " FAIL: " << name << "\n"; + ++failed; + } +} + +int main() { + int passed = 0; + int failed = 0; + + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + + EditorState state; + auto buf = std::make_unique(); + buf->path = "(untitled)"; + buf->language = "python"; + buf->bufferMode = BufferManager::BufferMode::Structured; + auto mod = std::make_unique("root", "OldName", "python"); + buf->sync.setAST(std::move(mod)); + buf->orchestrator.setAST(cloneModule(buf->sync.getAST())); + buf->orchestratorDirty = false; + state.bufferStates[buf->path] = std::move(buf); + state.activeBuffer = state.bufferStates["(untitled)"].get(); + + state.agentMutationPermissions["agent_1"] = false; + json mutReq = { + {"jsonrpc","2.0"}, + {"id",1}, + {"method","applyMutation"}, + {"params", {{"type","setProperty"}, {"nodeId","root"}, {"property","name"}, {"value","NewName"}}} + }; + json mutRes = state.processAgentRequest(mutReq, "agent_1"); + expect(mutRes.contains("error"), "mutation blocked", passed, failed); + + state.agentMutationPermissions["agent_1"] = true; + json mutRes2 = state.processAgentRequest(mutReq, "agent_1"); + expect(mutRes2.contains("result"), "mutation allowed", passed, failed); + Module* astAfter = state.activeAST(); + expect(astAfter && astAfter->name == "NewName", "mutation applied", passed, failed); + + std::cout << "\n=== Step 125 Integration Results: " << passed << " passed, " << failed << " failed ===\n"; + ImGui::DestroyContext(); + return failed == 0 ? 0 : 1; +}