use debtmap::priority::call_graph::{CallGraph, CallType, FunctionCall, FunctionId};
use std::path::PathBuf;
#[test]
fn test_resolve_cross_file_method_calls() {
let mut call_graph = CallGraph::new();
let store_func = FunctionId::new(
PathBuf::from("src/expansion/cache.rs"),
"store".to_string(),
126,
);
call_graph.add_function(store_func.clone(), false, false, 3, 36);
let expand_func = FunctionId::new(
PathBuf::from("src/expansion/expander.rs"),
"expand_file".to_string(),
200,
);
call_graph.add_function(expand_func.clone(), false, false, 5, 50);
let unresolved_store = FunctionId::new(
PathBuf::from("src/expansion/expander.rs"),
"store".to_string(),
0,
);
call_graph.add_call(FunctionCall {
caller: expand_func.clone(),
callee: unresolved_store.clone(),
call_type: CallType::Direct,
});
assert_eq!(
call_graph.get_callers(&store_func).len(),
0,
"Before resolution, store should have no callers"
);
call_graph.resolve_cross_file_calls();
assert_eq!(
call_graph.get_callers(&store_func).len(),
1,
"After resolution, store should have one caller"
);
let callers = call_graph.get_callers(&store_func);
assert_eq!(callers[0], expand_func);
}
#[test]
fn test_resolve_handles_multiple_candidates() {
let mut call_graph = CallGraph::new();
let process1 = FunctionId::new(PathBuf::from("src/module1.rs"), "process".to_string(), 10);
call_graph.add_function(process1.clone(), false, false, 2, 20);
let process2 = FunctionId::new(PathBuf::from("src/module2.rs"), "process".to_string(), 15);
call_graph.add_function(process2.clone(), false, false, 3, 25);
let main_func = FunctionId::new(PathBuf::from("src/main.rs"), "main".to_string(), 5);
call_graph.add_function(main_func.clone(), true, false, 1, 10);
let unresolved_process =
FunctionId::new(PathBuf::from("src/main.rs"), "process".to_string(), 0);
call_graph.add_call(FunctionCall {
caller: main_func.clone(),
callee: unresolved_process.clone(),
call_type: CallType::Direct,
});
call_graph.resolve_cross_file_calls();
assert_eq!(
call_graph.get_callers(&process1).len(),
0,
"process1 should have no callers when ambiguous"
);
assert_eq!(
call_graph.get_callers(&process2).len(),
0,
"process2 should have no callers when ambiguous"
);
}
#[test]
fn test_resolve_preserves_resolved_calls() {
let mut call_graph = CallGraph::new();
let func_a = FunctionId::new(PathBuf::from("src/a.rs"), "func_a".to_string(), 10);
call_graph.add_function(func_a.clone(), false, false, 2, 20);
let func_b = FunctionId::new(PathBuf::from("src/b.rs"), "func_b".to_string(), 15);
call_graph.add_function(func_b.clone(), false, false, 3, 25);
call_graph.add_call(FunctionCall {
caller: func_a.clone(),
callee: func_b.clone(),
call_type: CallType::Direct,
});
assert_eq!(call_graph.get_callers(&func_b).len(), 1);
call_graph.resolve_cross_file_calls();
assert_eq!(
call_graph.get_callers(&func_b).len(),
1,
"Already resolved calls should be preserved"
);
}