Files
grapherity/src/testing/graph_topology_testing.rs
T

1020 lines
36 KiB
Rust

#[cfg(test)]
#[macro_export]
macro_rules! graph_topology_test_fixtures {
($T:ty) => {
fn make_test_graph() -> (
$T,
[<$T as $crate::traits::GraphTopology>::Vertex; 10],
[<$T as $crate::traits::GraphTopology>::Edge; 18],
[Vec<(
<$T as $crate::traits::GraphTopology>::Vertex,
<$T as $crate::traits::GraphTopology>::Edge,
)>; 10],
) {
let mut graph = <$T>::new();
let vertices: [<$T as $crate::traits::GraphTopology>::Vertex; 10] =
core::array::from_fn(|_| graph.add_vertex());
let edges = [
graph.add_edge(vertices[0], vertices[1]),
graph.add_edge(vertices[0], vertices[1]),
graph.add_edge(vertices[1], vertices[2]),
graph.add_edge(vertices[1], vertices[3]),
graph.add_edge(vertices[1], vertices[4]),
graph.add_edge(vertices[2], vertices[2]),
graph.add_edge(vertices[2], vertices[4]),
graph.add_edge(vertices[2], vertices[4]),
graph.add_edge(vertices[2], vertices[5]),
graph.add_edge(vertices[2], vertices[6]),
graph.add_edge(vertices[3], vertices[6]),
graph.add_edge(vertices[4], vertices[4]),
graph.add_edge(vertices[4], vertices[7]),
graph.add_edge(vertices[4], vertices[8]),
graph.add_edge(vertices[5], vertices[9]),
graph.add_edge(vertices[6], vertices[9]),
graph.add_edge(vertices[7], vertices[8]),
graph.add_edge(vertices[7], vertices[9]),
];
let incidences: [Vec<_>; 10] = [
vec![(vertices[1], edges[0]), (vertices[1], edges[1])],
vec![
(vertices[0], edges[0]),
(vertices[0], edges[1]),
(vertices[2], edges[2]),
(vertices[3], edges[3]),
(vertices[4], edges[4]),
],
vec![
(vertices[2], edges[5]),
(vertices[2], edges[5]),
(vertices[1], edges[2]),
(vertices[4], edges[6]),
(vertices[4], edges[7]),
(vertices[5], edges[8]),
(vertices[6], edges[9]),
],
vec![(vertices[1], edges[3]), (vertices[6], edges[10])],
vec![
(vertices[1], edges[4]),
(vertices[2], edges[6]),
(vertices[2], edges[7]),
(vertices[4], edges[11]),
(vertices[4], edges[11]),
(vertices[7], edges[12]),
(vertices[8], edges[13]),
],
vec![(vertices[2], edges[8]), (vertices[9], edges[14])],
vec![
(vertices[2], edges[9]),
(vertices[3], edges[10]),
(vertices[9], edges[15]),
],
vec![
(vertices[4], edges[12]),
(vertices[8], edges[16]),
(vertices[9], edges[17]),
],
vec![(vertices[4], edges[13]), (vertices[7], edges[16])],
vec![
(vertices[5], edges[14]),
(vertices[6], edges[15]),
(vertices[7], edges[17]),
],
];
(graph, vertices, edges, incidences)
}
};
}
#[cfg(test)]
#[macro_export]
macro_rules! graph_topology_tests {
($T:ty) => {
#[test]
fn add_vertex() {
let mut graph = <$T>::new();
let v = graph.add_vertex();
assert_ne!(graph.add_vertex(), v, "unexpected duplicate vertex");
}
#[test]
fn vertex_count_empty() {
let graph = <$T>::new();
assert_eq!(graph.vertex_count(), 0, "unexpected vertex count");
}
#[test]
fn vertex_count() {
let (graph, _, _, _) = make_test_graph();
assert_eq!(graph.vertex_count(), 10, "unexpected vertex count");
}
#[test]
fn add_edge() {
let mut graph = <$T>::new();
let v1 = graph.add_vertex();
let v2 = graph.add_vertex();
let e = graph.add_edge(v1, v2);
assert_ne!(graph.add_edge(v1, v2), e, "unexpected duplicate edge");
}
#[test]
fn edge_count_empty() {
let graph = <$T>::new();
assert_eq!(graph.edge_count(), 0, "unexpected edge count");
}
#[test]
fn edge_count() {
let (graph, _, _, _) = make_test_graph();
assert_eq!(graph.edge_count(), 18, "unexpected edge count");
}
#[test]
fn degree_zero() {
let mut graph = <$T>::new();
let v = graph.add_vertex();
assert_eq!(graph.degree(v), 0, "unexpected non-zero degree");
}
#[test]
fn degree() {
let (graph, vertices, _, _) = make_test_graph();
let expected_degrees = [2, 5, 7, 2, 7, 2, 3, 3, 2, 3];
for i in 0..graph.vertex_count() {
assert_eq!(
graph.degree(vertices[i]),
expected_degrees[i],
"unexpected degree of {:?}",
vertices[i]
);
}
}
#[test]
fn loop_edge() {
let mut graph = <$T>::new();
let v = graph.add_vertex();
graph.add_edge(v, v);
assert_eq!(graph.vertex_count(), 1, "unexpected vertex count");
assert_eq!(graph.edge_count(), 1, "unexpected edge count");
assert_eq!(graph.degree(v), 2, "unexpected degree");
assert!(
graph.are_adjacent(v, v),
"vertex with loop edge should be adjacent to itself"
);
}
#[test]
fn multiple_edges() {
let k = 3;
let mut graph = <$T>::new();
let v1 = graph.add_vertex();
let v2 = graph.add_vertex();
for _ in 0..k {
graph.add_edge(v1, v2);
}
assert_eq!(graph.vertex_count(), 2, "unexpected vertex count");
assert_eq!(graph.edge_count(), k, "unexpected edge count");
assert_eq!(graph.degree(v1), k, "unexpected degree of vertex {v1:?}");
assert_eq!(graph.degree(v2), k, "unexpected degree of vertex {v2:?}");
assert!(graph.are_adjacent(v1, v2), "should be adjacent");
}
#[test]
fn are_adjacent_vertex_self() {
let mut graph = <$T>::new();
let v = graph.add_vertex();
assert!(
!graph.are_adjacent(v, v),
"should not be adjacent to itself"
);
}
#[test]
fn are_adjacent_single_edge() {
let mut graph = <$T>::new();
let v1 = graph.add_vertex();
let v2 = graph.add_vertex();
assert!(!graph.are_adjacent(v1, v2), "should not be adjacent");
assert!(!graph.are_adjacent(v2, v1), "should not be adjacent");
graph.add_edge(v1, v2);
assert!(graph.are_adjacent(v1, v2), "should be adjacent");
assert!(graph.are_adjacent(v2, v1), "should be adjacent");
}
#[test]
fn are_adjacent() {
let (graph, vertices, _, _) = make_test_graph();
assert!(
graph.are_adjacent(vertices[0], vertices[1]),
"expected {:?} and {:?} to be adjacent",
vertices[0],
vertices[1]
);
assert!(
graph.are_adjacent(vertices[9], vertices[5]),
"expected {:?} and {:?} to be adjacent",
vertices[9],
vertices[5]
);
assert!(
!graph.are_adjacent(vertices[9], vertices[3]),
"unexpected adjacency of {:?} and {:?}",
vertices[9],
vertices[3]
);
for i in 0..graph.vertex_count() {
let exp = match i {
1 | 2 | 4 | 5 | 6 => true,
_ => false,
};
assert_eq!(
graph.are_adjacent(vertices[2], vertices[i]),
exp,
"unexpected adjacency of {:?} and {:?}",
vertices[2],
vertices[i]
);
assert_eq!(
graph.are_adjacent(vertices[i], vertices[2]),
exp,
"unexpected adjacency of {:?} and {:?}",
vertices[i],
vertices[2]
);
}
}
#[test]
fn vertices_empty() {
let graph = <$T>::new();
assert_eq!(
graph.vertices().count(),
0,
"vertex iterator of empty graph should have no elements"
);
}
#[test]
fn vertices() {
let (graph, vertices, _, _) = make_test_graph();
assert_eq!(graph.vertices().count(), 10, "unexpected vertex count");
// Expects each vertex to appear exactly once.
for v in graph.vertices() {
assert_eq!(
vertices.iter().filter(|&x| *x == v).count(),
1,
"unexpected vertex {v:?} from the iterator"
);
}
}
#[test]
fn adjacent_vertices_empty() {
let mut graph = <$T>::new();
let v = graph.add_vertex();
assert_eq!(
graph.adjacent_vertices(v).count(),
0,
"adjacent vertex iterator of vertex with degree 0 should have no elements"
);
}
#[test]
fn adjacent_vertices() {
let (graph, vertices, _, _) = make_test_graph();
// Checks adjacency of vertex 4.
assert_eq!(
graph.adjacent_vertices(vertices[4]).count(),
7,
"unexpected adjacency count"
);
let mut expected_adjacency = vec![
vertices[1],
vertices[2],
vertices[2],
vertices[4],
vertices[4],
vertices[7],
vertices[8],
];
for v in graph.adjacent_vertices(vertices[4]) {
let i = expected_adjacency
.iter()
.position(|w| *w == v)
.expect(&format!(
"unexpected adjacent vertex {v:?} of {:?} from the iterator",
vertices[4]
));
expected_adjacency.swap_remove(i);
}
assert_eq!(
expected_adjacency.len(),
0,
"expected adjacent vertices {:?} of {:?} were not matched by the iterator",
expected_adjacency,
vertices[4]
);
}
#[test]
fn adjacent_vertices_loop_edge() {
let mut graph = <$T>::new();
let v = graph.add_vertex();
graph.add_edge(v, v);
let mut iter = graph.adjacent_vertices(v);
assert_eq!(iter.next(), Some(v), "vertex should be adjacent to itself");
assert_eq!(
iter.next(),
Some(v),
"vertex should be adjacent to itself twice"
);
assert_eq!(
iter.next(),
None,
"too many adjacent vertices from iterator"
);
}
#[test]
fn adjacent_vertices_multiple_edges() {
let k = 3;
let mut graph = <$T>::new();
let vertices = [graph.add_vertex(), graph.add_vertex()];
for _ in 0..k {
graph.add_edge(vertices[0], vertices[1]);
}
for i in 0..2 {
let mut iter = graph.adjacent_vertices(vertices[i]);
for j in 0..k {
assert_eq!(
iter.next(),
Some(vertices[1 - i]),
"unexpected adjacent vertex {j} of vertex {:?}",
vertices[i]
);
}
assert_eq!(
iter.next(),
None,
"too many adjacent vertices of vertex {:?} from iterator",
vertices[i]
);
}
}
#[test]
fn incident_vertices_single_edge() {
let mut graph = <$T>::new();
let v1 = graph.add_vertex();
let v2 = graph.add_vertex();
let e = graph.add_edge(v1, v2);
let (u1, u2) = graph.incident_vertices(e);
assert!(
(u1 == v1 && u2 == v2) || (u1 == v2 && u2 == v1),
"unexpected incident vertices {u1:?} and {u2:?} for edge {e:?}"
);
}
#[test]
fn incident_vertices_loop_edge() {
let mut graph = <$T>::new();
let v = graph.add_vertex();
let e = graph.add_edge(v, v);
assert_eq!(
graph.incident_vertices(e),
(v, v),
"unexpected incident vertices for loop edge {e:?}"
);
}
#[test]
fn incident_vertices_multiple_edges() {
let mut graph = <$T>::new();
let v1 = graph.add_vertex();
let v2 = graph.add_vertex();
let e1 = graph.add_edge(v1, v2);
let e2 = graph.add_edge(v1, v2);
assert_ne!(e1, e2, "edges should be distinct");
let (u1, u2) = graph.incident_vertices(e1);
assert!(
(u1 == v1 && u2 == v2) || (u1 == v2 && u2 == v1),
"unexpected incident vertices {u1:?} and {u2:?} for first multi-edge {e1:?}"
);
let (u1, u2) = graph.incident_vertices(e2);
assert!(
(u1 == v1 && u2 == v2) || (u1 == v2 && u2 == v1),
"unexpected incident vertices {u1:?} and {u2:?} for second multi-edge {e2:?}"
);
}
#[test]
fn incident_vertices() {
let (graph, vertices, edges, _) = make_test_graph();
let expected: [(<$T as $crate::traits::GraphTopology>::Vertex, <$T as $crate::traits::GraphTopology>::Vertex); 18] = [
(vertices[0], vertices[1]),
(vertices[0], vertices[1]),
(vertices[1], vertices[2]),
(vertices[1], vertices[3]),
(vertices[1], vertices[4]),
(vertices[2], vertices[2]),
(vertices[2], vertices[4]),
(vertices[2], vertices[4]),
(vertices[2], vertices[5]),
(vertices[2], vertices[6]),
(vertices[3], vertices[6]),
(vertices[4], vertices[4]),
(vertices[4], vertices[7]),
(vertices[4], vertices[8]),
(vertices[5], vertices[9]),
(vertices[6], vertices[9]),
(vertices[7], vertices[8]),
(vertices[7], vertices[9]),
];
for (i, &(v1, v2)) in expected.iter().enumerate() {
let (u1, u2) = graph.incident_vertices(edges[i]);
assert!(
(u1 == v1 && u2 == v2) || (u1 == v2 && u2 == v1),
"unexpected incident vertices {u1:?} and {u2:?} for edges[{i}]: edge {:?}",
edges[i]
);
}
}
#[test]
fn edges_empty() {
let graph = <$T>::new();
assert_eq!(
graph.edges().count(),
0,
"edge iterator of empty graph should have no elements"
);
}
#[test]
fn edges() {
let (graph, _, edges, _) = make_test_graph();
assert_eq!(graph.edges().count(), 18, "unexpected edge count");
// Expects each edge to appear exactly once.
for e in graph.edges() {
assert_eq!(
edges.iter().filter(|&x| *x == e).count(),
1,
"unexpected edge {e:?} from the iterator"
);
}
}
#[test]
fn incidences_empty() {
let mut graph = <$T>::new();
let v = graph.add_vertex();
assert_eq!(
graph.incidences(v).count(),
0,
"incidence iterator of vertex with degree 0 should have no elements"
);
}
#[test]
fn incidences() {
let (graph, vertices, _, incidences) = make_test_graph();
for i in 0..10 {
assert_eq!(
graph.incidences(vertices[i]).count(),
incidences[i].len(),
"unexpected incidence count for vertex {:?}",
vertices[i]
);
let mut remaining = incidences[i].clone();
for incidence in graph.incidences(vertices[i]) {
let pos = remaining
.iter()
.position(|(v, e)| *v == incidence.0 && *e == incidence.1)
.expect(&format!(
"unexpected incidence {incidence:?} of vertex {:?} from the iterator",
vertices[i]
));
remaining.swap_remove(pos);
}
assert!(
remaining.is_empty(),
"expected incidences {:?} of vertex {:?} were not matched by the iterator",
remaining,
vertices[i]
);
}
}
#[test]
fn incidences_edge_consistency() {
// For each incidence (v, e) of u, the same edge e must appear in the incidences of v.
// For loop edges (u == v), the edge must appear exactly twice in the incidences of u.
let (graph, _, _, _) = make_test_graph();
for u in graph.vertices() {
for (v, e) in graph.incidences(u) {
if u == v {
assert_eq!(
graph.incidences(u).filter(|(_, f)| *f == e).count(),
2,
"loop edge {e:?} should appear exactly twice in incidences of vertex {u:?}"
);
} else {
assert!(
graph.incidences(v).any(|(w, f)| w == u && f == e),
"edge {e:?} from incidences of vertex {u:?} missing in incidences of adjacent vertex {v:?}"
);
}
}
}
}
#[test]
fn incidences_loop_edge() {
let mut graph = <$T>::new();
let v = graph.add_vertex();
let e = graph.add_edge(v, v);
let mut iter = graph.incidences(v);
assert_eq!(
iter.next(),
Some((v, e)),
"vertex should be adjacent to itself"
);
assert_eq!(
iter.next(),
Some((v, e)),
"vertex should be adjacent to itself twice"
);
assert_eq!(
iter.next(),
None,
"too many adjacent vertices from iterator"
);
}
#[test]
fn incidences_multiple_edges() {
let k = 3;
let mut graph = <$T>::new();
let vertices = [graph.add_vertex(), graph.add_vertex()];
let mut edges = Vec::new();
for _ in 0..k {
edges.push(graph.add_edge(vertices[0], vertices[1]));
}
for i in 0..2 {
let mut iter = graph.incidences(vertices[i]);
for j in 0..k {
let current = iter.next().expect(&format!(
"incidence {j} missing, expected {k} incidences for vertex {:?}",
vertices[i]
));
assert_eq!(
current.0,
vertices[1 - i],
"unexpected adjacent vertex of vertex {:?} in incidence {j}",
vertices[i]
);
assert_eq!(
edges.iter().filter(|e| **e == current.1).count(),
1,
"unexpected incident edge {:?} of vertex {:?}",
current.1,
vertices[i],
);
}
assert_eq!(
iter.next(),
None,
"too many adjacent vertices of {:?} from iterator",
vertices[i]
);
}
}
#[test]
fn incident_vertices_incidences_consistency() {
let (graph, _, _, _) = make_test_graph();
for u in graph.vertices() {
for (v, e) in graph.incidences(u) {
let (w1, w2) = graph.incident_vertices(e);
assert!(
(w1 == u && w2 == v) || (w1 == v && w2 == u),
"incident vertices {w1:?} and {w2:?} of edge {e:?} are inconsistent with incidence ({v:?}, {e:?}) of vertex {u:?}"
);
}
}
}
};
}
#[cfg(test)]
#[macro_export]
macro_rules! graph_topology_deletion_tests {
($T:ty) => {
#[test]
fn delete_vertex() {
let mut graph = Graph::new();
let v = graph.add_vertex();
assert_eq!(
graph.vertex_count(),
1,
"unexpected vertex count before delete"
);
graph.delete_vertex(v);
assert_eq!(
graph.vertex_count(),
0,
"unexpected vertex count after delete"
);
assert_ne!(
graph.add_vertex(),
v,
"unexpected duplicate vertex after delete"
);
}
#[test]
fn delete_vertex_loop() {
let mut graph = Graph::new();
let v = graph.add_vertex();
graph.add_edge(v, v);
assert_eq!(
graph.vertex_count(),
1,
"unexpected vertex count before delete"
);
assert_eq!(graph.edge_count(), 1, "unexpected edge count before delete");
assert!(
graph.are_adjacent(v, v),
"expected vertex to be self-adjacent before delete"
);
assert_eq!(graph.degree(v), 2, "unexpected vertex degree before delete");
graph.delete_vertex(v);
assert_eq!(
graph.vertex_count(),
0,
"unexpected vertex count after delete"
);
assert_eq!(graph.edge_count(), 0, "unexpected edge count after delete");
assert_ne!(
graph.add_vertex(),
v,
"unexpected duplicate vertex after delete"
);
}
#[test]
fn delete_vertex_invalid_index() {
let mut graph = Graph::new();
let v = graph.add_vertex();
graph.delete_vertex(v);
let result = std::panic::catch_unwind(move || graph.delete_vertex(v));
assert!(result.is_err(), "second deletion should panic");
}
#[test]
fn delete_vertex_connected() {
let (mut graph, vertices, _, _) = make_test_graph();
assert_eq!(
graph.vertex_count(),
10,
"unexpected vertex count before delete"
);
assert_eq!(
graph.edge_count(),
18,
"unexpected edge count before delete"
);
graph.delete_vertex(vertices[2]);
assert_eq!(
graph.vertex_count(),
9,
"unexpected vertex count after delete"
);
assert_eq!(graph.edge_count(), 12, "unexpected edge count after delete");
let expected_edges = [
(vertices[0], vertices[1]),
(vertices[1], vertices[3]),
(vertices[1], vertices[4]),
(vertices[3], vertices[6]),
(vertices[4], vertices[4]),
(vertices[4], vertices[7]),
(vertices[4], vertices[8]),
(vertices[5], vertices[9]),
(vertices[6], vertices[9]),
(vertices[7], vertices[8]),
(vertices[7], vertices[9]),
];
for (v, u) in expected_edges {
assert!(
graph.are_adjacent(v, u),
"expected {v:?} and {u:?} to be adjacent after delete"
);
}
for v in [vertices[1], vertices[4], vertices[5], vertices[6]] {
assert!(
!graph.adjacent_vertices(v).any(|u| u == vertices[2]),
"unexpected adjacency of {v:?} to deleted vertex {:?}",
vertices[2]
);
}
}
#[test]
fn delete_edge() {
let mut graph = Graph::new();
let v1 = graph.add_vertex();
let v2 = graph.add_vertex();
let e = graph.add_edge(v1, v2);
assert_eq!(
graph.vertex_count(),
2,
"unexpected vertex count before delete"
);
assert_eq!(graph.edge_count(), 1, "unexpected edge count before delete");
assert!(
graph.are_adjacent(v1, v2),
"expected vertices to be adjacent before delete"
);
assert_eq!(
graph.degree(v1),
1,
"unexpected vertex degree before delete"
);
assert_eq!(
graph.degree(v2),
1,
"unexpected vertex degree before delete"
);
graph.delete_edge(e);
assert_eq!(
graph.vertex_count(),
2,
"unexpected vertex count after delete"
);
assert_eq!(graph.edge_count(), 0, "unexpected edge count after delete");
assert!(
!graph.are_adjacent(v1, v2),
"unexpected adjacency after delete"
);
assert_eq!(graph.degree(v1), 0, "unexpected vertex degree after delete");
assert_eq!(graph.degree(v2), 0, "unexpected vertex degree after delete");
assert_ne!(
graph.add_edge(v1, v2),
e,
"unexpected duplicate edge after delete"
);
}
#[test]
fn delete_edge_loop() {
let mut graph = Graph::new();
let v = graph.add_vertex();
let e = graph.add_edge(v, v);
assert_eq!(
graph.vertex_count(),
1,
"unexpected vertex count before delete"
);
assert_eq!(graph.edge_count(), 1, "unexpected edge count before delete");
assert!(
graph.are_adjacent(v, v),
"expected vertex to be self-adjacent before delete"
);
assert_eq!(graph.degree(v), 2, "unexpected vertex degree before delete");
graph.delete_edge(e);
assert_eq!(
graph.vertex_count(),
1,
"unexpected vertex count after delete"
);
assert_eq!(graph.edge_count(), 0, "unexpected edge count after delete");
assert!(
!graph.are_adjacent(v, v),
"unexpected adjacency after delete"
);
assert_eq!(graph.degree(v), 0, "unexpected vertex degree after delete");
assert_ne!(
graph.add_edge(v, v),
e,
"unexpected duplicate edge after delete"
);
}
#[test]
fn delete_edge_multiple() {
let mut graph = Graph::new();
let v1 = graph.add_vertex();
let v2 = graph.add_vertex();
let e = graph.add_edge(v1, v2);
graph.add_edge(v1, v2);
assert_eq!(
graph.vertex_count(),
2,
"unexpected vertex count before delete"
);
assert_eq!(graph.edge_count(), 2, "unexpected edge count before delete");
assert!(
graph.are_adjacent(v1, v2),
"expected vertices to be adjacent before delete"
);
assert_eq!(
graph.degree(v1),
2,
"unexpected vertex degree before delete"
);
assert_eq!(
graph.degree(v2),
2,
"unexpected vertex degree before delete"
);
graph.delete_edge(e);
assert_eq!(
graph.vertex_count(),
2,
"unexpected vertex count after delete"
);
assert_eq!(graph.edge_count(), 1, "unexpected edge count after delete");
assert!(
graph.are_adjacent(v1, v2),
"expected vertices to be adjacent after delete"
);
assert_eq!(graph.degree(v1), 1, "unexpected vertex degree after delete");
assert_eq!(graph.degree(v2), 1, "unexpected vertex degree after delete");
assert_ne!(
graph.add_edge(v1, v2),
e,
"unexpected duplicate edge after delete"
);
}
#[test]
fn delete_edge_invalid_index() {
let mut graph = Graph::new();
let v1 = graph.add_vertex();
let v2 = graph.add_vertex();
let e = graph.add_edge(v1, v2);
graph.delete_edge(e);
let result = std::panic::catch_unwind(move || graph.delete_edge(e));
assert!(result.is_err(), "second deletion should panic");
}
#[test]
fn vertices_after_delete() {
let (mut graph, vertices, _, _) = make_test_graph();
graph.delete_vertex(vertices[2]);
assert_eq!(
graph.vertex_count(),
9,
"unexpected vertex count after delete"
);
assert_eq!(
graph.vertices().count(),
9,
"unexpected vertex iterator count after delete"
);
for v in graph.vertices() {
assert_ne!(
v, vertices[2],
"deleted vertex {:?} appeared in iterator",
vertices[2]
);
}
for i in [0, 1, 3, 4, 5, 6, 7, 8, 9] {
assert!(
graph.vertices().any(|v| v == vertices[i]),
"expected vertex {:?} missing from iterator after delete",
vertices[i]
);
}
}
#[test]
fn incident_vertices_after_delete_edge() {
let (mut graph, vertices, edges, _) = make_test_graph();
graph.delete_edge(edges[2]);
let expected: [(
usize,
<Graph as $crate::traits::GraphTopology>::Vertex,
<Graph as $crate::traits::GraphTopology>::Vertex,
); 17] = [
(0, vertices[0], vertices[1]),
(1, vertices[0], vertices[1]),
(3, vertices[1], vertices[3]),
(4, vertices[1], vertices[4]),
(5, vertices[2], vertices[2]),
(6, vertices[2], vertices[4]),
(7, vertices[2], vertices[4]),
(8, vertices[2], vertices[5]),
(9, vertices[2], vertices[6]),
(10, vertices[3], vertices[6]),
(11, vertices[4], vertices[4]),
(12, vertices[4], vertices[7]),
(13, vertices[4], vertices[8]),
(14, vertices[5], vertices[9]),
(15, vertices[6], vertices[9]),
(16, vertices[7], vertices[8]),
(17, vertices[7], vertices[9]),
];
for (i, v1, v2) in expected {
let (u1, u2) = graph.incident_vertices(edges[i]);
assert!(
(u1 == v1 && u2 == v2) || (u1 == v2 && u2 == v1),
"unexpected incident vertices {u1:?} and {u2:?} for edges[{i}] ({:?}) after delete",
edges[i]
);
}
}
#[test]
fn edges_after_delete() {
let (mut graph, vertices, edges, _) = make_test_graph();
graph.delete_vertex(vertices[2]);
assert_eq!(graph.edge_count(), 12, "unexpected edge count after delete");
assert_eq!(
graph.edges().count(),
12,
"unexpected edge iterator count after delete"
);
for i in [2, 5, 6, 7, 8, 9] {
assert!(
!graph.edges().any(|e| e == edges[i]),
"deleted edge {:?} appeared in iterator",
edges[i]
);
}
for i in [0, 1, 3, 4, 10, 11, 12, 13, 14, 15, 16, 17] {
assert!(
graph.edges().any(|e| e == edges[i]),
"expected edge {:?} missing from iterator after delete",
edges[i]
);
}
}
#[test]
fn incidences_after_delete_vertex() {
let (mut graph, vertices, _, incidences) = make_test_graph();
graph.delete_vertex(vertices[2]);
for i in [0, 1, 3, 4, 5, 6, 7, 8, 9] {
let remaining = incidences[i]
.iter()
.filter(|(v, _)| *v != vertices[2])
.cloned()
.collect();
assert_vertex_incidences(&graph, vertices[i], remaining);
}
}
#[test]
fn incidences_after_delete_edge() {
let (mut graph, vertices, edges, incidences) = make_test_graph();
// Deletes the edge from vertices[1] to vertices[2].
graph.delete_edge(edges[2]);
for i in 0..10 {
let remaining = incidences[i]
.iter()
.filter(|(_, e)| *e != edges[2])
.cloned()
.collect();
assert_vertex_incidences(&graph, vertices[i], remaining);
}
}
fn assert_vertex_incidences(
graph: &$T,
v: <$T as $crate::traits::GraphTopology>::Vertex,
mut expected: Vec<(
<$T as $crate::traits::GraphTopology>::Vertex,
<$T as $crate::traits::GraphTopology>::Edge,
)>,
) {
assert_eq!(
graph.incidences(v).count(),
expected.len(),
"unexpected incidence count for vertex {:?} after delete",
v
);
for incidence in graph.incidences(v) {
let pos = expected
.iter()
.position(|(u, e)| *u == incidence.0 && *e == incidence.1)
.expect(&format!(
"unexpected incidence {incidence:?} of vertex {:?} after delete",
v
));
expected.swap_remove(pos);
}
assert!(
expected.is_empty(),
"expected incidences {:?} of vertex {:?} not matched after delete",
expected,
v
);
}
};
}