use super::DependencyGraph;
use super::TarjanState;
#[test]
fn dependency_graph_empty() {
let graph = DependencyGraph::from_adjacency(std::collections::HashMap::new());
let sorted = graph.sort_leaves_first();
assert!(sorted.is_empty());
}
#[test]
fn dependency_graph_single_node() {
let mut adjacency = std::collections::HashMap::new();
adjacency.insert("a".to_string(), vec![]);
let graph = DependencyGraph::from_adjacency(adjacency);
let sorted = graph.sort_leaves_first();
assert_eq!(sorted, vec!["a"]);
}
#[test]
fn dependency_graph_linear_chain() {
let mut adjacency = std::collections::HashMap::new();
adjacency.insert("a".to_string(), vec!["b".to_string()]);
adjacency.insert("b".to_string(), vec!["c".to_string()]);
adjacency.insert("c".to_string(), vec![]);
let graph = DependencyGraph::from_adjacency(adjacency);
let leaves_first = graph.sort_leaves_first();
assert_eq!(leaves_first, vec!["c", "b", "a"]);
let roots_first = graph.sort_roots_first();
assert_eq!(roots_first, vec!["a", "b", "c"]);
}
#[test]
fn dependency_graph_diamond() {
let mut adjacency = std::collections::HashMap::new();
adjacency.insert("a".to_string(), vec!["b".to_string(), "c".to_string()]);
adjacency.insert("b".to_string(), vec!["d".to_string()]);
adjacency.insert("c".to_string(), vec!["d".to_string()]);
adjacency.insert("d".to_string(), vec![]);
let graph = DependencyGraph::from_adjacency(adjacency);
let leaves_first = graph.sort_leaves_first();
assert_eq!(leaves_first[0], "d");
assert_eq!(leaves_first[3], "a");
assert!(leaves_first[1..3].contains(&"b".to_string()));
assert!(leaves_first[1..3].contains(&"c".to_string()));
let roots_first = graph.sort_roots_first();
assert_eq!(roots_first[0], "a");
assert_eq!(roots_first[3], "d");
assert!(roots_first[1..3].contains(&"b".to_string()));
assert!(roots_first[1..3].contains(&"c".to_string()));
}
#[test]
fn dependency_graph_simple_dependency() {
let mut adjacency = std::collections::HashMap::new();
adjacency.insert("a".to_string(), vec!["b".to_string()]);
adjacency.insert("b".to_string(), vec![]);
let graph = DependencyGraph::from_adjacency(adjacency);
let leaves_first = graph.sort_leaves_first();
assert_eq!(leaves_first, vec!["b", "a"]);
let roots_first = graph.sort_roots_first();
assert_eq!(roots_first, vec!["a", "b"]);
}
#[test]
fn dependency_graph_cycle_succeeds_with_correct_ordering() {
let mut adjacency = std::collections::HashMap::new();
adjacency.insert("a".to_string(), vec!["b".to_string()]);
adjacency.insert("b".to_string(), vec!["c".to_string()]);
adjacency.insert("c".to_string(), vec!["a".to_string()]);
let graph = DependencyGraph::from_adjacency(adjacency);
let sorted = graph.sort_leaves_first();
assert_eq!(sorted.len(), 3);
assert!(sorted.contains(&"a".to_string()));
assert!(sorted.contains(&"b".to_string()));
assert!(sorted.contains(&"c".to_string()));
}
#[test]
fn dependency_graph_self_loop() {
let mut adjacency = std::collections::HashMap::new();
adjacency.insert("a".to_string(), vec!["a".to_string()]);
let graph = DependencyGraph::from_adjacency(adjacency);
let sorted = graph.sort_leaves_first();
assert_eq!(sorted, vec!["a"]);
let cycles = graph.cycle_groups();
assert!(cycles.is_empty());
}
#[test]
fn dependency_graph_self_loop_alongside_multi_node_cycle() {
let mut adjacency = std::collections::HashMap::new();
adjacency.insert("a".to_string(), vec!["a".to_string()]);
adjacency.insert("b".to_string(), vec!["c".to_string()]);
adjacency.insert("c".to_string(), vec!["b".to_string()]);
let graph = DependencyGraph::from_adjacency(adjacency);
let cycles = graph.cycle_groups();
assert_eq!(cycles.len(), 1);
assert_eq!(cycles[0], vec!["b", "c"]);
}
#[test]
fn dependency_graph_two_node_cycle() {
let mut adjacency = std::collections::HashMap::new();
adjacency.insert("a".to_string(), vec!["b".to_string()]);
adjacency.insert("b".to_string(), vec!["a".to_string()]);
let graph = DependencyGraph::from_adjacency(adjacency);
let sorted = graph.sort_leaves_first();
assert_eq!(sorted.len(), 2);
assert_eq!(sorted, vec!["a", "b"]);
let cycles = graph.cycle_groups();
assert_eq!(cycles.len(), 1);
assert_eq!(cycles[0], vec!["a", "b"]);
}
#[test]
fn dependency_graph_partial_cycle_plus_dag() {
let mut adjacency = std::collections::HashMap::new();
adjacency.insert("a".to_string(), vec!["b".to_string()]);
adjacency.insert("b".to_string(), vec!["c".to_string()]);
adjacency.insert("c".to_string(), vec!["b".to_string(), "d".to_string()]);
adjacency.insert("d".to_string(), vec![]);
let graph = DependencyGraph::from_adjacency(adjacency);
let sorted = graph.sort_leaves_first();
assert_eq!(sorted[0], "d");
assert_eq!(sorted[3], "a");
let bc_slice = &sorted[1..3];
assert_eq!(bc_slice, &["b", "c"]);
let cycles = graph.cycle_groups();
assert_eq!(cycles.len(), 1);
assert_eq!(cycles[0], vec!["b", "c"]);
}
#[test]
fn dependency_graph_multiple_independent_cycles() {
let mut adjacency = std::collections::HashMap::new();
adjacency.insert("a".to_string(), vec!["b".to_string()]);
adjacency.insert("b".to_string(), vec!["a".to_string()]);
adjacency.insert("c".to_string(), vec!["d".to_string()]);
adjacency.insert("d".to_string(), vec!["c".to_string()]);
let graph = DependencyGraph::from_adjacency(adjacency);
let sorted = graph.sort_leaves_first();
assert_eq!(sorted.len(), 4);
let cycles = graph.cycle_groups();
assert_eq!(cycles.len(), 2);
let ab_cycle = cycles.iter().find(|c| c.contains(&"a".to_string()));
let cd_cycle = cycles.iter().find(|c| c.contains(&"c".to_string()));
assert!(ab_cycle.is_some());
assert!(cd_cycle.is_some());
assert_eq!(ab_cycle.unwrap(), &vec!["a", "b"]);
assert_eq!(cd_cycle.unwrap(), &vec!["c", "d"]);
}
#[test]
fn dependency_graph_diamond_with_cycle() {
let mut adjacency = std::collections::HashMap::new();
adjacency.insert("a".to_string(), vec!["b".to_string(), "c".to_string()]);
adjacency.insert("b".to_string(), vec!["c".to_string()]);
adjacency.insert("c".to_string(), vec!["b".to_string()]);
let graph = DependencyGraph::from_adjacency(adjacency);
let sorted = graph.sort_leaves_first();
assert_eq!(sorted.len(), 3);
assert_eq!(sorted[0], "b");
assert_eq!(sorted[1], "c");
assert_eq!(sorted[2], "a");
let cycles = graph.cycle_groups();
assert_eq!(cycles.len(), 1);
assert_eq!(cycles[0], vec!["b", "c"]);
}
#[test]
fn cycle_groups_empty_for_dag() {
let mut adjacency = std::collections::HashMap::new();
adjacency.insert("a".to_string(), vec!["b".to_string()]);
adjacency.insert("b".to_string(), vec!["c".to_string()]);
adjacency.insert("c".to_string(), vec![]);
let graph = DependencyGraph::from_adjacency(adjacency);
let cycles = graph.cycle_groups();
assert!(cycles.is_empty());
}
#[test]
fn dependency_graph_sorting_is_deterministic() {
let mut adjacency = std::collections::HashMap::new();
adjacency.insert("c".to_string(), vec!["a".to_string()]);
adjacency.insert("a".to_string(), vec!["b".to_string()]);
adjacency.insert("b".to_string(), vec!["c".to_string()]);
let graph = DependencyGraph::from_adjacency(adjacency);
let first = graph.sort_leaves_first();
for _ in 0..10 {
let result = graph.sort_leaves_first();
assert_eq!(result, first, "Sorting should be deterministic");
}
assert_eq!(first, vec!["a", "b", "c"]);
}
#[test]
fn dependency_graph_consistent_results() {
let mut adjacency = std::collections::HashMap::new();
adjacency.insert("a".to_string(), vec!["b".to_string()]);
adjacency.insert("b".to_string(), vec!["a".to_string()]);
adjacency.insert("c".to_string(), vec!["d".to_string()]);
adjacency.insert("d".to_string(), vec![]);
let graph = DependencyGraph::from_adjacency(adjacency);
let sorted1 = graph.sort_leaves_first();
let cycles = graph.cycle_groups();
let sorted2 = graph.sort_leaves_first();
assert_eq!(sorted1, sorted2);
assert_eq!(cycles.len(), 1);
assert_eq!(cycles[0], vec!["a", "b"]);
assert!(sorted1.contains(&"d".to_string()));
assert!(sorted1.contains(&"a".to_string()));
assert!(sorted1.contains(&"b".to_string()));
assert!(sorted1.contains(&"c".to_string()));
}
#[test]
fn dependency_graph_clone_returns_same_results() {
let mut adjacency = std::collections::HashMap::new();
adjacency.insert("a".to_string(), vec!["b".to_string()]);
adjacency.insert("b".to_string(), vec![]);
let graph = DependencyGraph::from_adjacency(adjacency);
let cloned = graph.clone();
assert_eq!(graph.sort_leaves_first(), cloned.sort_leaves_first());
}
#[test]
fn dependency_graph_with_external_dependencies() {
let mut adjacency = std::collections::HashMap::new();
adjacency.insert(
"app".to_string(),
vec![
"lib".to_string(),
"external-dep".to_string(), ],
);
adjacency.insert("lib".to_string(), vec!["react".to_string()]);
let graph = DependencyGraph::from_adjacency(adjacency);
let sorted = graph.sort_leaves_first();
assert_eq!(sorted.len(), 2);
assert!(sorted.contains(&"app".to_string()));
assert!(sorted.contains(&"lib".to_string()));
assert!(!sorted.contains(&"external-dep".to_string()));
assert!(!sorted.contains(&"react".to_string()));
let lib_idx = sorted.iter().position(|n| n == "lib").unwrap();
let app_idx = sorted.iter().position(|n| n == "app").unwrap();
assert!(lib_idx < app_idx);
}
#[test]
fn dependency_graph_cross_edges_between_sccs() {
let mut adjacency = std::collections::HashMap::new();
adjacency.insert("a".to_string(), vec!["b".to_string(), "c".to_string()]);
adjacency.insert("b".to_string(), vec!["a".to_string()]);
adjacency.insert("c".to_string(), vec!["d".to_string()]);
adjacency.insert("d".to_string(), vec!["c".to_string()]);
let graph = DependencyGraph::from_adjacency(adjacency);
let sorted = graph.sort_leaves_first();
let c_idx = sorted.iter().position(|n| n == "c").unwrap();
let d_idx = sorted.iter().position(|n| n == "d").unwrap();
let a_idx = sorted.iter().position(|n| n == "a").unwrap();
let b_idx = sorted.iter().position(|n| n == "b").unwrap();
assert!(c_idx < a_idx && c_idx < b_idx);
assert!(d_idx < a_idx && d_idx < b_idx);
let cycles = graph.cycle_groups();
assert_eq!(cycles.len(), 2);
}
#[test]
fn dependency_graph_node_with_no_dependencies() {
let mut adjacency = std::collections::HashMap::new();
adjacency.insert("standalone".to_string(), vec![]);
adjacency.insert("app".to_string(), vec!["standalone".to_string()]);
let graph = DependencyGraph::from_adjacency(adjacency);
let sorted = graph.sort_leaves_first();
assert_eq!(sorted[0], "standalone");
assert_eq!(sorted[1], "app");
let cycles = graph.cycle_groups();
assert!(cycles.is_empty());
}
#[test]
fn dependency_graph_complex_mixed_structure() {
let mut adjacency = std::collections::HashMap::new();
adjacency.insert("a".to_string(), vec!["b".to_string(), "f".to_string()]);
adjacency.insert("b".to_string(), vec!["a".to_string()]);
adjacency.insert("e".to_string(), vec!["f".to_string()]);
adjacency.insert("f".to_string(), vec!["g".to_string()]);
adjacency.insert("g".to_string(), vec![]);
let graph = DependencyGraph::from_adjacency(adjacency);
let sorted = graph.sort_leaves_first();
assert_eq!(sorted[0], "g");
let g_idx = sorted.iter().position(|n| n == "g").unwrap();
let f_idx = sorted.iter().position(|n| n == "f").unwrap();
let a_idx = sorted.iter().position(|n| n == "a").unwrap();
let b_idx = sorted.iter().position(|n| n == "b").unwrap();
let e_idx = sorted.iter().position(|n| n == "e").unwrap();
assert!(g_idx < f_idx);
assert!(f_idx < a_idx);
assert!(f_idx < b_idx);
assert!(f_idx < e_idx);
let cycles = graph.cycle_groups();
assert_eq!(cycles.len(), 1);
assert_eq!(cycles[0], vec!["a", "b"]);
}
#[test]
fn dependency_graph_back_edge_to_ancestor() {
let mut adjacency = std::collections::HashMap::new();
adjacency.insert("a".to_string(), vec!["b".to_string()]);
adjacency.insert("b".to_string(), vec!["c".to_string()]);
adjacency.insert("c".to_string(), vec!["a".to_string()]);
let graph = DependencyGraph::from_adjacency(adjacency);
let sorted = graph.sort_leaves_first();
assert_eq!(sorted, vec!["a", "b", "c"]);
let cycles = graph.cycle_groups();
assert_eq!(cycles.len(), 1);
assert_eq!(cycles[0], vec!["a", "b", "c"]);
}
#[test]
fn dependency_graph_shared_dependency() {
let mut adjacency = std::collections::HashMap::new();
adjacency.insert("a".to_string(), vec!["c".to_string()]);
adjacency.insert("b".to_string(), vec!["c".to_string()]);
adjacency.insert("c".to_string(), vec![]);
let graph = DependencyGraph::from_adjacency(adjacency);
let sorted = graph.sort_leaves_first();
assert_eq!(sorted[0], "c");
assert!(sorted.contains(&"a".to_string()));
assert!(sorted.contains(&"b".to_string()));
}
#[test]
fn dependency_graph_multiple_back_edges() {
let mut adjacency = std::collections::HashMap::new();
adjacency.insert("a".to_string(), vec!["b".to_string(), "c".to_string()]);
adjacency.insert("b".to_string(), vec!["c".to_string()]);
adjacency.insert("c".to_string(), vec!["a".to_string()]);
let graph = DependencyGraph::from_adjacency(adjacency);
let sorted = graph.sort_leaves_first();
assert_eq!(sorted.len(), 3);
assert_eq!(sorted, vec!["a", "b", "c"]);
let cycles = graph.cycle_groups();
assert_eq!(cycles.len(), 1);
}
#[test]
fn dependency_graph_deep_tree() {
let mut adjacency = std::collections::HashMap::new();
adjacency.insert("a".to_string(), vec!["b".to_string()]);
adjacency.insert("b".to_string(), vec!["c".to_string()]);
adjacency.insert("c".to_string(), vec!["d".to_string()]);
adjacency.insert("d".to_string(), vec!["e".to_string()]);
adjacency.insert("e".to_string(), vec!["f".to_string()]);
adjacency.insert("f".to_string(), vec![]);
let graph = DependencyGraph::from_adjacency(adjacency);
let sorted = graph.sort_leaves_first();
assert_eq!(sorted, vec!["f", "e", "d", "c", "b", "a"]);
let cycles = graph.cycle_groups();
assert!(cycles.is_empty());
}
#[test]
fn dependency_graph_wide_tree() {
let mut adjacency = std::collections::HashMap::new();
adjacency.insert(
"a".to_string(),
vec![
"b".to_string(),
"c".to_string(),
"d".to_string(),
"e".to_string(),
],
);
adjacency.insert("b".to_string(), vec![]);
adjacency.insert("c".to_string(), vec![]);
adjacency.insert("d".to_string(), vec![]);
adjacency.insert("e".to_string(), vec![]);
let graph = DependencyGraph::from_adjacency(adjacency);
let sorted = graph.sort_leaves_first();
let a_idx = sorted.iter().position(|n| n == "a").unwrap();
let b_idx = sorted.iter().position(|n| n == "b").unwrap();
let c_idx = sorted.iter().position(|n| n == "c").unwrap();
let d_idx = sorted.iter().position(|n| n == "d").unwrap();
let e_idx = sorted.iter().position(|n| n == "e").unwrap();
assert!(b_idx < a_idx);
assert!(c_idx < a_idx);
assert!(d_idx < a_idx);
assert!(e_idx < a_idx);
}
#[test]
fn dependency_graph_parallel_chains() {
let mut adjacency = std::collections::HashMap::new();
adjacency.insert("a".to_string(), vec!["b".to_string()]);
adjacency.insert("b".to_string(), vec!["c".to_string()]);
adjacency.insert("c".to_string(), vec![]);
adjacency.insert("d".to_string(), vec!["e".to_string()]);
adjacency.insert("e".to_string(), vec!["f".to_string()]);
adjacency.insert("f".to_string(), vec![]);
let graph = DependencyGraph::from_adjacency(adjacency);
let sorted = graph.sort_leaves_first();
let a_idx = sorted.iter().position(|n| n == "a").unwrap();
let b_idx = sorted.iter().position(|n| n == "b").unwrap();
let c_idx = sorted.iter().position(|n| n == "c").unwrap();
assert!(c_idx < b_idx && b_idx < a_idx);
let d_idx = sorted.iter().position(|n| n == "d").unwrap();
let e_idx = sorted.iter().position(|n| n == "e").unwrap();
let f_idx = sorted.iter().position(|n| n == "f").unwrap();
assert!(f_idx < e_idx && e_idx < d_idx);
}
#[test]
fn strongconnect_handles_missing_node_in_adjacency() {
let adjacency = std::collections::HashMap::new();
let mut state = TarjanState::new();
DependencyGraph::strongconnect(&adjacency, "nonexistent", &mut state);
assert_eq!(state.sccs.len(), 1);
assert_eq!(state.sccs[0], vec!["nonexistent"]);
assert!(state.indices.contains_key("nonexistent"));
assert!(state.lowlinks.contains_key("nonexistent"));
}
#[test]
fn strongconnect_handles_corrupted_lowlinks() {
let mut adjacency = std::collections::HashMap::new();
adjacency.insert("a".to_string(), vec!["b".to_string()]);
adjacency.insert("b".to_string(), vec![]);
let mut state = TarjanState::new();
state.indices.insert("b".to_string(), 99);
state.on_stack.insert("b".to_string());
DependencyGraph::strongconnect(&adjacency, "a", &mut state);
assert!(state.indices.contains_key("a"));
assert!(state.lowlinks.contains_key("a"));
}
#[test]
fn strongconnect_handles_already_visited_node() {
let mut adjacency = std::collections::HashMap::new();
adjacency.insert("a".to_string(), vec!["b".to_string()]);
adjacency.insert("b".to_string(), vec![]);
let mut state = TarjanState::new();
DependencyGraph::strongconnect(&adjacency, "a", &mut state);
let initial_sccs_count = state.sccs.len();
DependencyGraph::strongconnect(&adjacency, "a", &mut state);
assert_eq!(state.sccs.len(), initial_sccs_count);
}
#[test]
fn strongconnect_handles_node_not_on_stack_in_second_visit() {
let mut adjacency = std::collections::HashMap::new();
adjacency.insert("a".to_string(), vec!["b".to_string(), "c".to_string()]);
adjacency.insert("b".to_string(), vec![]);
adjacency.insert("c".to_string(), vec![]);
let mut state = TarjanState::new();
DependencyGraph::strongconnect(&adjacency, "a", &mut state);
assert!(!state.sccs.is_empty());
}
#[test]
fn strongconnect_handles_lowlink_not_improving() {
let mut adjacency = std::collections::HashMap::new();
adjacency.insert("a".to_string(), vec!["b".to_string()]);
adjacency.insert("b".to_string(), vec!["c".to_string()]);
adjacency.insert("c".to_string(), vec!["b".to_string()]);
let mut state = TarjanState::new();
DependencyGraph::strongconnect(&adjacency, "a", &mut state);
assert!(!state.sccs.is_empty());
}
#[test]
fn strongconnect_with_self_referencing_external_dep() {
let mut adjacency = std::collections::HashMap::new();
adjacency.insert(
"a".to_string(),
vec![
"a".to_string(), "external".to_string(), ],
);
let mut state = TarjanState::new();
DependencyGraph::strongconnect(&adjacency, "a", &mut state);
assert_eq!(state.sccs.len(), 1);
assert_eq!(state.sccs[0], vec!["a"]);
assert!(!state.indices.contains_key("external"));
assert!(!state.sccs[0].contains(&"external".to_string()));
}
#[test]
fn dependency_graph_multiple_roots() {
let mut adjacency = std::collections::HashMap::new();
adjacency.insert("a".to_string(), vec!["c".to_string()]);
adjacency.insert("b".to_string(), vec!["c".to_string()]);
adjacency.insert("c".to_string(), vec![]);
let graph = DependencyGraph::from_adjacency(adjacency);
let leaves_first = graph.sort_leaves_first();
assert_eq!(leaves_first[0], "c");
assert!(leaves_first[1..3].contains(&"a".to_string()));
assert!(leaves_first[1..3].contains(&"b".to_string()));
let roots_first = graph.sort_roots_first();
assert_eq!(roots_first[2], "c");
assert!(roots_first[0..2].contains(&"a".to_string()));
assert!(roots_first[0..2].contains(&"b".to_string()));
}
#[test]
fn dependency_graph_disconnected_subgraphs() {
let mut adjacency = std::collections::HashMap::new();
adjacency.insert("a".to_string(), vec!["b".to_string()]);
adjacency.insert("b".to_string(), vec![]);
adjacency.insert("c".to_string(), vec!["d".to_string()]);
adjacency.insert("d".to_string(), vec![]);
let graph = DependencyGraph::from_adjacency(adjacency);
let leaves_first = graph.sort_leaves_first();
let b_index = leaves_first.iter().position(|n| n == "b").unwrap();
let a_index = leaves_first.iter().position(|n| n == "a").unwrap();
let d_index = leaves_first.iter().position(|n| n == "d").unwrap();
let c_index = leaves_first.iter().position(|n| n == "c").unwrap();
assert!(b_index < a_index, "b should come before a");
assert!(d_index < c_index, "d should come before c");
let roots_first = graph.sort_roots_first();
let a_index = roots_first.iter().position(|n| n == "a").unwrap();
let b_index = roots_first.iter().position(|n| n == "b").unwrap();
let c_index = roots_first.iter().position(|n| n == "c").unwrap();
let d_index = roots_first.iter().position(|n| n == "d").unwrap();
assert!(a_index < b_index, "a should come before b");
assert!(c_index < d_index, "c should come before d");
let mut reversed_leaves = leaves_first.clone();
reversed_leaves.reverse();
assert_eq!(roots_first, reversed_leaves);
}
#[test]
fn direct_dependents_leaf_node_has_no_dependents() {
let mut adjacency = std::collections::HashMap::new();
adjacency.insert("a".to_string(), vec!["b".to_string()]);
adjacency.insert("b".to_string(), vec!["c".to_string()]);
adjacency.insert("c".to_string(), vec![]);
let graph = DependencyGraph::from_adjacency(adjacency);
let dependents = graph.direct_dependents("a");
assert!(dependents.is_empty(), "root node should have no dependents");
let dependents_c = graph.direct_dependents("c");
assert_eq!(dependents_c, vec!["b"], "b depends on c");
}
#[test]
fn direct_dependents_mid_graph_node() {
let mut adjacency = std::collections::HashMap::new();
adjacency.insert("a".to_string(), vec!["b".to_string()]);
adjacency.insert("c".to_string(), vec!["b".to_string()]);
adjacency.insert("b".to_string(), vec![]);
let graph = DependencyGraph::from_adjacency(adjacency);
let mut dependents = graph.direct_dependents("b");
dependents.sort();
assert_eq!(dependents, vec!["a", "c"]);
}
#[test]
fn direct_dependents_absent_node_returns_empty() {
let mut adjacency = std::collections::HashMap::new();
adjacency.insert("a".to_string(), vec!["b".to_string()]);
adjacency.insert("b".to_string(), vec![]);
let graph = DependencyGraph::from_adjacency(adjacency);
let dependents = graph.direct_dependents("nonexistent");
assert!(dependents.is_empty());
}