// CLI Grep Command Path Tree tests // Catch2 migration from GTest (yams-3s4 / yams-cli) // // Integration test for grep --path-tree flag. // Tests the path-tree retrieval service integration end-to-end. #include #include #include #include #include #include #include #include namespace fs = std::filesystem; namespace { /** * Test fixture providing isolated database for grep path-tree tests. */ struct GrepPathTreeFixture { fs::path testDir; fs::path dbPath; std::unique_ptr pool; std::shared_ptr repo; GrepPathTreeFixture() { // Create temporary directory for test database testDir = fs::temp_directory_path() / ("yams_test_" + std::to_string(std::random_device{}())); fs::create_directories(testDir); dbPath = testDir / "metadata.db"; // Initialize connection pool and repository yams::metadata::ConnectionPoolConfig poolCfg; poolCfg.minConnections = 1; poolCfg.maxConnections = 2; pool = std::make_unique(dbPath.string(), poolCfg); auto initRes = pool->initialize(); REQUIRE(initRes.has_value()); repo = std::make_shared(*pool); } ~GrepPathTreeFixture() { repo.reset(); pool.reset(); // Clean up test directory std::error_code ec; fs::remove_all(testDir, ec); } }; } // namespace TEST_CASE("GrepPathTree - PathTreeOptions struct creation", "[cli][grep][path_tree][catch2]") { // Test PathTreeOptions struct initialization yams::app::services::PathTreeOptions opts; CHECK_FALSE(opts.enabled); CHECK(opts.mode == "fallback"); CHECK(opts.childLimit == 5); // Test with custom values opts.enabled = true; opts.mode = "preferred"; opts.childLimit = 10; CHECK(opts.enabled); CHECK(opts.mode == "preferred"); CHECK(opts.childLimit == 10); } TEST_CASE("GrepPathTree - mode disabled by default", "[cli][grep][path_tree][catch2]") { GrepPathTreeFixture fixture; // Verify normal grep attempts daemon-first when path-tree not enabled yams::app::services::RetrievalService rsvc; yams::app::services::GrepOptions grepOpts; grepOpts.pattern = "test"; yams::app::services::RetrievalOptions ropts; ropts.explicitDataDir = fixture.testDir; ropts.requestTimeoutMs = 1000; // Call without PathTreeOptions - should use daemon-first path (will fail to connect) auto result = rsvc.grep(grepOpts, ropts, std::nullopt); // When daemon connection fails, falls back to local error (no documents indexed) // Current implementation returns error (connection timeout or IPC error) // We're validating the code path compiles and executes without crash CHECK((result.has_value() || !result.has_value())); // Either succeeds with empty or fails with error } TEST_CASE("GrepPathTree - mode with empty repository", "[cli][grep][path_tree][catch2]") { GrepPathTreeFixture fixture; // Test path-tree mode with empty repository // NOTE: RetrievalService::grep() requires daemon IPC, which is not available in unit tests. // This test validates the code path compiles and executes without crash. // Full integration testing requires DaemonHarness (see tests/integration/daemon/). yams::app::services::RetrievalService rsvc; yams::app::services::GrepOptions grepOpts; grepOpts.pattern = "test"; grepOpts.paths = {"/project/src"}; yams::app::services::RetrievalOptions ropts; ropts.explicitDataDir = fixture.testDir; ropts.requestTimeoutMs = 1000; // Short timeout since no daemon is running yams::app::services::PathTreeOptions ptOpts; ptOpts.enabled = true; ptOpts.mode = "fallback"; ptOpts.childLimit = 5; auto result = rsvc.grep(grepOpts, ropts, ptOpts); // Without a running daemon, this will fail with timeout or connection error. // We're validating the code path compiles and executes without crash. // Full path-tree grep integration tests should use DaemonHarness. CHECK((result.has_value() || !result.has_value())); } TEST_CASE("GrepPathTree - childLimit configuration", "[cli][grep][path_tree][catch2]") { // Verify childLimit is respected yams::app::services::PathTreeOptions opts; opts.enabled = true; opts.childLimit = 3; CHECK(opts.childLimit == 3); opts.childLimit = 100; CHECK(opts.childLimit == 100); }