// Step 313: New Languages Integration + MCP Tests (8 tests) // Full integration of Kotlin + C# across the pipeline: // Pipeline.run(), cross-language projection, all 10 generators, // memory inference, final language count. #include "Pipeline.h" #include "ast/KotlinParser.h" #include "ast/CSharpParser.h" #include "ast/KotlinGenerator.h" #include "ast/CSharpGenerator.h" #include "ast/Generator.h" #include "ast/Module.h" #include "ast/Function.h" #include "ast/Variable.h" #include "ast/Parameter.h" #include "ast/Statement.h" #include "ast/Expression.h" #include "ast/ClassDeclaration.h" #include "ast/AsyncNodes.h" #include "ast/Serialization.h" #include "CrossLanguageProjector.h" #include "MemoryStrategyInference.h" #include #include #include #include #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 {} // 1. Cross-language projection: Python-like AST → Kotlin void test_cross_projection_to_kotlin() { TEST(cross_projection_to_kotlin); // Build a Python-flavored AST auto mod = std::make_unique("mod1", "pymod", "python"); auto fn = std::make_unique("fn1", "compute"); auto retStmt = std::make_unique(); retStmt->id = "r1"; auto retVal = std::make_unique("il1", 99); retStmt->addChild("value", retVal.release()); fn->addChild("body", retStmt.release()); mod->addChild("functions", fn.release()); // Generate as Kotlin KotlinGenerator gen; std::string out = gen.generate(mod.get()); CHECK(out.find("fun compute") != std::string::npos, "Kotlin output missing 'fun compute'"); CHECK(out.find("return 99") != std::string::npos, "Kotlin output missing 'return 99'"); PASS(); } // 2. Cross-language projection: Java-like AST → C# void test_cross_projection_to_csharp() { TEST(cross_projection_to_csharp); auto mod = std::make_unique("mod1", "javamod", "java"); auto fn = std::make_unique("fn1", "Process"); auto retStmt = std::make_unique(); retStmt->id = "r1"; auto retVal = std::make_unique("s1", "result"); retStmt->addChild("value", retVal.release()); fn->addChild("body", retStmt.release()); mod->addChild("functions", fn.release()); CSharpGenerator gen; std::string out = gen.generate(mod.get()); CHECK(out.find("public void Process") != std::string::npos, "C# output missing 'public void Process'"); CHECK(out.find("return \"result\"") != std::string::npos, "C# output missing return statement"); PASS(); } // 3. Pipeline.parse() with Kotlin source void test_pipeline_parse_kotlin() { TEST(pipeline_parse_kotlin); Pipeline pipeline; std::vector diags; auto mod = pipeline.parse(R"( fun hello() { println("world") } )", "kotlin", diags); CHECK(mod != nullptr, "Pipeline.parse() returned null for Kotlin"); CHECK(mod->targetLanguage == "kotlin", "target language should be 'kotlin'"); auto fns = mod->getChildren("functions"); CHECK(fns.size() == 1, "expected 1 function from Kotlin parse"); PASS(); } // 4. Pipeline.parse() with C# source void test_pipeline_parse_csharp() { TEST(pipeline_parse_csharp); Pipeline pipeline; std::vector diags; auto mod = pipeline.parse(R"( public void Execute() { int x = 42; } )", "csharp", diags); CHECK(mod != nullptr, "Pipeline.parse() returned null for C#"); CHECK(mod->targetLanguage == "csharp", "target language should be 'csharp'"); auto fns = mod->getChildren("functions"); CHECK(fns.size() == 1, "expected 1 function from C# parse"); PASS(); } // 5. Pipeline.generate() for both new languages void test_pipeline_generate_both() { TEST(pipeline_generate_both); Pipeline pipeline; // Build a simple AST auto mod = std::make_unique("mod1", "test", "python"); auto fn = std::make_unique("fn1", "work"); auto retStmt = std::make_unique(); retStmt->id = "r1"; fn->addChild("body", retStmt.release()); mod->addChild("functions", fn.release()); std::string kotlin = pipeline.generate(mod.get(), "kotlin"); std::string csharp = pipeline.generate(mod.get(), "csharp"); CHECK(!kotlin.empty(), "Kotlin generation produced empty output"); CHECK(!csharp.empty(), "C# generation produced empty output"); CHECK(kotlin.find("fun work") != std::string::npos, "Kotlin missing 'fun work'"); CHECK(csharp.find("public void work") != std::string::npos, "C# missing 'public void work'"); PASS(); } // 6. MemoryStrategyInference handles Kotlin/C# languages void test_memory_inference_new_languages() { TEST(memory_inference_new_languages); // Build a Kotlin module auto ktMod = std::make_unique("mod1", "ktmod", "kotlin"); auto fn1 = std::make_unique("fn1", "run"); ktMod->addChild("functions", fn1.release()); MemoryStrategyInference inference; auto suggestions = inference.inferAnnotations(ktMod.get()); // Should not crash; suggestions depend on module structure // Just verify it completes without error // Build a C# module auto csMod = std::make_unique("mod2", "csmod", "csharp"); auto fn2 = std::make_unique("fn2", "execute"); csMod->addChild("functions", fn2.release()); auto csSuggestions = inference.inferAnnotations(csMod.get()); // Same: should not crash CHECK(true, ""); PASS(); } // 7. All 10 generators produce non-empty output void test_all_10_generators() { TEST(all_10_generators); Pipeline pipeline; auto fn = std::make_unique("fn1", "test"); auto retStmt = std::make_unique(); retStmt->id = "r1"; fn->addChild("body", retStmt.release()); std::vector languages = { "python", "cpp", "elisp", "javascript", "typescript", "java", "rust", "go", "kotlin", "csharp" }; for (const auto& lang : languages) { std::string out = pipeline.generate(fn.get(), lang); CHECK(!out.empty(), ("Empty output for language: " + lang).c_str()); } CHECK(languages.size() == 10, "expected 10 languages"); PASS(); } // 8. Final language count: 10 parsers, 10 generators void test_final_language_count() { TEST(final_language_count); Pipeline pipeline; // Test all 10 parsers produce valid modules struct ParserTest { std::string lang; std::string source; }; std::vector parserTests = { {"python", "def hello():\n pass\n"}, {"cpp", "void hello() {}\n"}, {"elisp", "(defun hello () nil)\n"}, {"javascript", "function hello() {}\n"}, {"typescript", "function hello(): void {}\n"}, {"java", "public void hello() {}\n"}, {"rust", "fn hello() {}\n"}, {"go", "func hello() {\n}\n"}, {"kotlin", "fun hello() {\n}\n"}, {"csharp", "public void hello() {\n}\n"}, }; int parserCount = 0; for (const auto& pt : parserTests) { std::vector diags; auto mod = pipeline.parse(pt.source, pt.lang, diags); if (mod != nullptr) parserCount++; } CHECK(parserCount == 10, "expected 10 working parsers, got " + std::to_string(parserCount)); // Verify all 10 generators auto testNode = std::make_unique("fn1", "test"); auto ret = std::make_unique(); ret->id = "r1"; testNode->addChild("body", ret.release()); std::vector genLangs = { "python", "cpp", "elisp", "javascript", "typescript", "java", "rust", "go", "kotlin", "csharp" }; int genCount = 0; for (const auto& lang : genLangs) { std::string out = pipeline.generate(testNode.get(), lang); if (!out.empty()) genCount++; } CHECK(genCount == 10, "expected 10 working generators, got " + std::to_string(genCount)); PASS(); } int main() { std::cout << "Step 313: New Languages Integration Tests\n"; test_cross_projection_to_kotlin(); // 1 test_cross_projection_to_csharp(); // 2 test_pipeline_parse_kotlin(); // 3 test_pipeline_parse_csharp(); // 4 test_pipeline_generate_both(); // 5 test_memory_inference_new_languages(); // 6 test_all_10_generators(); // 7 test_final_language_count(); // 8 std::cout << "\nResults: " << passed << "/" << (passed + failed) << " passed\n"; return failed == 0 ? 0 : 1; }