use ralph::symbol_index::SymbolIndex;
use std::fs;
use tempfile::TempDir;
fn write(dir: &TempDir, name: &str, content: &str) {
let path = dir.path().join(name);
if let Some(parent) = path.parent() {
fs::create_dir_all(parent).unwrap();
}
fs::write(path, content).unwrap();
}
#[test]
fn finds_rust_function() {
let dir = TempDir::new().unwrap();
write(&dir, "lib.rs", "pub fn hello_world() {}\n");
let idx = SymbolIndex::build(dir.path());
let results = idx.find("hello_world", 10);
assert!(!results.is_empty());
assert_eq!(results[0].name, "hello_world");
}
#[test]
fn finds_rust_struct() {
let dir = TempDir::new().unwrap();
write(&dir, "models.rs", "pub struct FooBar { x: u32 }\n");
let idx = SymbolIndex::build(dir.path());
let results = idx.find("FooBar", 10);
assert!(!results.is_empty());
assert_eq!(results[0].name, "FooBar");
}
#[test]
fn find_is_case_insensitive() {
let dir = TempDir::new().unwrap();
write(&dir, "lib.rs", "pub fn MyFunction() {}\n");
let idx = SymbolIndex::build(dir.path());
let results = idx.find("myfunction", 10);
assert!(!results.is_empty());
}
#[test]
fn find_returns_substring_matches() {
let dir = TempDir::new().unwrap();
write(
&dir,
"lib.rs",
"pub fn process_request() {}\npub fn process_response() {}\n",
);
let idx = SymbolIndex::build(dir.path());
let results = idx.find("process", 10);
assert!(results.len() >= 2);
}
#[test]
fn find_returns_empty_for_unknown_name() {
let dir = TempDir::new().unwrap();
write(&dir, "lib.rs", "pub fn foo() {}\n");
let idx = SymbolIndex::build(dir.path());
let results = idx.find("zzz_not_found", 10);
assert!(results.is_empty());
}
#[test]
fn read_body_returns_source() {
let dir = TempDir::new().unwrap();
write(
&dir,
"lib.rs",
"pub fn greet() {\n println!(\"hi\");\n}\n",
);
let idx = SymbolIndex::build(dir.path());
let body = idx.read_body("greet");
assert!(body.is_some());
let body = body.unwrap();
assert!(body.contains("greet"));
assert!(body.contains("println"));
}
#[test]
fn read_body_returns_none_for_unknown() {
let dir = TempDir::new().unwrap();
write(&dir, "lib.rs", "pub fn foo() {}\n");
let idx = SymbolIndex::build(dir.path());
assert!(idx.read_body("not_a_real_symbol").is_none());
}
#[test]
fn symbol_count_reflects_indexed_symbols() {
let dir = TempDir::new().unwrap();
write(
&dir,
"lib.rs",
"pub fn a() {}\npub fn b() {}\npub struct C {}\n",
);
let idx = SymbolIndex::build(dir.path());
assert!(idx.symbol_count() >= 3);
}
#[test]
fn finds_python_function() {
let dir = TempDir::new().unwrap();
write(&dir, "main.py", "def my_py_func():\n pass\n");
let idx = SymbolIndex::build(dir.path());
let results = idx.find("my_py_func", 10);
assert!(!results.is_empty());
}
#[test]
fn finds_typescript_function() {
let dir = TempDir::new().unwrap();
write(&dir, "index.ts", "export function tsFunc() { return 1; }\n");
let idx = SymbolIndex::build(dir.path());
let results = idx.find("tsFunc", 10);
assert!(!results.is_empty());
}
#[test]
fn find_limit_is_respected() {
let dir = TempDir::new().unwrap();
let fns: String = (0..20)
.map(|i| format!("pub fn foo_func_{i}() {{}}\n"))
.collect();
write(&dir, "lib.rs", &fns);
let idx = SymbolIndex::build(dir.path());
let results = idx.find("foo_func", 5);
assert_eq!(results.len(), 5);
}