#[test]
fn test_topo_tree() {
let g = Graph::from_edges(&[(0, 1), (0, 2), (1, 3), (1, 4)], true);
let order = g.topological_sort().expect("Tree is a DAG");
assert_eq!(order.len(), 5);
assert_eq!(order.iter().position(|&x| x == 0), Some(0));
let pos_1 = order
.iter()
.position(|&x| x == 1)
.expect("1 should be in order");
assert!(
pos_1
< order
.iter()
.position(|&x| x == 3)
.expect("3 should be in order")
);
assert!(
pos_1
< order
.iter()
.position(|&x| x == 4)
.expect("4 should be in order")
);
}
#[test]
fn test_topo_self_loop() {
let g = Graph::from_edges(&[(0, 0)], true);
assert!(g.topological_sort().is_none());
}
#[test]
fn test_topo_complete_dag() {
let g = Graph::from_edges(&[(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3)], true);
let order = g
.topological_sort()
.expect("Complete DAG has topological order");
assert_eq!(order.len(), 4);
let positions: Vec<_> = (0..4)
.map(|i| {
order
.iter()
.position(|&x| x == i)
.expect("node should be in order")
})
.collect();
assert!(positions[0] < positions[1]);
assert!(positions[0] < positions[2]);
assert!(positions[0] < positions[3]);
assert!(positions[1] < positions[2]);
assert!(positions[1] < positions[3]);
assert!(positions[2] < positions[3]);
}
#[test]
fn test_topo_undirected() {
let g = Graph::from_edges(&[(0, 1), (1, 2)], false);
assert!(g.topological_sort().is_none());
}
#[test]
fn test_common_neighbors_triangle() {
let g = Graph::from_edges(&[(0, 1), (0, 2), (1, 2)], false);
assert_eq!(g.common_neighbors(1, 2), Some(1));
assert_eq!(g.common_neighbors(0, 1), Some(1));
assert_eq!(g.common_neighbors(0, 2), Some(1));
}
#[test]
fn test_common_neighbors_no_overlap() {
let g = Graph::from_edges(&[(0, 1), (0, 2), (3, 4), (3, 5)], false);
assert_eq!(g.common_neighbors(1, 2), Some(1));
assert_eq!(g.common_neighbors(1, 4), Some(0));
assert_eq!(g.common_neighbors(0, 3), Some(0));
}
#[test]
fn test_common_neighbors_complete() {
let g = Graph::from_edges(&[(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3)], false);
assert_eq!(g.common_neighbors(0, 1), Some(2)); assert_eq!(g.common_neighbors(0, 2), Some(2)); assert_eq!(g.common_neighbors(1, 2), Some(2)); }
#[test]
fn test_common_neighbors_directed() {
let g = Graph::from_edges(&[(0, 1), (0, 2), (1, 2)], true);
assert_eq!(g.common_neighbors(0, 1), Some(1)); }
#[test]
fn test_common_neighbors_invalid() {
let g = Graph::from_edges(&[(0, 1), (1, 2)], false);
assert!(g.common_neighbors(0, 10).is_none());
assert!(g.common_neighbors(10, 0).is_none());
assert!(g.common_neighbors(10, 20).is_none());
}
#[test]
fn test_common_neighbors_self() {
let g = Graph::from_edges(&[(0, 1), (0, 2), (1, 2)], false);
assert_eq!(g.common_neighbors(0, 0), Some(2)); }
#[test]
fn test_common_neighbors_empty() {
let g = Graph::new(false);
assert!(g.common_neighbors(0, 1).is_none());
}
#[test]
fn test_common_neighbors_star() {
let g = Graph::from_edges(&[(0, 1), (0, 2), (0, 3), (0, 4)], false);
assert_eq!(g.common_neighbors(1, 2), Some(1)); assert_eq!(g.common_neighbors(1, 3), Some(1)); assert_eq!(g.common_neighbors(2, 4), Some(1)); }
#[test]
fn test_adamic_adar_triangle() {
let g = Graph::from_edges(&[(0, 1), (0, 2), (1, 2)], false);
let aa = g.adamic_adar_index(1, 2).expect("valid nodes");
assert!((aa - 1.0 / 2.0_f64.ln()).abs() < 1e-10);
}
#[test]
fn test_adamic_adar_no_common() {
let g = Graph::from_edges(&[(0, 1), (2, 3)], false);
assert_eq!(g.adamic_adar_index(0, 2).expect("valid nodes"), 0.0);
assert_eq!(g.adamic_adar_index(1, 3).expect("valid nodes"), 0.0);
}
#[test]
fn test_adamic_adar_star() {
let g = Graph::from_edges(&[(0, 1), (0, 2), (0, 3), (0, 4)], false);
let aa = g.adamic_adar_index(1, 2).expect("valid nodes");
assert!((aa - 1.0 / 4.0_f64.ln()).abs() < 1e-10);
}
#[test]
fn test_adamic_adar_multiple_common() {
let g = Graph::from_edges(&[(0, 2), (0, 3), (0, 4), (1, 2), (1, 3), (1, 4)], false);
let aa = g.adamic_adar_index(0, 1).expect("valid nodes");
let expected = 3.0 / 2.0_f64.ln();
assert!((aa - expected).abs() < 1e-10);
}
#[test]
fn test_adamic_adar_degree_one() {
let g = Graph::from_edges(&[(0, 1), (1, 2)], false);
let aa = g.adamic_adar_index(0, 2).expect("valid nodes");
assert!((aa - 1.0 / 2.0_f64.ln()).abs() < 1e-10);
}
#[test]
fn test_adamic_adar_invalid() {
let g = Graph::from_edges(&[(0, 1), (1, 2)], false);
assert!(g.adamic_adar_index(0, 10).is_none());
assert!(g.adamic_adar_index(10, 0).is_none());
}
#[test]
fn test_adamic_adar_directed() {
let g = Graph::from_edges(&[(0, 2), (1, 2), (2, 3)], true);
let aa = g.adamic_adar_index(0, 1).expect("valid nodes");
assert!(aa >= 0.0);
}
#[test]
fn test_adamic_adar_empty() {
let g = Graph::new(false);
assert!(g.adamic_adar_index(0, 1).is_none());
}
#[test]
fn test_label_propagation_two_triangles() {
let g = Graph::from_edges(
&[(0, 1), (1, 2), (2, 0), (3, 4), (4, 5), (5, 3), (2, 3)],
false,
);
let communities = g.label_propagation(100, Some(42));
assert_eq!(communities.len(), 6);
use std::collections::HashSet;
let unique: HashSet<_> = communities.iter().copied().collect();
assert!(!unique.is_empty() && unique.len() <= 6);
}
#[test]
fn test_label_propagation_complete_graph() {
let g = Graph::from_edges(&[(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3)], false);
let communities = g.label_propagation(100, Some(42));
assert_eq!(communities.len(), 4);
let first_label = communities[0];
assert!(communities.iter().all(|&c| c == first_label));
}
#[test]
fn test_label_propagation_disconnected() {
let g = Graph::from_edges(&[(0, 1), (1, 2), (2, 0), (3, 4), (4, 5), (5, 3)], false);
let communities = g.label_propagation(100, Some(42));
assert_eq!(communities.len(), 6);
assert_eq!(communities[0], communities[1]);
assert_eq!(communities[1], communities[2]);
assert_eq!(communities[3], communities[4]);
assert_eq!(communities[4], communities[5]);
assert_ne!(communities[0], communities[3]);
}
#[test]
fn test_label_propagation_star() {
let g = Graph::from_edges(&[(0, 1), (0, 2), (0, 3), (0, 4)], false);
let communities = g.label_propagation(100, Some(42));
assert_eq!(communities.len(), 5);
use std::collections::HashSet;
let unique: HashSet<_> = communities.iter().copied().collect();
assert_eq!(unique.len(), 1);
}
#[test]
fn test_label_propagation_linear() {
let g = Graph::from_edges(&[(0, 1), (1, 2), (2, 3), (3, 4)], false);
let communities = g.label_propagation(100, Some(42));
assert_eq!(communities.len(), 5);
use std::collections::HashSet;
let unique: HashSet<_> = communities.iter().copied().collect();
assert!(!unique.is_empty() && unique.len() <= 5);
}
#[test]
fn test_label_propagation_empty() {
let g = Graph::new(false);
let communities = g.label_propagation(100, Some(42));
assert!(communities.is_empty());
}
#[test]
fn test_label_propagation_single_node() {
let g = Graph::from_edges(&[(0, 0)], false);
let communities = g.label_propagation(100, Some(42));
assert_eq!(communities.len(), 1);
assert_eq!(communities[0], 0); }
#[test]
fn test_label_propagation_convergence() {
let g = Graph::from_edges(&[(0, 1), (1, 2), (2, 0)], false);
let communities = g.label_propagation(100, Some(42));
assert_eq!(communities.len(), 3);
assert_eq!(communities[0], communities[1]);
assert_eq!(communities[1], communities[2]);
}
#[test]
fn test_label_propagation_directed() {
let g = Graph::from_edges(&[(0, 1), (1, 0), (1, 2), (2, 1), (0, 2), (2, 0)], true);
let communities = g.label_propagation(100, Some(42));
assert_eq!(communities.len(), 3);
assert_eq!(communities[0], communities[1]);
assert_eq!(communities[1], communities[2]);
}
#[test]
fn test_label_propagation_barbell() {
let g = Graph::from_edges(
&[(0, 1), (0, 2), (1, 2), (3, 4), (3, 5), (4, 5), (2, 3)],
false,
);
let communities = g.label_propagation(100, Some(42));
assert_eq!(communities.len(), 6);
use std::collections::HashSet;
let unique: HashSet<_> = communities.iter().copied().collect();
assert!(!unique.is_empty() && unique.len() <= 3);
}