// Step 407: VB.NET Parser Tests (12 tests) #include "ast/VBNetParser.h" #include "Pipeline.h" #include "ast/Function.h" #include "ast/Variable.h" #include "ast/ClassDeclaration.h" #include "ast/EnumNamespaceNodes.h" #include "ast/Statement.h" #include #include 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_parse_sub_method() { TEST(parse_sub_method); auto mod = VBNetParser::parseVBNet( "Public Sub DoWork(x As Integer)\n" "End Sub\n"); CHECK(mod != nullptr, "module is null"); auto fns = mod->getChildren("functions"); CHECK(fns.size() == 1, "expected 1 function"); auto* fn = static_cast(fns[0]); CHECK(fn->name == "DoWork", "expected method DoWork"); PASS(); } void test_parse_function_method() { TEST(parse_function_method); auto mod = VBNetParser::parseVBNet( "Public Function Sum(a As Integer, b As Integer) As Integer\n" "End Function\n"); CHECK(mod != nullptr, "module is null"); auto fns = mod->getChildren("functions"); CHECK(fns.size() == 1, "expected 1 function"); auto* fn = static_cast(fns[0]); CHECK(fn->name == "Sum", "expected method Sum"); PASS(); } void test_parse_class() { TEST(parse_class); auto mod = VBNetParser::parseVBNet( "Class Person\n" "End Class\n"); CHECK(mod != nullptr, "module is null"); auto classes = mod->getChildren("classes"); CHECK(classes.size() == 1, "expected 1 class"); auto* cls = static_cast(classes[0]); CHECK(cls->name == "Person", "expected class Person"); PASS(); } void test_parse_interface() { TEST(parse_interface); auto mod = VBNetParser::parseVBNet( "Interface IWorker\n" "End Interface\n"); CHECK(mod != nullptr, "module is null"); auto ifaces = mod->getChildren("interfaces"); CHECK(ifaces.size() == 1, "expected 1 interface"); auto* iface = static_cast(ifaces[0]); CHECK(iface->name == "IWorker", "expected interface IWorker"); PASS(); } void test_parse_module_namespace() { TEST(parse_module_namespace); auto mod = VBNetParser::parseVBNet( "Module Utils\n" "End Module\n"); CHECK(mod != nullptr, "module is null"); auto stmts = mod->getChildren("statements"); NamespaceDeclaration* ns = nullptr; for (auto* s : stmts) { if (s->conceptType == "NamespaceDeclaration") ns = static_cast(s); } CHECK(ns != nullptr, "expected namespace declaration"); CHECK(ns->name == "Utils", "expected module name Utils"); PASS(); } void test_parse_dim_variable() { TEST(parse_dim_variable); auto mod = VBNetParser::parseVBNet("Dim x As Integer = 5\n"); CHECK(mod != nullptr, "module is null"); auto vars = mod->getChildren("variables"); CHECK(vars.size() == 1, "expected 1 variable"); auto* var = static_cast(vars[0]); CHECK(var->name == "x", "expected variable x"); PASS(); } void test_parse_if_then_block() { TEST(parse_if_then_block); auto mod = VBNetParser::parseVBNet( "If x > 0 Then\n" "ElseIf x < 0 Then\n" "Else\n" "End If\n"); CHECK(mod != nullptr, "module is null"); bool foundIf = false; for (auto* s : mod->getChildren("statements")) { if (s->conceptType == "IfStatement") foundIf = true; } CHECK(foundIf, "expected IfStatement marker"); PASS(); } void test_parse_for_each_block() { TEST(parse_for_each_block); auto mod = VBNetParser::parseVBNet( "For Each item In collection\n" "Next\n"); CHECK(mod != nullptr, "module is null"); bool foundFor = false; for (auto* s : mod->getChildren("statements")) { if (s->conceptType == "ForLoop") { auto* loop = static_cast(s); CHECK(loop->iteratorName == "item", "expected iterator item"); foundFor = true; } } CHECK(foundFor, "expected ForLoop marker"); PASS(); } void test_case_insensitive_keywords() { TEST(case_insensitive_keywords); auto mod = VBNetParser::parseVBNet( "public sub Run()\n" "end sub\n"); CHECK(mod != nullptr, "module is null"); CHECK(mod->getChildren("functions").size() == 1, "expected function with lowercase keyword"); PASS(); } void test_parse_with_diagnostics() { TEST(parse_with_diagnostics); auto result = VBNetParser::parseVBNetWithDiagnostics( "Function Echo(value As String) As String\n" "End Function\n"); CHECK(result.module != nullptr, "module is null"); CHECK(result.module->getChildren("functions").size() == 1, "expected 1 function"); PASS(); } void test_parse_mixed_file() { TEST(parse_mixed_file); auto mod = VBNetParser::parseVBNet( "' comment\n" "Module App\n" "End Module\n" "Class Person\n" "End Class\n" "Public Sub Main()\n" "End Sub\n" "Dim count As Integer = 1\n"); CHECK(mod != nullptr, "module is null"); CHECK(mod->getChildren("statements").size() >= 1, "expected module statement"); CHECK(mod->getChildren("classes").size() == 1, "expected class"); CHECK(mod->getChildren("functions").size() == 1, "expected function"); CHECK(mod->getChildren("variables").size() == 1, "expected variable"); PASS(); } void test_pipeline_parse_routing() { TEST(pipeline_parse_routing); Pipeline p; std::vector d1, d2, d3; auto m1 = p.parse("Sub Main()\nEnd Sub\n", "vbnet", d1); auto m2 = p.parse("Sub Main()\nEnd Sub\n", "vb", d2); auto m3 = p.parse("Sub Main()\nEnd Sub\n", "vb.net", d3); CHECK(m1 != nullptr && m2 != nullptr && m3 != nullptr, "expected parse success for aliases"); CHECK(m1->targetLanguage == "vbnet", "expected vbnet target language"); CHECK(m2->targetLanguage == "vbnet", "expected vb alias target language"); CHECK(m3->targetLanguage == "vbnet", "expected vb.net alias target language"); PASS(); } int main() { std::cout << "Step 407: VB.NET Parser Tests\n"; test_parse_sub_method(); // 1 test_parse_function_method(); // 2 test_parse_class(); // 3 test_parse_interface(); // 4 test_parse_module_namespace(); // 5 test_parse_dim_variable(); // 6 test_parse_if_then_block(); // 7 test_parse_for_each_block(); // 8 test_case_insensitive_keywords(); // 9 test_parse_with_diagnostics(); // 10 test_parse_mixed_file(); // 11 test_pipeline_parse_routing(); // 12 std::cout << "\nResults: " << passed << "/" << (passed + failed) << " passed\n"; return failed == 0 ? 0 : 1; }