From aed787f44b2a4fa2bd5bc925dc718d58d96f1519 Mon Sep 17 00:00:00 2001 From: ak2k <19240940+ak2k@users.noreply.github.com> Date: Sun, 5 Jul 2026 00:21:18 -0400 Subject: [PATCH] test(ck-engine): guard empty-corpus lexical rebuild Add a regression test covering the transition from an empty corpus (which builds an empty tantivy index) to a populated one: the corpus fingerprint changes, so the next lexical search must rebuild and surface the new files rather than trusting the empty index. The test uses a plain #[tokio::test] with a TempDir-scoped .ck, matching the other lexical-search tests: the unique temp path keys its own index (in-tree, or a path-hashed subdir when CK_INDEX_DIR relocates it), so it stays isolated without serial_test or removing the CK_INDEX_DIR env var. --- ck-engine/src/lib.rs | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/ck-engine/src/lib.rs b/ck-engine/src/lib.rs index 1e0309d..3d6beef 100644 --- a/ck-engine/src/lib.rs +++ b/ck-engine/src/lib.rs @@ -2747,4 +2747,43 @@ mod tests { // Top score is normalized to 1.0, exactly as before this patch. assert!((results[0].score - 1.0).abs() < 1e-6); } + + #[tokio::test] + async fn test_lexical_search_rebuilds_empty_stub() { + // A lexical search over a directory with no indexable files builds an + // empty tantivy index. Once real files appear the corpus fingerprint + // changes, so a later search must rebuild and surface them rather than + // trusting the empty index. The unique TempDir path keys its own index + // (in-tree .ck, or a path-hashed subdir under CK_INDEX_DIR when set), so + // the test needs no env manipulation or serialization to stay isolated. + let temp_dir = TempDir::new().unwrap(); + fs::create_dir_all(temp_dir.path().join(".ck")).unwrap(); + + let options = SearchOptions { + mode: SearchMode::Lexical, + query: "zebra".to_string(), + path: temp_dir.path().to_path_buf(), + recursive: true, + ..Default::default() + }; + + // First search builds an empty index (no files yet). + let empty = lexical_search(&options).await.unwrap(); + assert!(empty.is_empty()); + + // A real file appears; the next search must find it. + fs::write( + temp_dir.path().join("mod.py"), + "def gamma():\n zebra = 3\n return zebra\n", + ) + .unwrap(); + + let results = lexical_search(&options).await.unwrap(); + assert!( + results + .iter() + .any(|r| r.file.file_name().unwrap() == "mod.py"), + "empty tantivy stub was trusted; expected a rebuild to find the new file" + ); + } }