Add GraphTopology::incident_edges() and tests

This commit is contained in:
2026-05-13 10:59:38 +02:00
parent 384dca2d20
commit f862ac55ec
4 changed files with 185 additions and 1 deletions
+172
View File
@@ -452,6 +452,92 @@ macro_rules! graph_topology_tests {
}
}
#[test]
fn incident_edges_empty() {
let mut graph = <$T>::new();
let v = graph.add_vertex();
assert_eq!(
graph.incident_edges(v).count(),
0,
"incident edge iterator of vertex with degree 0 should have no elements"
);
}
#[test]
fn incident_edges() {
let (graph, vertices, _, incidences) = make_test_graph();
for i in 0..10 {
assert_eq!(
graph.incident_edges(vertices[i]).count(),
incidences[i].len(),
"unexpected incident edge count for vertex {:?}",
vertices[i]
);
let mut expected: Vec<_> = incidences[i].iter().map(|(_, e)| *e).collect();
for e in graph.incident_edges(vertices[i]) {
let pos = expected
.iter()
.position(|f| *f == e)
.expect(&format!(
"unexpected incident edge {e:?} of vertex {:?} from the iterator",
vertices[i]
));
expected.swap_remove(pos);
}
assert!(
expected.is_empty(),
"expected incident edges {:?} of vertex {:?} were not matched by the iterator",
expected,
vertices[i]
);
}
}
#[test]
fn incident_edges_loop_edge() {
let mut graph = <$T>::new();
let v = graph.add_vertex();
let e = graph.add_edge(v, v);
let mut iter = graph.incident_edges(v);
assert_eq!(iter.next(), Some(e), "loop edge should appear in incident edges");
assert_eq!(
iter.next(),
Some(e),
"loop edge should appear twice in incident edges"
);
assert_eq!(iter.next(), None, "too many incident edges from iterator");
}
#[test]
fn incident_edges_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 expected = edges.clone();
for e in graph.incident_edges(vertices[i]) {
let pos = expected
.iter()
.position(|f| *f == e)
.expect(&format!(
"unexpected incident edge {e:?} of vertex {:?}",
vertices[i]
));
expected.swap_remove(pos);
}
assert!(
expected.is_empty(),
"expected incident edges {:?} of vertex {:?} were not matched by the iterator",
expected,
vertices[i]
);
}
}
#[test]
fn incidences_empty() {
let mut graph = <$T>::new();
@@ -591,6 +677,28 @@ macro_rules! graph_topology_tests {
}
}
}
#[test]
fn incident_edges_incidences_consistency() {
let (graph, _, _, _) = make_test_graph();
for u in graph.vertices() {
let mut expected: Vec<_> = graph.incidences(u).map(|(_, e)| e).collect();
for e in graph.incident_edges(u) {
let pos = expected
.iter()
.position(|f| *f == e)
.expect(&format!(
"incident edge {e:?} of vertex {u:?} missing from incidences"
));
expected.swap_remove(pos);
}
assert!(
expected.is_empty(),
"incidence edges {:?} of vertex {u:?} not matched by incident_edges",
expected
);
}
}
};
}
@@ -916,6 +1024,70 @@ macro_rules! graph_topology_deletion_tests {
}
}
#[test]
fn incident_edges_after_delete_edge() {
let (mut graph, vertices, edges, incidences) = make_test_graph();
graph.delete_edge(edges[2].0);
for i in 0..10 {
let mut expected: Vec<_> = incidences[i]
.iter()
.filter(|(_, e)| *e != edges[2].0)
.map(|(_, e)| *e)
.collect();
assert_eq!(
graph.incident_edges(vertices[i]).count(),
expected.len(),
"unexpected incident edge count for vertex {:?} after delete",
vertices[i]
);
for e in graph.incident_edges(vertices[i]) {
let pos = expected.iter().position(|f| *f == e).expect(&format!(
"unexpected incident edge {e:?} of vertex {:?} after delete",
vertices[i]
));
expected.swap_remove(pos);
}
assert!(
expected.is_empty(),
"expected incident edges {:?} of vertex {:?} not matched after delete",
expected,
vertices[i]
);
}
}
#[test]
fn incident_edges_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 mut expected: Vec<_> = incidences[i]
.iter()
.filter(|(v, _)| *v != vertices[2])
.map(|(_, e)| *e)
.collect();
assert_eq!(
graph.incident_edges(vertices[i]).count(),
expected.len(),
"unexpected incident edge count for vertex {:?} after delete",
vertices[i]
);
for e in graph.incident_edges(vertices[i]) {
let pos = expected.iter().position(|f| *f == e).expect(&format!(
"unexpected incident edge {e:?} of vertex {:?} after delete",
vertices[i]
));
expected.swap_remove(pos);
}
assert!(
expected.is_empty(),
"expected incident edges {:?} of vertex {:?} not matched after delete",
expected,
vertices[i]
);
}
}
#[test]
fn incidences_after_delete_vertex() {
let (mut graph, vertices, _, incidences) = make_test_graph();