callGraph测试模块

·

1 min read

  1. 初始化一个新的 CallGraph 实例。

  2. 填充预定义的函数到 call_graph.defined_fns

  3. 创建一个模拟调用关系的 calls 向量。

  4. 创建一个表示每个函数的调用者的 callers 哈希映射。

  5. 遍历 calls 向量,并使用 add_call 方法将它们添加到 call_graph

  6. 创建预期的闭包(transitive closure)哈希映射 closure

  7. 调用 call_graph.compute_closure() 计算闭包。

  8. 使用断言检查 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);
    }
}