callGraph测试模块
初始化一个新的
CallGraph
实例。填充预定义的函数到
call_graph.defined_fns
。创建一个模拟调用关系的
calls
向量。创建一个表示每个函数的调用者的
callers
哈希映射。遍历
calls
向量,并使用add_call
方法将它们添加到call_graph
。创建预期的闭包(transitive closure)哈希映射
closure
。调用
call_graph.compute_closure()
计算闭包。使用断言检查
call_graph
的闭包与预期闭包是否匹配,以及call_graph
的调用者与预期调用者是否匹配。
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn call_graph_test() {
let mut call_graph = CallGraph::new();
call_graph.defined_fns.extend(
vec!["::e", "::f", "::g"]
.into_iter()
.map(|f| (Name::from(f), Name::from(f))),
);
let calls = vec![
("::f", "::g"),
("::g", "::h"),
("::i", "::h"),
("::g", "::j"),
("::e", "::j"),
("::j", "::e"),
("::g", "::g"),
]
.into_iter()
.map(|(f, g)| (Name::from(f), Name::from(g)))
.collect::<Vec<(Name, Name)>>();
let callers = vec![
("::e", vec!["::j"]),
("::f", vec![]),
("::g", vec!["::f", "::g"]),
("::i", vec![]),
("::h", vec!["::g", "::i"]),
("::j", vec!["::e", "::g"]),
]
.into_iter()
.map(|(f, gs)| {
(
Name::from(f),
gs.into_iter().map(|g| Name::from(g)).collect(),
)
})
.collect::<HashMap<Name, HashSet<Name>>>();
for (f, g) in calls.into_iter() {
call_graph.add_call(f, g, false);
}
let closure: HashMap<Name, HashSet<Name>> = vec![
("::f", vec!["::g", "::h", "::j", "::e"]),
("::g", vec!["::g", "::h", "::j", "::e"]),
("::h", vec![]),
("::i", vec!["::h"]),
("::e", vec!["::j", "::e"]),
("::j", vec!["::j", "::e"]),
]
.into_iter()
.map(|(f, gs)| {
(
Name::from(f),
gs.into_iter()
.map(|g| Name::from(g))
.collect::<HashSet<Name>>(),
)
})
.collect();
call_graph.compute_closure();
assert_eq!(call_graph.closure().unwrap(), &closure);
assert_eq!(call_graph.callers(), &callers);
}
}