use opengrep::{Config, SearchEngine};
use std::fs::{self, File};
use std::io::Write;
use std::path::PathBuf;
use tempfile::tempdir;
fn setup_test_files() -> (PathBuf, Vec<PathBuf>) {
let dir = tempdir().unwrap();
let file1_path = dir.path().join("file1.rs");
let file2_path = dir.path().join("file2.py");
let nested_dir = dir.path().join("nested");
fs::create_dir(&nested_dir).unwrap();
let file3_path = nested_dir.join("file3.js");
let mut file1 = File::create(&file1_path).unwrap();
file1.write_all(b"fn main() {\n // A TODO comment\n}\n").unwrap();
let mut file2 = File::create(&file2_path).unwrap();
file2.write_all(b"def main():\n # Another TODO here\n pass\n").unwrap();
let mut file3 = File::create(&file3_path).unwrap();
file3.write_all(b"function main() {\n // No items of interest\n}\n").unwrap();
(dir.into_path(), vec![file1_path, file2_path, file3_path])
}
#[tokio::test]
async fn test_simple_search() {
let (dir_path, _files) = setup_test_files();
let config = Config::default();
let engine = SearchEngine::new(config);
let results = engine.search("TODO", &[dir_path]).await.unwrap();
assert_eq!(results.len(), 2);
let total_matches: usize = results.iter().map(|r| r.matches.len()).sum();
assert_eq!(total_matches, 2);
}
#[tokio::test]
async fn test_case_sensitive_search() {
let (dir_path, _files) = setup_test_files();
let mut config = Config::default();
config.search.ignore_case = false;
let engine = SearchEngine::new(config);
let results = engine.search("todo", &[dir_path]).await.unwrap();
assert_eq!(results.len(), 0);
}
#[tokio::test]
async fn test_regex_search() {
let (dir_path, _files) = setup_test_files();
let mut config = Config::default();
config.search.regex = true;
let engine = SearchEngine::new(config);
let results = engine.search("co..ent", &[dir_path]).await.unwrap();
assert_eq!(results.len(), 1);
assert_eq!(results[0].matches.len(), 1);
assert!(results[0].matches[0].line.contains("comment"));
}
#[tokio::test]
async fn test_ast_context_search() {
let (dir_path, _files) = setup_test_files();
let mut config = Config::default();
config.output.show_ast_context = true;
let engine = SearchEngine::new(config);
let results = engine.search("TODO", &[dir_path]).await.unwrap();
assert_eq!(results.len(), 2);
let rust_match = results.iter().find(|r| r.path.ends_with("file1.rs")).unwrap();
assert_eq!(rust_match.matches[0].ast_context.as_ref().unwrap().parent_name, "main");
}