WIP: Batch 1 — backfill tests for store, search, and workflow
- store.rs: 8 tests (roundtrip, persistence, corrupt/empty file handling) - io/search.rs: 5 tests (matching, nested dirs, gitignore, empty results) - workflow.rs: 7 new tests (acceptance logic, summarize, can_start, record, refresh) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -63,3 +63,101 @@ pub async fn search_files_impl(query: String, root: PathBuf) -> Result<Vec<Searc
|
||||
|
||||
Ok(results)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use std::fs;
|
||||
use tempfile::TempDir;
|
||||
|
||||
fn setup_project(files: &[(&str, &str)]) -> TempDir {
|
||||
let dir = TempDir::new().unwrap();
|
||||
for (path, content) in files {
|
||||
let full = dir.path().join(path);
|
||||
if let Some(parent) = full.parent() {
|
||||
fs::create_dir_all(parent).unwrap();
|
||||
}
|
||||
fs::write(full, content).unwrap();
|
||||
}
|
||||
dir
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn finds_files_matching_query() {
|
||||
let dir = setup_project(&[
|
||||
("hello.txt", "hello world"),
|
||||
("goodbye.txt", "goodbye world"),
|
||||
]);
|
||||
|
||||
let results = search_files_impl("hello".to_string(), dir.path().to_path_buf())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(results.len(), 1);
|
||||
assert_eq!(results[0].path, "hello.txt");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn returns_empty_for_no_matches() {
|
||||
let dir = setup_project(&[("file.txt", "some content")]);
|
||||
|
||||
let results = search_files_impl("nonexistent".to_string(), dir.path().to_path_buf())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert!(results.is_empty());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn searches_nested_directories() {
|
||||
let dir = setup_project(&[
|
||||
("top.txt", "needle"),
|
||||
("sub/deep.txt", "needle in haystack"),
|
||||
("sub/other.txt", "no match here"),
|
||||
]);
|
||||
|
||||
let results = search_files_impl("needle".to_string(), dir.path().to_path_buf())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(results.len(), 2);
|
||||
let paths: Vec<&str> = results.iter().map(|r| r.path.as_str()).collect();
|
||||
assert!(paths.contains(&"top.txt"));
|
||||
assert!(paths.contains(&"sub/deep.txt"));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn skips_directories_only_matches_files() {
|
||||
let dir = setup_project(&[("sub/file.txt", "content")]);
|
||||
|
||||
let results = search_files_impl("content".to_string(), dir.path().to_path_buf())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(results.len(), 1);
|
||||
assert_eq!(results[0].path, "sub/file.txt");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn respects_gitignore() {
|
||||
let dir = setup_project(&[
|
||||
(".gitignore", "ignored/\n"),
|
||||
("kept.txt", "search term"),
|
||||
("ignored/hidden.txt", "search term"),
|
||||
]);
|
||||
|
||||
// Initialize a git repo so .gitignore is respected
|
||||
std::process::Command::new("git")
|
||||
.args(["init"])
|
||||
.current_dir(dir.path())
|
||||
.output()
|
||||
.unwrap();
|
||||
|
||||
let results = search_files_impl("search term".to_string(), dir.path().to_path_buf())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(results.len(), 1);
|
||||
assert_eq!(results[0].path, "kept.txt");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user