Update generators unit tests to cover generate_as and better validate Petersen graph

This commit is contained in:
2026-10-16 20:28:48 +02:00
parent 5b6ad13f0e
commit 3ae0aa9b67
+110 -19
View File
@@ -84,37 +84,128 @@ where
#[cfg(test)]
mod tests {
use std::fmt::Debug;
use super::*;
use crate::models::{FrozenGraph, Graph};
#[test]
fn petersen() {
let mut graph = AppendGraph::new();
let (vertices, edges) = super::petersen(&mut graph);
assert_eq!(
graph.vertex_count(),
10,
"unexpected number of added vertices"
);
assert_eq!(graph.edge_count(), 15, "unexpected number of added edges");
fn petersen_append_graph() {
petersen_add::<AppendGraph>();
}
#[test]
fn petersen_graph() {
petersen_add::<Graph>();
}
#[test]
fn petersen_frozen_graph() {
petersen_generate_as::<FrozenGraph>();
}
fn petersen_generate_as<G: GraphTopologyConversion>()
where
G::Vertex: Debug,
G::Edge: Debug,
{
let (graph, vertices, edges) = generate_as::<G, _, _>(petersen);
assert_petersen(&graph, &vertices, &edges);
}
fn petersen_add<G: GraphTopologyAddition>()
where
G::Vertex: Debug,
G::Edge: Debug,
{
let mut graph = G::default();
let (vertices, edges) = petersen(&mut graph);
assert_petersen(&graph, &vertices, &edges);
}
fn assert_petersen<G: GraphTopology>(graph: &G, vertices: &[G::Vertex], edges: &[G::Edge])
where
G::Vertex: Debug,
G::Edge: Debug,
{
assert_element_counts(graph, 10, 15);
assert_handles(graph.vertices(), vertices, "vertex");
assert_handles(graph.edges(), edges, "edge");
assert_no_loops_no_multi_edges(graph);
assert!(
graph.vertices().all(|v| graph.degree(v) == 3),
"all vertices should have degree 3"
);
assert_handles_in_graph(&graph, &vertices, &edges);
// Checks that each pair of vertices (u, v) has no common neighbor if they are adjacent, and
// exactly one common neighbor otherwise.
for (i, &v) in vertices.iter().enumerate() {
for &u in &vertices[i + 1..] {
if graph.are_adjacent(v, u) {
assert!(
graph.common_neighbors(u, v).next().is_none(),
"adjacent vertices {u:?} and {v:?} should not have a common neighbor"
);
} else {
assert_eq!(
graph.common_neighbors(u, v).count(),
1,
"non-adjacent vertices {u:?} and {v:?} should have exactly one common neighbor"
);
}
}
}
}
fn assert_handles_in_graph<G: GraphTopology>(
fn assert_element_counts<G: GraphTopology>(
graph: &G,
vertices: &[G::Vertex],
edges: &[G::Edge],
expected_vertex_count: usize,
expected_edge_count: usize,
) {
assert!(
vertices.iter().all(|&v| graph.vertices().any(|u| u == v)),
"all returned vertices should be in the graph"
assert_eq!(
graph.vertex_count(),
expected_vertex_count,
"unexpected number of vertices"
);
assert!(
edges.iter().all(|&e| graph.edges().any(|f| f == e)),
"all returned edges should be in the graph"
assert_eq!(
graph.edge_count(),
expected_edge_count,
"unexpected number of edges"
);
}
/// Asserts that every handle in `returned` is unique and in `all`.
fn assert_handles<T: PartialEq + Debug>(
all: impl Iterator<Item = T>,
returned: &[T],
kind: &str,
) {
let mut remaining: Vec<T> = all.collect();
for e in returned {
let Some(position) = remaining.iter().position(|x| x == e) else {
panic!("returned {kind} {e:?} is not in the graph or appears more than once");
};
remaining.swap_remove(position);
}
}
fn assert_no_loops_no_multi_edges<G: GraphTopology>(graph: &G)
where
G::Vertex: Debug,
G::Edge: Debug,
{
for e in graph.edges() {
let (u, v) = graph.incident_vertices(e);
assert_ne!(u, v, "unexpected loop edge {e:?}");
}
for v in graph.vertices() {
let mut neighbors = Vec::new();
for u in graph.adjacent_vertices(v) {
assert!(
!neighbors.contains(&u),
"unexpected multi-edge between {v:?} and {u:?}"
);
neighbors.push(u);
}
}
}
}