Refactor tests: use MakeTestGraph in model-specific tests, deconstruct vertex arrays where useful, adjust local variable names

This commit is contained in:
2026-09-04 09:28:00 +02:00
parent 016d127bd1
commit 4c6a8a43e4
11 changed files with 153 additions and 195 deletions
+14 -14
View File
@@ -90,10 +90,10 @@ impl IncidenceCursor<AppendGraph> for AppendGraphIncidenceCursor {
/// use grapherity::models::AppendGraph;
///
/// let mut graph = AppendGraph::new();
/// let v1 = graph.add_vertex();
/// let v2 = graph.add_vertex();
/// let e = graph.add_edge(v1, v2);
/// assert!(graph.are_adjacent(v1, v2));
/// let u = graph.add_vertex();
/// let v = graph.add_vertex();
/// let e = graph.add_edge(u, v);
/// assert!(graph.are_adjacent(u, v));
/// ```
///
/// # Time and space complexity
@@ -122,13 +122,13 @@ impl AppendGraph {
/// Adds a single incidence of an edge, which is composed by two such incidences, to the
/// incidences vector.
fn add_incidence(&mut self, v1: Vertex, v2: Vertex) {
fn add_incidence(&mut self, u: Vertex, v: Vertex) {
self.incidences.push(IncidenceEntry {
next: self.vertices[v1.0].first_incidence.take(),
adjacent: v2,
next: self.vertices[u.0].first_incidence.take(),
adjacent: v,
});
self.vertices[v1.0].incidence_count += 1;
self.vertices[v1.0].first_incidence = Some(Edge::new(self.incidences.len() - 1));
self.vertices[u.0].incidence_count += 1;
self.vertices[u.0].first_incidence = Some(Edge::new(self.incidences.len() - 1));
}
fn raw_incidences(&self, v: Vertex) -> impl Iterator<Item = (Vertex, Edge)> {
@@ -177,8 +177,8 @@ impl GraphTopology for AppendGraph {
self.vertices[v.0].incidence_count
}
fn are_adjacent(&self, v1: Self::Vertex, v2: Self::Vertex) -> bool {
self.adjacent_vertices(v1).any(|x| x == v2)
fn are_adjacent(&self, u: Self::Vertex, v: Self::Vertex) -> bool {
self.adjacent_vertices(u).any(|x| x == v)
}
fn vertices(&self) -> impl Iterator<Item = Self::Vertex> {
@@ -244,9 +244,9 @@ impl GraphTopologyAddition for AppendGraph {
Vertex(self.vertices.len() - 1)
}
fn add_edge(&mut self, v1: Self::Vertex, v2: Self::Vertex) -> Self::Edge {
self.add_incidence(v1, v2);
self.add_incidence(v2, v1);
fn add_edge(&mut self, u: Self::Vertex, v: Self::Vertex) -> Self::Edge {
self.add_incidence(u, v);
self.add_incidence(v, u);
Edge::new(self.incidences.len() - 2)
}
}
+8 -8
View File
@@ -74,13 +74,13 @@ impl IncidenceCursor<FrozenGraph> for FrozenGraphIncidenceCursor {
///
/// // Constructs a FrozenGraph instance via AppendGraph.
/// let mut graph = AppendGraph::new();
/// let v1 = graph.add_vertex();
/// let v2 = graph.add_vertex();
/// let e = graph.add_edge(v1, v2);
/// let (graph, vertices, edges) = FrozenGraph::from_graph(&graph);
/// let u = graph.add_vertex();
/// let v = graph.add_vertex();
/// let e = graph.add_edge(u, v);
/// let (graph, vertex_map, edge_map) = FrozenGraph::from_graph(&graph);
///
/// // Queries the FrozenGraph instance.
/// assert!(graph.are_adjacent(vertices[v1], vertices[v2]));
/// // Queries the FrozenGraph instance via the returned map.
/// assert!(graph.are_adjacent(vertex_map[u], vertex_map[v]));
/// ```
///
/// # Time and space complexity
@@ -210,8 +210,8 @@ impl GraphTopology for FrozenGraph {
self.vertices[v.0 + 1] - self.vertices[v.0]
}
fn are_adjacent(&self, v1: Self::Vertex, v2: Self::Vertex) -> bool {
self.adjacent_vertices(v1).any(|x| x == v2)
fn are_adjacent(&self, u: Self::Vertex, v: Self::Vertex) -> bool {
self.adjacent_vertices(u).any(|x| x == v)
}
fn vertices(&self) -> impl Iterator<Item = Self::Vertex> {
+30 -39
View File
@@ -152,13 +152,13 @@ impl Graph {
/// Adds a single incidence of an edge, which is composed by two such incidences, to the
/// incidences arena, and returns its index.
fn add_incidence(&mut self, v1: Vertex, v2: Vertex) -> Edge {
fn add_incidence(&mut self, u: Vertex, v: Vertex) -> Edge {
let edge = self.incidences.insert(IncidenceEntry {
next: self.vertices[v1].first_incidence.take(),
adjacent: VertexSlot(v2.arr_idx()),
next: self.vertices[u].first_incidence.take(),
adjacent: VertexSlot(v.arr_idx()),
});
self.vertices[v1].incidence_count += 1;
self.vertices[v1].first_incidence = Some(IncidenceSlot::new(edge.arr_idx()));
self.vertices[u].incidence_count += 1;
self.vertices[u].first_incidence = Some(IncidenceSlot::new(edge.arr_idx()));
edge
}
@@ -270,8 +270,8 @@ impl GraphTopology for Graph {
self.vertices[v].incidence_count
}
fn are_adjacent(&self, v1: Self::Vertex, v2: Self::Vertex) -> bool {
self.adjacent_vertices(v1).any(|x| x == v2)
fn are_adjacent(&self, u: Self::Vertex, v: Self::Vertex) -> bool {
self.adjacent_vertices(u).any(|x| x == v)
}
fn vertices(&self) -> impl Iterator<Item = Self::Vertex> {
@@ -284,16 +284,16 @@ impl GraphTopology for Graph {
}
fn incident_vertices(&self, e: Self::Edge) -> (Self::Vertex, Self::Vertex) {
let v2 = self
let v = self
.vertices
.get_idx(self.incidences[e].adjacent.0)
.unwrap();
let f = self.incidences.get_idx(e.arr_idx() ^ 1).unwrap();
let v1 = self
let u = self
.vertices
.get_idx(self.incidences[f].adjacent.0)
.unwrap();
(v1, v2)
(u, v)
}
fn edges(&self) -> impl Iterator<Item = Self::Edge> {
@@ -345,9 +345,9 @@ impl GraphTopologyAddition for Graph {
})
}
fn add_edge(&mut self, v1: Self::Vertex, v2: Self::Vertex) -> Self::Edge {
let first = self.add_incidence(v1, v2);
self.add_incidence(v2, v1);
fn add_edge(&mut self, u: Self::Vertex, v: Self::Vertex) -> Self::Edge {
let first = self.add_incidence(u, v);
self.add_incidence(v, u);
first
}
}
@@ -403,30 +403,25 @@ mod trait_tests {
#[cfg(test)]
mod tests {
use super::*;
use crate::testing::fixtures::MakeTestGraph;
#[test]
fn incident_vertices_paired_index() {
let mut graph = Graph::new();
let v1 = graph.add_vertex();
let v2 = graph.add_vertex();
let e = graph.add_edge(v1, v2);
let (graph, [v0, v1], e) = Graph::single_edge();
let f = graph
.incidences
.get_idx(e.arr_idx() + 1)
.expect("paired index should be valid");
let (u1, u2) = graph.incident_vertices(f);
let (u0, u1) = graph.incident_vertices(f);
assert!(
(u1 == v1 && u2 == v2) || (u1 == v2 && u2 == v1),
"unexpected incident vertices {u1:?} and {u2:?} for edge {f:?}"
(u0 == v0 && u1 == v1) || (u0 == v1 && u1 == v0),
"unexpected incident vertices {u0:?} and {u1:?} for edge {f:?}"
);
}
#[test]
fn delete_edge_paired_index() {
let mut graph = Graph::new();
let v1 = graph.add_vertex();
let v2 = graph.add_vertex();
let e = graph.add_edge(v1, v2);
let (mut graph, _, e) = Graph::single_edge();
let f = graph
.incidences
.get_idx(e.arr_idx() + 1)
@@ -437,9 +432,7 @@ mod tests {
#[test]
fn delete_edge_loop_paired_index() {
let mut graph = Graph::new();
let v = graph.add_vertex();
let e = graph.add_edge(v, v);
let (mut graph, _, e) = Graph::loop_edge();
let f = graph
.incidences
.get_idx(e.arr_idx() + 1)
@@ -450,23 +443,21 @@ mod tests {
#[test]
fn reused_slot_returns_old_value() {
let mut graph = Graph::new();
graph.add_vertex();
let v1 = graph.add_vertex();
let (mut graph, [_, v], _) = Graph::single_edge();
let mut map = graph.vertex_map(0);
map[v1] = 99;
graph.delete_vertex(v1);
let v2 = graph.add_vertex();
map[v] = 99;
graph.delete_vertex(v);
let u = graph.add_vertex();
assert_eq!(
v1.arr_idx(),
v2.arr_idx(),
"precondition: new vertex {v1:?} should reuse slot of deleted vertex {v2:?}"
v.arr_idx(),
u.arr_idx(),
"precondition: new vertex {v:?} should reuse slot of deleted vertex {u:?}"
);
// ElementMap uses raw indices, not vertex identity. A new vertex v2 reusing the slot
// of previously deleted v1 sees the old value. Callers must reinitialize stale slots
// ElementMap uses raw indices, not vertex identity. A new vertex u reusing the slot
// of previously deleted v sees the old value. Callers must reinitialize stale slots
// after deletion.
assert_eq!(
map[v2], 99,
map[u], 99,
"new vertex reusing slot of deleted vertex should return old value"
);
}