Refactor tests: use MakeTestGraph in model-specific tests, deconstruct vertex arrays where useful, adjust local variable names
This commit is contained in:
+14
-14
@@ -90,10 +90,10 @@ impl IncidenceCursor<AppendGraph> for AppendGraphIncidenceCursor {
|
|||||||
/// use grapherity::models::AppendGraph;
|
/// use grapherity::models::AppendGraph;
|
||||||
///
|
///
|
||||||
/// let mut graph = AppendGraph::new();
|
/// let mut graph = AppendGraph::new();
|
||||||
/// let v1 = graph.add_vertex();
|
/// let u = graph.add_vertex();
|
||||||
/// let v2 = graph.add_vertex();
|
/// let v = graph.add_vertex();
|
||||||
/// let e = graph.add_edge(v1, v2);
|
/// let e = graph.add_edge(u, v);
|
||||||
/// assert!(graph.are_adjacent(v1, v2));
|
/// assert!(graph.are_adjacent(u, v));
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// # Time and space complexity
|
/// # 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
|
/// Adds a single incidence of an edge, which is composed by two such incidences, to the
|
||||||
/// incidences vector.
|
/// incidences vector.
|
||||||
fn add_incidence(&mut self, v1: Vertex, v2: Vertex) {
|
fn add_incidence(&mut self, u: Vertex, v: Vertex) {
|
||||||
self.incidences.push(IncidenceEntry {
|
self.incidences.push(IncidenceEntry {
|
||||||
next: self.vertices[v1.0].first_incidence.take(),
|
next: self.vertices[u.0].first_incidence.take(),
|
||||||
adjacent: v2,
|
adjacent: v,
|
||||||
});
|
});
|
||||||
self.vertices[v1.0].incidence_count += 1;
|
self.vertices[u.0].incidence_count += 1;
|
||||||
self.vertices[v1.0].first_incidence = Some(Edge::new(self.incidences.len() - 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)> {
|
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
|
self.vertices[v.0].incidence_count
|
||||||
}
|
}
|
||||||
|
|
||||||
fn are_adjacent(&self, v1: Self::Vertex, v2: Self::Vertex) -> bool {
|
fn are_adjacent(&self, u: Self::Vertex, v: Self::Vertex) -> bool {
|
||||||
self.adjacent_vertices(v1).any(|x| x == v2)
|
self.adjacent_vertices(u).any(|x| x == v)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn vertices(&self) -> impl Iterator<Item = Self::Vertex> {
|
fn vertices(&self) -> impl Iterator<Item = Self::Vertex> {
|
||||||
@@ -244,9 +244,9 @@ impl GraphTopologyAddition for AppendGraph {
|
|||||||
Vertex(self.vertices.len() - 1)
|
Vertex(self.vertices.len() - 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_edge(&mut self, v1: Self::Vertex, v2: Self::Vertex) -> Self::Edge {
|
fn add_edge(&mut self, u: Self::Vertex, v: Self::Vertex) -> Self::Edge {
|
||||||
self.add_incidence(v1, v2);
|
self.add_incidence(u, v);
|
||||||
self.add_incidence(v2, v1);
|
self.add_incidence(v, u);
|
||||||
Edge::new(self.incidences.len() - 2)
|
Edge::new(self.incidences.len() - 2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,13 +74,13 @@ impl IncidenceCursor<FrozenGraph> for FrozenGraphIncidenceCursor {
|
|||||||
///
|
///
|
||||||
/// // Constructs a FrozenGraph instance via AppendGraph.
|
/// // Constructs a FrozenGraph instance via AppendGraph.
|
||||||
/// let mut graph = AppendGraph::new();
|
/// let mut graph = AppendGraph::new();
|
||||||
/// let v1 = graph.add_vertex();
|
/// let u = graph.add_vertex();
|
||||||
/// let v2 = graph.add_vertex();
|
/// let v = graph.add_vertex();
|
||||||
/// let e = graph.add_edge(v1, v2);
|
/// let e = graph.add_edge(u, v);
|
||||||
/// let (graph, vertices, edges) = FrozenGraph::from_graph(&graph);
|
/// let (graph, vertex_map, edge_map) = FrozenGraph::from_graph(&graph);
|
||||||
///
|
///
|
||||||
/// // Queries the FrozenGraph instance.
|
/// // Queries the FrozenGraph instance via the returned map.
|
||||||
/// assert!(graph.are_adjacent(vertices[v1], vertices[v2]));
|
/// assert!(graph.are_adjacent(vertex_map[u], vertex_map[v]));
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// # Time and space complexity
|
/// # Time and space complexity
|
||||||
@@ -210,8 +210,8 @@ impl GraphTopology for FrozenGraph {
|
|||||||
self.vertices[v.0 + 1] - self.vertices[v.0]
|
self.vertices[v.0 + 1] - self.vertices[v.0]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn are_adjacent(&self, v1: Self::Vertex, v2: Self::Vertex) -> bool {
|
fn are_adjacent(&self, u: Self::Vertex, v: Self::Vertex) -> bool {
|
||||||
self.adjacent_vertices(v1).any(|x| x == v2)
|
self.adjacent_vertices(u).any(|x| x == v)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn vertices(&self) -> impl Iterator<Item = Self::Vertex> {
|
fn vertices(&self) -> impl Iterator<Item = Self::Vertex> {
|
||||||
|
|||||||
+30
-39
@@ -152,13 +152,13 @@ impl Graph {
|
|||||||
|
|
||||||
/// Adds a single incidence of an edge, which is composed by two such incidences, to the
|
/// Adds a single incidence of an edge, which is composed by two such incidences, to the
|
||||||
/// incidences arena, and returns its index.
|
/// 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 {
|
let edge = self.incidences.insert(IncidenceEntry {
|
||||||
next: self.vertices[v1].first_incidence.take(),
|
next: self.vertices[u].first_incidence.take(),
|
||||||
adjacent: VertexSlot(v2.arr_idx()),
|
adjacent: VertexSlot(v.arr_idx()),
|
||||||
});
|
});
|
||||||
self.vertices[v1].incidence_count += 1;
|
self.vertices[u].incidence_count += 1;
|
||||||
self.vertices[v1].first_incidence = Some(IncidenceSlot::new(edge.arr_idx()));
|
self.vertices[u].first_incidence = Some(IncidenceSlot::new(edge.arr_idx()));
|
||||||
edge
|
edge
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -270,8 +270,8 @@ impl GraphTopology for Graph {
|
|||||||
self.vertices[v].incidence_count
|
self.vertices[v].incidence_count
|
||||||
}
|
}
|
||||||
|
|
||||||
fn are_adjacent(&self, v1: Self::Vertex, v2: Self::Vertex) -> bool {
|
fn are_adjacent(&self, u: Self::Vertex, v: Self::Vertex) -> bool {
|
||||||
self.adjacent_vertices(v1).any(|x| x == v2)
|
self.adjacent_vertices(u).any(|x| x == v)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn vertices(&self) -> impl Iterator<Item = Self::Vertex> {
|
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) {
|
fn incident_vertices(&self, e: Self::Edge) -> (Self::Vertex, Self::Vertex) {
|
||||||
let v2 = self
|
let v = self
|
||||||
.vertices
|
.vertices
|
||||||
.get_idx(self.incidences[e].adjacent.0)
|
.get_idx(self.incidences[e].adjacent.0)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let f = self.incidences.get_idx(e.arr_idx() ^ 1).unwrap();
|
let f = self.incidences.get_idx(e.arr_idx() ^ 1).unwrap();
|
||||||
let v1 = self
|
let u = self
|
||||||
.vertices
|
.vertices
|
||||||
.get_idx(self.incidences[f].adjacent.0)
|
.get_idx(self.incidences[f].adjacent.0)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
(v1, v2)
|
(u, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn edges(&self) -> impl Iterator<Item = Self::Edge> {
|
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 {
|
fn add_edge(&mut self, u: Self::Vertex, v: Self::Vertex) -> Self::Edge {
|
||||||
let first = self.add_incidence(v1, v2);
|
let first = self.add_incidence(u, v);
|
||||||
self.add_incidence(v2, v1);
|
self.add_incidence(v, u);
|
||||||
first
|
first
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -403,30 +403,25 @@ mod trait_tests {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::testing::fixtures::MakeTestGraph;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn incident_vertices_paired_index() {
|
fn incident_vertices_paired_index() {
|
||||||
let mut graph = Graph::new();
|
let (graph, [v0, v1], e) = Graph::single_edge();
|
||||||
let v1 = graph.add_vertex();
|
|
||||||
let v2 = graph.add_vertex();
|
|
||||||
let e = graph.add_edge(v1, v2);
|
|
||||||
let f = graph
|
let f = graph
|
||||||
.incidences
|
.incidences
|
||||||
.get_idx(e.arr_idx() + 1)
|
.get_idx(e.arr_idx() + 1)
|
||||||
.expect("paired index should be valid");
|
.expect("paired index should be valid");
|
||||||
let (u1, u2) = graph.incident_vertices(f);
|
let (u0, u1) = graph.incident_vertices(f);
|
||||||
assert!(
|
assert!(
|
||||||
(u1 == v1 && u2 == v2) || (u1 == v2 && u2 == v1),
|
(u0 == v0 && u1 == v1) || (u0 == v1 && u1 == v0),
|
||||||
"unexpected incident vertices {u1:?} and {u2:?} for edge {f:?}"
|
"unexpected incident vertices {u0:?} and {u1:?} for edge {f:?}"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn delete_edge_paired_index() {
|
fn delete_edge_paired_index() {
|
||||||
let mut graph = Graph::new();
|
let (mut graph, _, e) = Graph::single_edge();
|
||||||
let v1 = graph.add_vertex();
|
|
||||||
let v2 = graph.add_vertex();
|
|
||||||
let e = graph.add_edge(v1, v2);
|
|
||||||
let f = graph
|
let f = graph
|
||||||
.incidences
|
.incidences
|
||||||
.get_idx(e.arr_idx() + 1)
|
.get_idx(e.arr_idx() + 1)
|
||||||
@@ -437,9 +432,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn delete_edge_loop_paired_index() {
|
fn delete_edge_loop_paired_index() {
|
||||||
let mut graph = Graph::new();
|
let (mut graph, _, e) = Graph::loop_edge();
|
||||||
let v = graph.add_vertex();
|
|
||||||
let e = graph.add_edge(v, v);
|
|
||||||
let f = graph
|
let f = graph
|
||||||
.incidences
|
.incidences
|
||||||
.get_idx(e.arr_idx() + 1)
|
.get_idx(e.arr_idx() + 1)
|
||||||
@@ -450,23 +443,21 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn reused_slot_returns_old_value() {
|
fn reused_slot_returns_old_value() {
|
||||||
let mut graph = Graph::new();
|
let (mut graph, [_, v], _) = Graph::single_edge();
|
||||||
graph.add_vertex();
|
|
||||||
let v1 = graph.add_vertex();
|
|
||||||
let mut map = graph.vertex_map(0);
|
let mut map = graph.vertex_map(0);
|
||||||
map[v1] = 99;
|
map[v] = 99;
|
||||||
graph.delete_vertex(v1);
|
graph.delete_vertex(v);
|
||||||
let v2 = graph.add_vertex();
|
let u = graph.add_vertex();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
v1.arr_idx(),
|
v.arr_idx(),
|
||||||
v2.arr_idx(),
|
u.arr_idx(),
|
||||||
"precondition: new vertex {v1:?} should reuse slot of deleted vertex {v2:?}"
|
"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
|
// ElementMap uses raw indices, not vertex identity. A new vertex u reusing the slot
|
||||||
// of previously deleted v1 sees the old value. Callers must reinitialize stale slots
|
// of previously deleted v sees the old value. Callers must reinitialize stale slots
|
||||||
// after deletion.
|
// after deletion.
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
map[v2], 99,
|
map[u], 99,
|
||||||
"new vertex reusing slot of deleted vertex should return old value"
|
"new vertex reusing slot of deleted vertex should return old value"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ impl<G: GraphTopologyAddition> MakeTestGraph for G {
|
|||||||
(vertices[7], vertices[8]),
|
(vertices[7], vertices[8]),
|
||||||
(vertices[7], vertices[9]),
|
(vertices[7], vertices[9]),
|
||||||
]
|
]
|
||||||
.map(|(v1, v2)| (graph.add_edge(v1, v2), v1, v2));
|
.map(|(u, v)| (graph.add_edge(u, v), u, v));
|
||||||
let i = |vertex, edge| Incidence { vertex, edge };
|
let i = |vertex, edge| Incidence { vertex, edge };
|
||||||
let incidences = [
|
let incidences = [
|
||||||
vec![i(vertices[1], edges[0].0), i(vertices[1], edges[1].0)],
|
vec![i(vertices[1], edges[0].0), i(vertices[1], edges[1].0)],
|
||||||
@@ -323,13 +323,13 @@ where
|
|||||||
// Walks the path: tracks current vertex, confirms each edge is incident to it.
|
// Walks the path: tracks current vertex, confirms each edge is incident to it.
|
||||||
let mut current = source;
|
let mut current = source;
|
||||||
for (i, &e) in path.iter().enumerate() {
|
for (i, &e) in path.iter().enumerate() {
|
||||||
let (v1, v2) = graph.incident_vertices(e);
|
let (u, v) = graph.incident_vertices(e);
|
||||||
assert_ne!(v1, v2, "path should not contain loop edge {e:?}");
|
assert_ne!(u, v, "path should not contain loop edge {e:?}");
|
||||||
assert!(
|
assert!(
|
||||||
v1 == current || v2 == current,
|
u == current || v == current,
|
||||||
"path edge {e:?} (index {i}, vertices {v1:?} to {v2:?}) not incident to vertex {current:?}"
|
"path edge {e:?} (index {i}, vertices {u:?} to {v:?}) not incident to vertex {current:?}"
|
||||||
);
|
);
|
||||||
current = if v1 == current { v2 } else { v1 };
|
current = if u == current { v } else { u };
|
||||||
}
|
}
|
||||||
assert!(
|
assert!(
|
||||||
targets.contains(¤t),
|
targets.contains(¤t),
|
||||||
|
|||||||
@@ -50,11 +50,11 @@ pub fn delete_edge_add_edge<G: GraphTopologyDeletion + GraphTopologyAddition>()
|
|||||||
where
|
where
|
||||||
G::Edge: Debug,
|
G::Edge: Debug,
|
||||||
{
|
{
|
||||||
let (mut graph, vertices, e) = G::single_edge();
|
let (mut graph, [v0, v1], e) = G::single_edge();
|
||||||
graph.delete_edge(e);
|
graph.delete_edge(e);
|
||||||
assert_eq!(graph.edge_count(), 0, "unexpected edge count after delete");
|
assert_eq!(graph.edge_count(), 0, "unexpected edge count after delete");
|
||||||
assert_ne!(
|
assert_ne!(
|
||||||
graph.add_edge(vertices[0], vertices[1]),
|
graph.add_edge(v0, v1),
|
||||||
e,
|
e,
|
||||||
"unexpected duplicate edge after re-add"
|
"unexpected duplicate edge after re-add"
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -77,12 +77,12 @@ pub fn reserve_edges_increases_capacity<G: GraphTopologyAddition>() {
|
|||||||
|
|
||||||
pub fn reserve_edges_prevents_reallocation_on_add<G: GraphTopologyAddition>() {
|
pub fn reserve_edges_prevents_reallocation_on_add<G: GraphTopologyAddition>() {
|
||||||
let mut graph = G::default();
|
let mut graph = G::default();
|
||||||
let v1 = graph.add_vertex();
|
let u = graph.add_vertex();
|
||||||
let v2 = graph.add_vertex();
|
let v = graph.add_vertex();
|
||||||
graph.reserve_edges(10);
|
graph.reserve_edges(10);
|
||||||
let capacity_before = graph.edge_capacity();
|
let capacity_before = graph.edge_capacity();
|
||||||
for _ in 0..10 {
|
for _ in 0..10 {
|
||||||
graph.add_edge(v1, v2);
|
graph.add_edge(u, v);
|
||||||
}
|
}
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
graph.edge_capacity(),
|
graph.edge_capacity(),
|
||||||
@@ -116,10 +116,10 @@ where
|
|||||||
G::Edge: Debug,
|
G::Edge: Debug,
|
||||||
{
|
{
|
||||||
let mut graph = G::default();
|
let mut graph = G::default();
|
||||||
let v1 = graph.add_vertex();
|
let u = graph.add_vertex();
|
||||||
let v2 = graph.add_vertex();
|
let v = graph.add_vertex();
|
||||||
let e = graph.add_edge(v1, v2);
|
let e = graph.add_edge(u, v);
|
||||||
assert_ne!(graph.add_edge(v1, v2), e, "unexpected duplicate edge");
|
assert_ne!(graph.add_edge(u, v), e, "unexpected duplicate edge");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn vertex_map_new_vertex<G: GraphTopologyAddition>() {
|
pub fn vertex_map_new_vertex<G: GraphTopologyAddition>() {
|
||||||
@@ -139,10 +139,10 @@ pub fn vertex_map_new_vertex<G: GraphTopologyAddition>() {
|
|||||||
|
|
||||||
pub fn edge_map_new_edge<G: GraphTopologyAddition>() {
|
pub fn edge_map_new_edge<G: GraphTopologyAddition>() {
|
||||||
let mut graph = G::default();
|
let mut graph = G::default();
|
||||||
let v1 = graph.add_vertex();
|
let u = graph.add_vertex();
|
||||||
let v2 = graph.add_vertex();
|
let v = graph.add_vertex();
|
||||||
let mut map = graph.edge_map(28);
|
let mut map = graph.edge_map(28);
|
||||||
let e = graph.add_edge(v1, v2);
|
let e = graph.add_edge(u, v);
|
||||||
assert_eq!(map[e], 28);
|
assert_eq!(map[e], 28);
|
||||||
map[e] = 8;
|
map[e] = 8;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn delete_edge<G: GraphTopologyDeletion + GraphTopologyAddition>() {
|
pub fn delete_edge<G: GraphTopologyDeletion + GraphTopologyAddition>() {
|
||||||
let (mut graph, vertices, e) = G::single_edge();
|
let (mut graph, [v0, v1], e) = G::single_edge();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
graph.vertex_count(),
|
graph.vertex_count(),
|
||||||
2,
|
2,
|
||||||
@@ -144,16 +144,16 @@ pub fn delete_edge<G: GraphTopologyDeletion + GraphTopologyAddition>() {
|
|||||||
);
|
);
|
||||||
assert_eq!(graph.edge_count(), 1, "unexpected edge count before delete");
|
assert_eq!(graph.edge_count(), 1, "unexpected edge count before delete");
|
||||||
assert!(
|
assert!(
|
||||||
graph.are_adjacent(vertices[0], vertices[1]),
|
graph.are_adjacent(v0, v1),
|
||||||
"expected vertices to be adjacent before delete"
|
"expected vertices to be adjacent before delete"
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
graph.degree(vertices[0]),
|
graph.degree(v0),
|
||||||
1,
|
1,
|
||||||
"unexpected vertex degree before delete"
|
"unexpected vertex degree before delete"
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
graph.degree(vertices[1]),
|
graph.degree(v1),
|
||||||
1,
|
1,
|
||||||
"unexpected vertex degree before delete"
|
"unexpected vertex degree before delete"
|
||||||
);
|
);
|
||||||
@@ -165,19 +165,11 @@ pub fn delete_edge<G: GraphTopologyDeletion + GraphTopologyAddition>() {
|
|||||||
);
|
);
|
||||||
assert_eq!(graph.edge_count(), 0, "unexpected edge count after delete");
|
assert_eq!(graph.edge_count(), 0, "unexpected edge count after delete");
|
||||||
assert!(
|
assert!(
|
||||||
!graph.are_adjacent(vertices[0], vertices[1]),
|
!graph.are_adjacent(v0, v1),
|
||||||
"unexpected adjacency after delete"
|
"unexpected adjacency after delete"
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(graph.degree(v0), 0, "unexpected vertex degree after delete");
|
||||||
graph.degree(vertices[0]),
|
assert_eq!(graph.degree(v1), 0, "unexpected vertex degree after delete");
|
||||||
0,
|
|
||||||
"unexpected vertex degree after delete"
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
graph.degree(vertices[1]),
|
|
||||||
0,
|
|
||||||
"unexpected vertex degree after delete"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn delete_edge_loop<G: GraphTopologyDeletion + GraphTopologyAddition>() {
|
pub fn delete_edge_loop<G: GraphTopologyDeletion + GraphTopologyAddition>() {
|
||||||
@@ -209,7 +201,7 @@ pub fn delete_edge_loop<G: GraphTopologyDeletion + GraphTopologyAddition>() {
|
|||||||
|
|
||||||
pub fn delete_edge_multiple<G: GraphTopologyDeletion + GraphTopologyAddition>() {
|
pub fn delete_edge_multiple<G: GraphTopologyDeletion + GraphTopologyAddition>() {
|
||||||
const K: usize = 2;
|
const K: usize = 2;
|
||||||
let (mut graph, vertices, edges) = G::multiple_edges::<K>();
|
let (mut graph, [v0, v1], edges) = G::multiple_edges::<K>();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
graph.vertex_count(),
|
graph.vertex_count(),
|
||||||
2,
|
2,
|
||||||
@@ -217,16 +209,16 @@ pub fn delete_edge_multiple<G: GraphTopologyDeletion + GraphTopologyAddition>()
|
|||||||
);
|
);
|
||||||
assert_eq!(graph.edge_count(), K, "unexpected edge count before delete");
|
assert_eq!(graph.edge_count(), K, "unexpected edge count before delete");
|
||||||
assert!(
|
assert!(
|
||||||
graph.are_adjacent(vertices[0], vertices[1]),
|
graph.are_adjacent(v0, v1),
|
||||||
"expected vertices to be adjacent before delete"
|
"expected vertices to be adjacent before delete"
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
graph.degree(vertices[0]),
|
graph.degree(v0),
|
||||||
K,
|
K,
|
||||||
"unexpected vertex degree before delete"
|
"unexpected vertex degree before delete"
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
graph.degree(vertices[1]),
|
graph.degree(v1),
|
||||||
K,
|
K,
|
||||||
"unexpected vertex degree before delete"
|
"unexpected vertex degree before delete"
|
||||||
);
|
);
|
||||||
@@ -242,16 +234,16 @@ pub fn delete_edge_multiple<G: GraphTopologyDeletion + GraphTopologyAddition>()
|
|||||||
"unexpected edge count after delete"
|
"unexpected edge count after delete"
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(
|
||||||
graph.are_adjacent(vertices[0], vertices[1]),
|
graph.are_adjacent(v0, v1),
|
||||||
"expected vertices to be adjacent after delete"
|
"expected vertices to be adjacent after delete"
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
graph.degree(vertices[0]),
|
graph.degree(v0),
|
||||||
K - 1,
|
K - 1,
|
||||||
"unexpected vertex degree after delete"
|
"unexpected vertex degree after delete"
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
graph.degree(vertices[1]),
|
graph.degree(v1),
|
||||||
K - 1,
|
K - 1,
|
||||||
"unexpected vertex degree after delete"
|
"unexpected vertex degree after delete"
|
||||||
);
|
);
|
||||||
@@ -305,11 +297,11 @@ where
|
|||||||
let (mut graph, _, edges, _) = G::standard();
|
let (mut graph, _, edges, _) = G::standard();
|
||||||
let e = edges[2].0;
|
let e = edges[2].0;
|
||||||
graph.delete_edge(e);
|
graph.delete_edge(e);
|
||||||
for &(f, v1, v2) in edges.iter().filter(|&&(f, _, _)| f != e) {
|
for &(f, v0, v1) in edges.iter().filter(|&&(f, _, _)| f != e) {
|
||||||
let (u1, u2) = graph.incident_vertices(f);
|
let (u0, u1) = graph.incident_vertices(f);
|
||||||
assert!(
|
assert!(
|
||||||
(u1 == v1 && u2 == v2) || (u1 == v2 && u2 == v1),
|
(u0 == v0 && u1 == v1) || (u0 == v1 && u1 == v0),
|
||||||
"unexpected incident vertices {u1:?} and {u2:?} for edge {f:?} after delete"
|
"unexpected incident vertices {u0:?} and {u1:?} for edge {f:?} after delete"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -135,25 +135,12 @@ where
|
|||||||
G::Vertex: Debug,
|
G::Vertex: Debug,
|
||||||
{
|
{
|
||||||
const K: usize = 3;
|
const K: usize = 3;
|
||||||
let (graph, vertices, _) = G::multiple_edges::<K>();
|
let (graph, [v0, v1], _) = G::multiple_edges::<K>();
|
||||||
assert_eq!(graph.vertex_count(), 2, "unexpected vertex count");
|
assert_eq!(graph.vertex_count(), 2, "unexpected vertex count");
|
||||||
assert_eq!(graph.edge_count(), K, "unexpected edge count");
|
assert_eq!(graph.edge_count(), K, "unexpected edge count");
|
||||||
assert_eq!(
|
assert_eq!(graph.degree(v0), K, "unexpected degree of vertex {v0:?}");
|
||||||
graph.degree(vertices[0]),
|
assert_eq!(graph.degree(v1), K, "unexpected degree of vertex {v1:?}",);
|
||||||
K,
|
assert!(graph.are_adjacent(v0, v1), "should be adjacent");
|
||||||
"unexpected degree of vertex {:?}",
|
|
||||||
vertices[0]
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
graph.degree(vertices[1]),
|
|
||||||
K,
|
|
||||||
"unexpected degree of vertex {:?}",
|
|
||||||
vertices[1]
|
|
||||||
);
|
|
||||||
assert!(
|
|
||||||
graph.are_adjacent(vertices[0], vertices[1]),
|
|
||||||
"should be adjacent"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn are_adjacent_vertex_self<G: MakeTestGraph>() {
|
pub fn are_adjacent_vertex_self<G: MakeTestGraph>() {
|
||||||
@@ -165,15 +152,9 @@ pub fn are_adjacent_vertex_self<G: MakeTestGraph>() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn are_adjacent_single_edge<G: MakeTestGraph>() {
|
pub fn are_adjacent_single_edge<G: MakeTestGraph>() {
|
||||||
let (graph, vertices, _) = G::single_edge();
|
let (graph, [v0, v1], _) = G::single_edge();
|
||||||
assert!(
|
assert!(graph.are_adjacent(v0, v1), "should be adjacent");
|
||||||
graph.are_adjacent(vertices[0], vertices[1]),
|
assert!(graph.are_adjacent(v1, v0), "should be adjacent");
|
||||||
"should be adjacent"
|
|
||||||
);
|
|
||||||
assert!(
|
|
||||||
graph.are_adjacent(vertices[1], vertices[0]),
|
|
||||||
"should be adjacent"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn are_adjacent<G: MakeTestGraph>()
|
pub fn are_adjacent<G: MakeTestGraph>()
|
||||||
@@ -341,11 +322,11 @@ where
|
|||||||
G::Vertex: Debug,
|
G::Vertex: Debug,
|
||||||
G::Edge: Debug,
|
G::Edge: Debug,
|
||||||
{
|
{
|
||||||
let (graph, vertices, e) = G::single_edge();
|
let (graph, [v0, v1], e) = G::single_edge();
|
||||||
let (u, v) = graph.incident_vertices(e);
|
let (u0, u1) = graph.incident_vertices(e);
|
||||||
assert!(
|
assert!(
|
||||||
(u == vertices[0] && v == vertices[1]) || (u == vertices[1] && v == vertices[0]),
|
(u0 == v0 && u1 == v1) || (u0 == v1 && u1 == v0),
|
||||||
"unexpected incident vertices {u:?} and {v:?} for edge {e:?}"
|
"unexpected incident vertices {u0:?} and {u1:?} for edge {e:?}"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -367,20 +348,16 @@ where
|
|||||||
G::Vertex: Debug,
|
G::Vertex: Debug,
|
||||||
G::Edge: Debug,
|
G::Edge: Debug,
|
||||||
{
|
{
|
||||||
let (graph, vertices, edges) = G::multiple_edges::<2>();
|
let (graph, [v0, v1], edges) = G::multiple_edges::<2>();
|
||||||
assert_ne!(edges[0], edges[1], "edges should be distinct");
|
assert_ne!(edges[0], edges[1], "edges should be distinct");
|
||||||
let (u, v) = graph.incident_vertices(edges[0]);
|
for i in 0..2 {
|
||||||
assert!(
|
let (u0, u1) = graph.incident_vertices(edges[i]);
|
||||||
(u == vertices[0] && v == vertices[1]) || (u == vertices[1] && v == vertices[0]),
|
assert!(
|
||||||
"unexpected incident vertices {u:?} and {v:?} for first multi-edge {:?}",
|
(u0 == v0 && u1 == v1) || (u0 == v1 && u1 == v0),
|
||||||
edges[0]
|
"unexpected incident vertices {u0:?} and {u1:?} for multi-edge {:?} (index {i})",
|
||||||
);
|
edges[i]
|
||||||
let (u, v) = graph.incident_vertices(edges[1]);
|
);
|
||||||
assert!(
|
}
|
||||||
(u == vertices[0] && v == vertices[1]) || (u == vertices[1] && v == vertices[0]),
|
|
||||||
"unexpected incident vertices {u:?} and {v:?} for second multi-edge {:?}",
|
|
||||||
edges[1]
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn incident_vertices<G: MakeTestGraph>()
|
pub fn incident_vertices<G: MakeTestGraph>()
|
||||||
@@ -389,11 +366,11 @@ where
|
|||||||
G::Edge: Debug,
|
G::Edge: Debug,
|
||||||
{
|
{
|
||||||
let (graph, _, edges, _) = G::standard();
|
let (graph, _, edges, _) = G::standard();
|
||||||
for &(e, v1, v2) in edges.iter() {
|
for &(e, v0, v1) in edges.iter() {
|
||||||
let (u1, u2) = graph.incident_vertices(e);
|
let (u0, u1) = graph.incident_vertices(e);
|
||||||
assert!(
|
assert!(
|
||||||
(u1 == v1 && u2 == v2) || (u1 == v2 && u2 == v1),
|
(u0 == v0 && u1 == v1) || (u0 == v1 && u1 == v0),
|
||||||
"unexpected incident vertices {u1:?} and {u2:?} for edge {e:?}"
|
"unexpected incident vertices {u0:?} and {u1:?} for edge {e:?}"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -741,8 +718,8 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn incidence_cursor_copy<G: MakeTestGraph>() {
|
pub fn incidence_cursor_copy<G: MakeTestGraph>() {
|
||||||
let (graph, vertices, _) = G::two_edge_path();
|
let (graph, [_, v, _], _) = G::two_edge_path();
|
||||||
let mut c1 = graph.incidence_cursor(vertices[1]);
|
let mut c1 = graph.incidence_cursor(v);
|
||||||
assert!(c1.next(&graph).is_some(), "expected first incidence");
|
assert!(c1.next(&graph).is_some(), "expected first incidence");
|
||||||
let mut c2 = c1;
|
let mut c2 = c1;
|
||||||
assert!(
|
assert!(
|
||||||
|
|||||||
+6
-6
@@ -101,14 +101,14 @@ pub trait GraphTopology {
|
|||||||
/// Panics if `v` is not a valid vertex of this graph.
|
/// Panics if `v` is not a valid vertex of this graph.
|
||||||
fn degree(&self, v: Self::Vertex) -> usize;
|
fn degree(&self, v: Self::Vertex) -> usize;
|
||||||
|
|
||||||
/// Returns `true` if there is at least one edge between `v1` and `v2`, and `false` otherwise.
|
/// Returns `true` if there is at least one edge between `u` and `v`, and `false` otherwise.
|
||||||
///
|
///
|
||||||
/// A vertex is adjacent to itself if and only if it has a loop edge.
|
/// A vertex is adjacent to itself if and only if it has a loop edge.
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// Panics if `v1` or `v2` is not a valid vertex of this graph.
|
/// Panics if `u` or `v` is not a valid vertex of this graph.
|
||||||
fn are_adjacent(&self, v1: Self::Vertex, v2: Self::Vertex) -> bool;
|
fn are_adjacent(&self, u: Self::Vertex, v: Self::Vertex) -> bool;
|
||||||
|
|
||||||
/// Returns an iterator over all vertices in the graph.
|
/// Returns an iterator over all vertices in the graph.
|
||||||
fn vertices(&self) -> impl Iterator<Item = Self::Vertex>;
|
fn vertices(&self) -> impl Iterator<Item = Self::Vertex>;
|
||||||
@@ -206,12 +206,12 @@ pub trait GraphTopologyAddition: GraphTopology + Default {
|
|||||||
/// Adds a new isolated vertex and returns its handle.
|
/// Adds a new isolated vertex and returns its handle.
|
||||||
fn add_vertex(&mut self) -> Self::Vertex;
|
fn add_vertex(&mut self) -> Self::Vertex;
|
||||||
|
|
||||||
/// Adds a new edge between `v1` and `v2` and returns its handle.
|
/// Adds a new edge between `u` and `v` and returns its handle.
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// Panics if `v1` or `v2` is not a valid vertex of this graph.
|
/// Panics if `u` or `v` is not a valid vertex of this graph.
|
||||||
fn add_edge(&mut self, v1: Self::Vertex, v2: Self::Vertex) -> Self::Edge;
|
fn add_edge(&mut self, u: Self::Vertex, v: Self::Vertex) -> Self::Edge;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A trait that adds deletion operations to an undirected graph topology.
|
/// A trait that adds deletion operations to an undirected graph topology.
|
||||||
|
|||||||
+15
-16
@@ -161,9 +161,9 @@ fn bfs_find_source<G: MakeTestGraph>() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn bfs_find_disconnected<G: MakeTestGraph>() {
|
fn bfs_find_disconnected<G: MakeTestGraph>() {
|
||||||
let (graph, vertices) = G::disconnected();
|
let (graph, [v0, v1, _]) = G::disconnected();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
algorithms::bfs_find(&graph, vertices[0], vertices[1]),
|
algorithms::bfs_find(&graph, v0, v1),
|
||||||
None,
|
None,
|
||||||
"disconnected target should not be found"
|
"disconnected target should not be found"
|
||||||
);
|
);
|
||||||
@@ -196,12 +196,11 @@ fn bfs_find_where_disconnected<G: MakeTestGraph>()
|
|||||||
where
|
where
|
||||||
G::Vertex: Debug,
|
G::Vertex: Debug,
|
||||||
{
|
{
|
||||||
let (graph, vertices) = G::disconnected();
|
let (graph, [v0, v1, _]) = G::disconnected();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
algorithms::bfs_find_where(&graph, vertices[0], |v| v == vertices[1]),
|
algorithms::bfs_find_where(&graph, v0, |v| v == v1),
|
||||||
None,
|
None,
|
||||||
"disconnected vertex {:?} should not be found",
|
"disconnected vertex {v1:?} should not be found"
|
||||||
vertices[1]
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,9 +208,9 @@ fn bfs_find_where_no_match<G: MakeTestGraph>()
|
|||||||
where
|
where
|
||||||
G::Vertex: Debug,
|
G::Vertex: Debug,
|
||||||
{
|
{
|
||||||
let (graph, vertices, _, _) = G::standard();
|
let (graph, [v0, ..], _, _) = G::standard();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
algorithms::bfs_find_where(&graph, vertices[0], |_| false),
|
algorithms::bfs_find_where(&graph, v0, |_| false),
|
||||||
None,
|
None,
|
||||||
"no vertex should match an always-false predicate"
|
"no vertex should match an always-false predicate"
|
||||||
);
|
);
|
||||||
@@ -258,9 +257,9 @@ fn bfs_find_path_disconnected<G: MakeTestGraph>()
|
|||||||
where
|
where
|
||||||
G::Edge: Debug,
|
G::Edge: Debug,
|
||||||
{
|
{
|
||||||
let (graph, vertices) = G::disconnected();
|
let (graph, [v0, v1, _]) = G::disconnected();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
algorithms::bfs_find_path(&graph, vertices[0], vertices[1]),
|
algorithms::bfs_find_path(&graph, v0, v1),
|
||||||
None,
|
None,
|
||||||
"no path should exist to disconnected vertex"
|
"no path should exist to disconnected vertex"
|
||||||
);
|
);
|
||||||
@@ -270,8 +269,8 @@ fn bfs_find_path_adjacent<G: MakeTestGraph>()
|
|||||||
where
|
where
|
||||||
G::Edge: Debug,
|
G::Edge: Debug,
|
||||||
{
|
{
|
||||||
let (graph, vertices, e) = G::single_edge();
|
let (graph, [v0, v1], e) = G::single_edge();
|
||||||
let path = algorithms::bfs_find_path(&graph, vertices[0], vertices[1])
|
let path = algorithms::bfs_find_path(&graph, v0, v1)
|
||||||
.expect("path should exist between adjacent vertices");
|
.expect("path should exist between adjacent vertices");
|
||||||
assert_eq!(path, [e], "path should contain only the connecting edge");
|
assert_eq!(path, [e], "path should contain only the connecting edge");
|
||||||
}
|
}
|
||||||
@@ -308,9 +307,9 @@ fn bfs_find_path_where_disconnected<G: MakeTestGraph>()
|
|||||||
where
|
where
|
||||||
G::Edge: Debug,
|
G::Edge: Debug,
|
||||||
{
|
{
|
||||||
let (graph, vertices) = G::disconnected();
|
let (graph, [v0, v1, _]) = G::disconnected();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
algorithms::bfs_find_path_where(&graph, vertices[0], |v| v == vertices[1]),
|
algorithms::bfs_find_path_where(&graph, v0, |v| v == v1),
|
||||||
None,
|
None,
|
||||||
"no path should exist to disconnected vertex"
|
"no path should exist to disconnected vertex"
|
||||||
);
|
);
|
||||||
@@ -320,9 +319,9 @@ fn bfs_find_path_where_no_match<G: MakeTestGraph>()
|
|||||||
where
|
where
|
||||||
G::Edge: Debug,
|
G::Edge: Debug,
|
||||||
{
|
{
|
||||||
let (graph, vertices, _, _) = G::standard();
|
let (graph, [v0, ..], _, _) = G::standard();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
algorithms::bfs_find_path_where(&graph, vertices[0], |_| false),
|
algorithms::bfs_find_path_where(&graph, v0, |_| false),
|
||||||
None,
|
None,
|
||||||
"no path should exist when predicate never matches"
|
"no path should exist when predicate never matches"
|
||||||
);
|
);
|
||||||
|
|||||||
+18
-19
@@ -150,9 +150,9 @@ fn dfs_find_source<G: MakeTestGraph>() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn dfs_find_disconnected<G: MakeTestGraph>() {
|
fn dfs_find_disconnected<G: MakeTestGraph>() {
|
||||||
let (graph, vertices) = G::disconnected();
|
let (graph, [v0, v1, _]) = G::disconnected();
|
||||||
assert!(
|
assert!(
|
||||||
!algorithms::dfs_find(&graph, vertices[0], vertices[1]),
|
!algorithms::dfs_find(&graph, v0, v1),
|
||||||
"disconnected target should not be found"
|
"disconnected target should not be found"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -188,12 +188,11 @@ fn dfs_find_where_disconnected<G: MakeTestGraph>()
|
|||||||
where
|
where
|
||||||
G::Vertex: Debug,
|
G::Vertex: Debug,
|
||||||
{
|
{
|
||||||
let (graph, vertices) = G::disconnected();
|
let (graph, [v0, v1, _]) = G::disconnected();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
algorithms::dfs_find_where(&graph, vertices[0], |v| v == vertices[1]),
|
algorithms::dfs_find_where(&graph, v0, |v| v == v1),
|
||||||
None,
|
None,
|
||||||
"disconnected vertex {:?} should not be found",
|
"disconnected vertex {v1:?} should not be found"
|
||||||
vertices[1]
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,9 +200,9 @@ fn dfs_find_where_no_match<G: MakeTestGraph>()
|
|||||||
where
|
where
|
||||||
G::Vertex: Debug,
|
G::Vertex: Debug,
|
||||||
{
|
{
|
||||||
let (graph, vertices, _, _) = G::standard();
|
let (graph, [v0, ..], _, _) = G::standard();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
algorithms::dfs_find_where(&graph, vertices[0], |_| false),
|
algorithms::dfs_find_where(&graph, v0, |_| false),
|
||||||
None,
|
None,
|
||||||
"no vertex should match an always-false predicate"
|
"no vertex should match an always-false predicate"
|
||||||
);
|
);
|
||||||
@@ -213,10 +212,10 @@ fn dfs_find_where_adjacent<G: MakeTestGraph>()
|
|||||||
where
|
where
|
||||||
G::Vertex: Debug,
|
G::Vertex: Debug,
|
||||||
{
|
{
|
||||||
let (graph, vertices, _, _) = G::standard();
|
let (graph, [v0, v1, ..], _, _) = G::standard();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
algorithms::dfs_find_where(&graph, vertices[0], |v| v == vertices[1]),
|
algorithms::dfs_find_where(&graph, v0, |v| v == v1),
|
||||||
Some(vertices[1]),
|
Some(v1),
|
||||||
"expected to find adjacent vertex"
|
"expected to find adjacent vertex"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -249,9 +248,9 @@ fn dfs_find_path_disconnected<G: MakeTestGraph>()
|
|||||||
where
|
where
|
||||||
G::Edge: Debug,
|
G::Edge: Debug,
|
||||||
{
|
{
|
||||||
let (graph, vertices) = G::disconnected();
|
let (graph, [v0, v1, _]) = G::disconnected();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
algorithms::dfs_find_path(&graph, vertices[0], vertices[1]),
|
algorithms::dfs_find_path(&graph, v0, v1),
|
||||||
None,
|
None,
|
||||||
"no path should exist to disconnected vertex"
|
"no path should exist to disconnected vertex"
|
||||||
);
|
);
|
||||||
@@ -261,8 +260,8 @@ fn dfs_find_path_adjacent<G: MakeTestGraph>()
|
|||||||
where
|
where
|
||||||
G::Edge: Debug,
|
G::Edge: Debug,
|
||||||
{
|
{
|
||||||
let (graph, vertices, e) = G::single_edge();
|
let (graph, [v0, v1], e) = G::single_edge();
|
||||||
let path = algorithms::dfs_find_path(&graph, vertices[0], vertices[1])
|
let path = algorithms::dfs_find_path(&graph, v0, v1)
|
||||||
.expect("path should exist between adjacent vertices");
|
.expect("path should exist between adjacent vertices");
|
||||||
assert_eq!(path, [e], "path should contain only the connecting edge");
|
assert_eq!(path, [e], "path should contain only the connecting edge");
|
||||||
}
|
}
|
||||||
@@ -293,9 +292,9 @@ fn dfs_find_path_where_disconnected<G: MakeTestGraph>()
|
|||||||
where
|
where
|
||||||
G::Edge: Debug,
|
G::Edge: Debug,
|
||||||
{
|
{
|
||||||
let (graph, vertices) = G::disconnected();
|
let (graph, [v0, v1, _]) = G::disconnected();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
algorithms::dfs_find_path_where(&graph, vertices[0], |v| v == vertices[1]),
|
algorithms::dfs_find_path_where(&graph, v0, |v| v == v1),
|
||||||
None,
|
None,
|
||||||
"no path should exist to disconnected vertex"
|
"no path should exist to disconnected vertex"
|
||||||
);
|
);
|
||||||
@@ -305,9 +304,9 @@ fn dfs_find_path_where_no_match<G: MakeTestGraph>()
|
|||||||
where
|
where
|
||||||
G::Edge: Debug,
|
G::Edge: Debug,
|
||||||
{
|
{
|
||||||
let (graph, vertices, _, _) = G::standard();
|
let (graph, [v0, ..], _, _) = G::standard();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
algorithms::dfs_find_path_where(&graph, vertices[0], |_| false),
|
algorithms::dfs_find_path_where(&graph, v0, |_| false),
|
||||||
None,
|
None,
|
||||||
"no path should exist when predicate never matches"
|
"no path should exist when predicate never matches"
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user