#[cfg(test)]
mod call_graph_tests {
use crate::backend_router::MagellanBackend;
use crate::graph::CodeGraph;
use std::path::PathBuf;
fn setup_test_db_with_calls() -> (tempfile::TempDir, PathBuf) {
let temp_dir = tempfile::tempdir().unwrap();
let db_path = temp_dir.path().join("test.db");
let mut graph = CodeGraph::open(&db_path).unwrap();
let source = r#"
fn caller_function() {
callee_a();
callee_b();
}
fn callee_a() {
helper_func();
}
fn callee_b() {
callee_a();
}
fn helper_func() {}
fn main() {
caller_function();
callee_a();
}
"#;
let symbol_count = graph.index_file("src/test.rs", source.as_bytes()).unwrap();
assert!(symbol_count > 0, "Expected some symbols to be indexed");
(temp_dir, db_path)
}
#[test]
fn test_calls_from_symbol_sqlite() {
let (_temp_dir, db_path) = setup_test_db_with_calls();
let mut backend = MagellanBackend::open(&db_path).unwrap();
let calls = backend.calls_from_symbol("src/test.rs", "caller_function").unwrap();
assert_eq!(calls.len(), 2, "Expected 2 calls from caller_function");
let callee_names: Vec<String> = calls.iter().map(|c| c.callee.clone()).collect();
assert!(
callee_names.contains(&"callee_a".to_string()),
"Expected callee_a in calls"
);
assert!(
callee_names.contains(&"callee_b".to_string()),
"Expected callee_b in calls"
);
for call in &calls {
assert_eq!(call.caller, "caller_function");
assert_eq!(call.file_path.to_str().unwrap(), "src/test.rs");
assert!(call.byte_start < call.byte_end);
assert!(call.start_line > 0);
}
}
#[test]
fn test_callers_of_symbol_sqlite() {
let (_temp_dir, db_path) = setup_test_db_with_calls();
let mut backend = MagellanBackend::open(&db_path).unwrap();
let calls = backend.callers_of_symbol("src/test.rs", "callee_a").unwrap();
assert_eq!(calls.len(), 3, "Expected 3 calls to callee_a");
let caller_names: Vec<String> = calls.iter().map(|c| c.caller.clone()).collect();
assert!(
caller_names.contains(&"caller_function".to_string()),
"Expected caller_function in callers"
);
assert!(
caller_names.contains(&"callee_b".to_string()),
"Expected callee_b in callers"
);
assert!(
caller_names.contains(&"main".to_string()),
"Expected main in callers"
);
for call in &calls {
assert_eq!(call.callee, "callee_a");
assert_eq!(call.file_path.to_str().unwrap(), "src/test.rs");
assert!(call.byte_start < call.byte_end);
}
}
#[test]
fn test_calls_from_symbol_nonexistent() {
let (_temp_dir, db_path) = setup_test_db_with_calls();
let mut backend = MagellanBackend::open(&db_path).unwrap();
let calls = backend
.calls_from_symbol("src/test.rs", "nonexistent_function")
.unwrap();
assert!(calls.is_empty(), "Expected empty calls for non-existent symbol");
}
#[test]
fn test_callers_of_symbol_nonexistent() {
let (_temp_dir, db_path) = setup_test_db_with_calls();
let mut backend = MagellanBackend::open(&db_path).unwrap();
let calls = backend
.callers_of_symbol("src/test.rs", "nonexistent_function")
.unwrap();
assert!(calls.is_empty(), "Expected empty callers for non-existent symbol");
}
#[test]
fn test_calls_from_symbol_empty_file() {
let temp_dir = tempfile::tempdir().unwrap();
let db_path = temp_dir.path().join("test.db");
let mut graph = CodeGraph::open(&db_path).unwrap();
let source = r#"
fn standalone_function() {
let _x = 42;
}
"#;
graph.index_file("src/standalone.rs", source.as_bytes()).unwrap();
let mut backend = MagellanBackend::open(&db_path).unwrap();
let calls = backend
.calls_from_symbol("src/standalone.rs", "standalone_function")
.unwrap();
assert!(calls.is_empty(), "Expected empty calls for standalone function");
}
#[test]
fn test_callers_of_symbol_no_callers() {
let temp_dir = tempfile::tempdir().unwrap();
let db_path = temp_dir.path().join("test.db");
let mut graph = CodeGraph::open(&db_path).unwrap();
let source = r#"
fn uncalled_function() {
let _x = 42;
}
fn main() {
// main doesn't call uncalled_function
}
"#;
graph.index_file("src/uncalled.rs", source.as_bytes()).unwrap();
let mut backend = MagellanBackend::open(&db_path).unwrap();
let calls = backend
.callers_of_symbol("src/uncalled.rs", "uncalled_function")
.unwrap();
assert!(calls.is_empty(), "Expected empty callers for uncalled function");
}
}