// Step 479: Dependency + Build System Awareness Tests (12 tests) #include "ArchitectBuildAwareness.h" #include #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 {} static SkeletonModuleSpec mk(const std::string& name, const std::string& lang, std::initializer_list deps = {}) { SkeletonModuleSpec m; m.moduleName = name; m.language = lang; m.dependencies.assign(deps.begin(), deps.end()); return m; } void test_python_dependency_annotations_include_imports_and_pip_requirements() { TEST(python_dependency_annotations_include_imports_and_pip_requirements); SkeletonProjectSpec sk; sk.modules.push_back(mk("api", "python", {"data"})); auto report = ArchitectBuildAwareness::annotate(sk); auto api = report.getModule("api"); CHECK(!api.importHints.empty(), "expected import hints"); CHECK(api.importHints[0].find("from data import *") != std::string::npos, "missing data import"); CHECK(api.manifestSnippet.find("fastapi") != std::string::npos, "missing fastapi hint"); PASS(); } void test_rust_dependency_annotations_include_cargo_format() { TEST(rust_dependency_annotations_include_cargo_format); SkeletonProjectSpec sk; sk.modules.push_back(mk("core", "rust", {"util"})); sk.modules.push_back(mk("util", "rust")); auto report = ArchitectBuildAwareness::annotate(sk); auto core = report.getModule("core"); CHECK(core.manifestSnippet.find("[dependencies]") != std::string::npos, "missing dependencies section"); CHECK(core.manifestSnippet.find("util = { path = \"../util\" }") != std::string::npos, "missing local crate path dep"); PASS(); } void test_node_dependency_annotations_include_package_json_style() { TEST(node_dependency_annotations_include_package_json_style); SkeletonProjectSpec sk; sk.modules.push_back(mk("api", "typescript", {"auth"})); auto report = ArchitectBuildAwareness::annotate(sk); auto api = report.getModule("api"); CHECK(api.manifestSnippet.find("\"dependencies\"") != std::string::npos, "missing package deps object"); CHECK(api.manifestSnippet.find("express") != std::string::npos, "missing express hint"); PASS(); } void test_cpp_dependency_annotations_include_cmake_target_hints() { TEST(cpp_dependency_annotations_include_cmake_target_hints); SkeletonProjectSpec sk; sk.modules.push_back(mk("engine", "cpp", {"math"})); sk.modules.push_back(mk("math", "cpp")); auto report = ArchitectBuildAwareness::annotate(sk); auto engine = report.getModule("engine"); CHECK(engine.importHints[0].find("#include \"math.h\"") != std::string::npos, "missing include hint"); CHECK(engine.manifestSnippet.find("target_link_libraries(engine INTERFACE math)") != std::string::npos, "missing cmake link line"); PASS(); } void test_sql_dependency_annotations_include_migration_ordering() { TEST(sql_dependency_annotations_include_migration_ordering); SkeletonProjectSpec sk; sk.modules.push_back(mk("schema", "sql")); sk.modules.push_back(mk("seed", "sql", {"schema"})); auto report = ArchitectBuildAwareness::annotate(sk); auto schema = report.getModule("schema"); auto seed = report.getModule("seed"); CHECK(schema.migrationOrder > 0, "schema missing migration order"); CHECK(seed.migrationOrder > schema.migrationOrder, "seed should come after schema"); PASS(); } void test_module_dependencies_are_preserved_in_report() { TEST(module_dependencies_are_preserved_in_report); SkeletonProjectSpec sk; sk.modules.push_back(mk("api", "python", {"auth", "data"})); auto report = ArchitectBuildAwareness::annotate(sk); auto api = report.getModule("api"); CHECK(api.moduleDependencies.size() == 2, "dependency count mismatch"); CHECK(api.moduleDependencies[0] == "auth", "missing auth dep"); CHECK(api.moduleDependencies[1] == "data", "missing data dep"); PASS(); } void test_module_without_dependencies_still_has_manifest_snippet() { TEST(module_without_dependencies_still_has_manifest_snippet); SkeletonProjectSpec sk; sk.modules.push_back(mk("core", "rust")); auto report = ArchitectBuildAwareness::annotate(sk); auto core = report.getModule("core"); CHECK(core.manifestSnippet.find("[dependencies]") != std::string::npos, "missing manifest header"); PASS(); } void test_mixed_language_report_contains_all_modules() { TEST(mixed_language_report_contains_all_modules); SkeletonProjectSpec sk; sk.modules.push_back(mk("api", "python")); sk.modules.push_back(mk("core", "rust")); sk.modules.push_back(mk("ui", "typescript")); sk.modules.push_back(mk("engine", "cpp")); sk.modules.push_back(mk("schema", "sql")); auto report = ArchitectBuildAwareness::annotate(sk); CHECK(report.modules.size() == 5, "expected five modules"); PASS(); } void test_node_dependencies_emit_import_hints_for_each_module_dep() { TEST(node_dependencies_emit_import_hints_for_each_module_dep); SkeletonProjectSpec sk; sk.modules.push_back(mk("ui", "typescript", {"api", "state"})); auto report = ArchitectBuildAwareness::annotate(sk); auto ui = report.getModule("ui"); CHECK(ui.importHints.size() == 2, "import hint count mismatch"); CHECK(ui.importHints[0].find("../api/api") != std::string::npos, "missing api import path"); PASS(); } void test_unknown_language_falls_back_to_generic_hint() { TEST(unknown_language_falls_back_to_generic_hint); SkeletonProjectSpec sk; sk.modules.push_back(mk("docs", "markdown")); auto report = ArchitectBuildAwareness::annotate(sk); auto docs = report.getModule("docs"); CHECK(docs.manifestSnippet.find("build-hints unavailable") != std::string::npos, "missing generic fallback hint"); PASS(); } void test_sql_cycle_fallback_is_deterministic() { TEST(sql_cycle_fallback_is_deterministic); SkeletonProjectSpec sk; sk.modules.push_back(mk("a", "sql", {"b"})); sk.modules.push_back(mk("b", "sql", {"a"})); auto report = ArchitectBuildAwareness::annotate(sk); auto a = report.getModule("a"); auto b = report.getModule("b"); CHECK(a.migrationOrder > 0 && b.migrationOrder > 0, "expected migration orders"); CHECK(a.migrationOrder != b.migrationOrder, "orders should remain unique"); PASS(); } void test_global_notes_explain_annotation_scope() { TEST(global_notes_explain_annotation_scope); SkeletonProjectSpec sk; sk.modules.push_back(mk("api", "python")); auto report = ArchitectBuildAwareness::annotate(sk); CHECK(report.globalNotes.size() >= 2, "missing report notes"); CHECK(report.globalNotes[1].find("annotation-level") != std::string::npos, "missing scope disclaimer"); PASS(); } int main() { std::cout << "Step 479: Dependency + Build System Awareness Tests\n"; test_python_dependency_annotations_include_imports_and_pip_requirements(); // 1 test_rust_dependency_annotations_include_cargo_format(); // 2 test_node_dependency_annotations_include_package_json_style(); // 3 test_cpp_dependency_annotations_include_cmake_target_hints(); // 4 test_sql_dependency_annotations_include_migration_ordering(); // 5 test_module_dependencies_are_preserved_in_report(); // 6 test_module_without_dependencies_still_has_manifest_snippet(); // 7 test_mixed_language_report_contains_all_modules(); // 8 test_node_dependencies_emit_import_hints_for_each_module_dep(); // 9 test_unknown_language_falls_back_to_generic_hint(); // 10 test_sql_cycle_fallback_is_deterministic(); // 11 test_global_notes_explain_annotation_scope(); // 12 std::cout << "\nResults: " << passed << "/" << (passed + failed) << " passed\n"; return failed == 0 ? 0 : 1; }