diff --git a/editor/CMakeLists.txt b/editor/CMakeLists.txt index 10b1a36..b9e23f7 100644 --- a/editor/CMakeLists.txt +++ b/editor/CMakeLists.txt @@ -3010,4 +3010,13 @@ target_link_libraries(step458_test PRIVATE tree_sitter_javascript tree_sitter_typescript tree_sitter_java tree_sitter_rust tree_sitter_go) +add_executable(step459_test tests/step459_test.cpp) +target_include_directories(step459_test PRIVATE src) +target_link_libraries(step459_test PRIVATE + nlohmann_json::nlohmann_json + unofficial::tree-sitter::tree-sitter + tree_sitter_python tree_sitter_cpp tree_sitter_elisp + tree_sitter_javascript tree_sitter_typescript + tree_sitter_java tree_sitter_rust tree_sitter_go) + # Step 12: Dear ImGui shell scaffolding created (main.cpp exists but not built due to dependencies) diff --git a/editor/tests/step459_test.cpp b/editor/tests/step459_test.cpp new file mode 100644 index 0000000..a8ccaf7 --- /dev/null +++ b/editor/tests/step459_test.cpp @@ -0,0 +1,167 @@ +// Step 459: Phase 21b Integration + Sprint Summary Tests (8 tests) + +#include "TranspilationRPC.h" + +#include + +using json = nlohmann::json; + +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 {} + +void test_end_to_end_semantic_transpile_python_to_rust() { + TEST(end_to_end_semantic_transpile_python_to_rust); + json transpileParams = { + {"functionName", "sort_items"}, + {"intent", "sort list ascending"}, + {"source", "for i in range(n): ... swap(...)"}, + {"sourceLanguage", "python"}, + {"targetLanguage", "rust"} + }; + auto transpile = TranspilationRPCHandler::handleTranspile(transpileParams); + CHECK(transpile["idiomatic"].get(), "expected idiomatic transpile"); + CHECK(transpile["confidence"].get() >= 0.90f, "expected high confidence"); + + json confParams = { + {"functionName", "sort_items"}, + {"sourceCode", transpile["sourceCode"]}, + {"targetCode", transpile["targetCode"]}, + {"sourceLanguage", "python"}, + {"targetLanguage", "rust"}, + {"hasIntent", true} + }; + auto conf = TranspilationRPCHandler::handleGetConfidence(confParams); + CHECK(conf["score"].get() >= 0.90f, "expected high confidence score"); + PASS(); +} + +void test_translation_report_shows_idiomatic_choice_with_reasoning() { + TEST(translation_report_shows_idiomatic_choice_with_reasoning); + json params = { + {"sourceLanguage", "python"}, + {"targetLanguage", "rust"}, + {"functions", json::array({ + {{"name", "sort_items"}, {"intent", "sort list ascending"}, {"source", "sort loop"}} + })} + }; + auto report = TranspilationRPCHandler::handleGetTranslationReport(params); + CHECK(report["functions"].size() == 1, "expected one function report"); + auto fn = report["functions"][0]; + CHECK(fn["idiomatic"].get(), "expected idiomatic choice"); + CHECK(fn["rationale"].get().find("idiomatic") != std::string::npos, + "expected rationale mentioning idiomatic mapping"); + PASS(); +} + +void test_low_confidence_translation_auto_flagged_for_review() { + TEST(low_confidence_translation_auto_flagged_for_review); + json confParams = { + {"functionName", "mystery"}, + {"sourceCode", "custom operation"}, + {"targetCode", "TODO: translate manually"}, + {"sourceLanguage", "python"}, + {"targetLanguage", "rust"}, + {"hasIntent", false} + }; + auto conf = TranspilationRPCHandler::handleGetConfidence(confParams); + CHECK(conf["reviewRequired"].get(), "expected review-required"); + CHECK(conf["score"].get() <= 0.30f, "expected low confidence"); + PASS(); +} + +void test_equivalence_assertions_generated_and_non_empty() { + TEST(equivalence_assertions_generated_and_non_empty); + json eqParams = { + {"functionName", "find_user"}, + {"sourceCode", "find element by key"}, + {"targetCode", "items.iter().find(|x| pred(x))"}, + {"sourceLanguage", "python"}, + {"targetLanguage", "rust"} + }; + auto eq = TranspilationRPCHandler::handleVerifyEquivalence(eqParams); + CHECK(eq["assertions"].size() >= 1, "expected generated assertions"); + CHECK(eq["annotation"].get().find("@Contract(") != std::string::npos, + "expected contract annotation"); + PASS(); +} + +void test_rpc_dispatch_full_flow_methods() { + TEST(rpc_dispatch_full_flow_methods); + auto a = TranspilationRPCHandler::dispatch( + "transpile", + {{"functionName", "f"}, {"intent", "sort list ascending"}, {"source", "sort loop"}}, + 1); + auto b = TranspilationRPCHandler::dispatch( + "getConfidence", + {{"functionName", "f"}, {"sourceCode", "sort loop"}, {"targetCode", "items.sort()"}, {"hasIntent", true}}, + 2); + auto c = TranspilationRPCHandler::dispatch( + "verifyEquivalence", + {{"functionName", "f"}, {"sourceCode", "sort values"}, {"targetCode", "items.sort()"}}, + 3); + CHECK(a.contains("result"), "transpile dispatch failed"); + CHECK(b.contains("result"), "confidence dispatch failed"); + CHECK(c.contains("result"), "equivalence dispatch failed"); + PASS(); +} + +void test_mcp_tool_surface_contains_all_phase21b_tools() { + TEST(mcp_tool_surface_contains_all_phase21b_tools); + auto defs = TranspilationRPCHandler::toolDefinitions(); + CHECK(defs.size() == 4, "expected 4 phase21b tools"); + bool hasTranspile = false, hasReport = false, hasEq = false, hasConf = false; + for (const auto& d : defs) { + if (d.name == "whetstone_transpile") hasTranspile = true; + if (d.name == "whetstone_get_translation_report") hasReport = true; + if (d.name == "whetstone_verify_equivalence") hasEq = true; + if (d.name == "whetstone_get_confidence") hasConf = true; + } + CHECK(hasTranspile && hasReport && hasEq && hasConf, "missing one or more MCP tools"); + PASS(); +} + +void test_report_summary_percentages_are_consistent() { + TEST(report_summary_percentages_are_consistent); + json params = { + {"sourceLanguage", "python"}, + {"targetLanguage", "rust"}, + {"functions", json::array({ + {{"name", "sort_items"}, {"intent", "sort list ascending"}, {"source", "sort loop"}}, + {{"name", "mystery"}, {"intent", ""}, {"source", "x = a + b"}} + })} + }; + auto report = TranspilationRPCHandler::handleGetTranslationReport(params); + float idiomaticPercent = report["summary"]["idiomaticPercent"].get(); + float literalPercent = report["summary"]["literalPercent"].get(); + CHECK(idiomaticPercent > 49.0f && idiomaticPercent < 51.0f, "expected ~50% idiomatic"); + CHECK(literalPercent > 49.0f && literalPercent < 51.0f, "expected ~50% literal"); + PASS(); +} + +void test_unknown_dispatch_reports_method_error() { + TEST(unknown_dispatch_reports_method_error); + auto r = TranspilationRPCHandler::dispatch("unknown", json::object(), 9); + CHECK(r.contains("error"), "expected error on unknown method"); + CHECK(r["error"]["code"] == -32601, "expected method-not-found code"); + PASS(); +} + +int main() { + std::cout << "Step 459: Phase 21b Integration Tests\n"; + + test_end_to_end_semantic_transpile_python_to_rust(); // 1 + test_translation_report_shows_idiomatic_choice_with_reasoning(); // 2 + test_low_confidence_translation_auto_flagged_for_review(); // 3 + test_equivalence_assertions_generated_and_non_empty(); // 4 + test_rpc_dispatch_full_flow_methods(); // 5 + test_mcp_tool_surface_contains_all_phase21b_tools(); // 6 + test_report_summary_percentages_are_consistent(); // 7 + test_unknown_dispatch_reports_method_error(); // 8 + + std::cout << "\nResults: " << passed << "/" << (passed + failed) + << " passed\n"; + return failed == 0 ? 0 : 1; +} diff --git a/progress.md b/progress.md index c67d96d..6e04c58 100644 --- a/progress.md +++ b/progress.md @@ -5978,3 +5978,57 @@ handlers and MCP tool definitions. **Architecture gate check:** - `editor/src/TranspilationRPC.h` within header-size limit (`255` <= `600`) - `editor/tests/step458_test.cpp` within test-file size guidance (`193` lines) + +### Step 459: Phase 21b Integration + Sprint 21 Summary +**Status:** PASS (8/8 tests) + +Adds end-to-end integration coverage for semantic transpilation, report +generation, confidence scoring, equivalence checks, and RPC/MCP surface. + +**Files added:** +- `editor/tests/step459_test.cpp` — 8 integration tests covering: + - semantic transpile flow (Python→Rust) with confidence follow-up + - translation report rationale/summary validation + - low-confidence auto-review behavior + - equivalence assertion generation + - full JSON-RPC dispatch flow and unknown-method handling + - MCP tool surface completeness for Phase 21b tools +- `editor/CMakeLists.txt` — `step459_test` target + +**Verification run:** +- `cmake --build editor/build-native --target step459_test` — PASS +- `./editor/build-native/step459_test` — PASS (8/8) +- `./editor/build-native/step458_test` — PASS (12/12) regression coverage + +**Architecture gate check:** +- `editor/tests/step459_test.cpp` within test-file size guidance (`167` lines) +- No new production header introduced in this integration step + +**Sprint 21 totals:** +- **Steps:** 449-459 (11 steps) +- **Tests:** 124/124 passing +- **Headers created:** 9 + - `IntentTranslator.h` + - `AlgorithmEquivalence.h` + - `TypeSystemTranslator.h` + - `ConcurrencyTranslator.h` + - `MemoryModelTranslator.h` + - `BehavioralEquivalence.h` + - `TranspilationConfidence.h` + - `TranslationReport.h` + - `TranspilationRPC.h` +- **MCP tools added:** 4 + - `whetstone_transpile` + - `whetstone_get_translation_report` + - `whetstone_verify_equivalence` + - `whetstone_get_confidence` +- **Capabilities delivered:** + - intent-driven idiomatic translation selection + - algorithm pattern recognition and stdlib equivalence mapping + - cross-language type model translation with lossiness annotations + - concurrency model translation with runtime/review signals + - ownership/lifetime memory model translation with safety deltas + - behavioral equivalence assertion generation with contract grading + - deterministic confidence scoring and review gating + - per-function/project translation reporting + - RPC + MCP interfaces for transpilation pipeline operations