Refactor graph creation in all tests into new internal MakeTestGraph trait

This large refactor allows future re-use of the existing tests for `FrozenGraph`, which does not implement `GraphTopologyAddition`, but instead has to convert from a different graph which does.

- Fix tests for `GraphTopologyDeletion` hard-coding Graph instead of using the trait.
- Fix some tests silently depending on macro call site uses.
- Change `GraphTopologyAddition` tests to use `Default::default` instead of `new`.
- Add new tests for `GraphTopology::vertex_map` and `edge_map` that also depend on `GraphTopologyAddition`, removing these dependencies from the existing tests.
- Add new test macro `graph_topology_addition_deletion_tests` for tests that need deletion and addition.
This commit is contained in:
2026-08-29 22:38:27 +02:00
parent 1185e3b667
commit 7fbd5eed9d
12 changed files with 509 additions and 590 deletions
+1 -1
View File
@@ -149,4 +149,4 @@ pub mod prelude {
};
}
mod testing;
pub mod testing;
+7 -3
View File
@@ -239,12 +239,16 @@ impl GraphTopologyAddition for AppendGraph {
}
#[cfg(test)]
mod tests {
use super::*;
mod trait_tests {
use super::AppendGraph;
crate::graph_topology_test_fixtures!(AppendGraph);
crate::graph_topology_tests!(AppendGraph);
crate::graph_topology_addition_tests!(AppendGraph);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn incident_vertices_paired_index() {
+8 -3
View File
@@ -378,13 +378,18 @@ impl GraphTopologyDeletion for Graph {
}
#[cfg(test)]
mod tests {
use super::*;
mod trait_tests {
use super::Graph;
crate::graph_topology_test_fixtures!(Graph);
crate::graph_topology_tests!(Graph);
crate::graph_topology_addition_tests!(Graph);
crate::graph_topology_deletion_tests!(Graph);
crate::graph_topology_addition_deletion_tests!(Graph);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn incident_vertices_paired_index() {
+3
View File
@@ -4,3 +4,6 @@ pub(crate) mod bfs_testing;
pub(crate) mod dfs_testing;
pub(crate) mod dijkstra_testing;
pub(crate) mod graph_topology_testing;
#[doc(hidden)]
pub mod fixtures;
+24 -21
View File
@@ -4,9 +4,7 @@ macro_rules! bfs_tests {
($T:ty) => {
#[test]
fn bfs_single_vertex() {
use $crate::traits::GraphTopologyAddition;
let mut graph = <$T>::new();
let v = graph.add_vertex();
let (graph, v): ($T, _) = $crate::testing::fixtures::MakeTestGraph::single_vertex();
let result = $crate::algorithms::bfs(&graph, v);
assert_eq!(
result.distances[v],
@@ -21,7 +19,8 @@ macro_rules! bfs_tests {
#[test]
fn bfs_disconnected() {
let (graph, vertices) = make_test_graph_disconnected();
let (graph, vertices): ($T, _) =
$crate::testing::fixtures::MakeTestGraph::disconnected();
let result = $crate::algorithms::bfs(&graph, vertices[0]);
assert_eq!(
result.distances[vertices[0]],
@@ -46,7 +45,8 @@ macro_rules! bfs_tests {
#[test]
fn bfs() {
let (graph, vertices, _, _) = make_test_graph();
let (graph, vertices, _, _): ($T, _, _, _) =
$crate::testing::fixtures::MakeTestGraph::standard();
let result = $crate::algorithms::bfs(&graph, vertices[0]);
assert_bfs_distances(&result.distances, &vertices);
assert_bfs_predecessors(&result.predecessors, &vertices);
@@ -54,9 +54,7 @@ macro_rules! bfs_tests {
#[test]
fn bfs_distances_single_vertex() {
use $crate::traits::GraphTopologyAddition;
let mut graph = <$T>::new();
let v = graph.add_vertex();
let (graph, v): ($T, _) = $crate::testing::fixtures::MakeTestGraph::single_vertex();
let distances = $crate::algorithms::bfs_distances(&graph, v);
assert_eq!(
distances[v],
@@ -67,7 +65,8 @@ macro_rules! bfs_tests {
#[test]
fn bfs_distances_disconnected() {
let (graph, vertices) = make_test_graph_disconnected();
let (graph, vertices): ($T, _) =
$crate::testing::fixtures::MakeTestGraph::disconnected();
let distances = $crate::algorithms::bfs_distances(&graph, vertices[0]);
assert_eq!(
distances[vertices[0]],
@@ -84,16 +83,15 @@ macro_rules! bfs_tests {
#[test]
fn bfs_distances() {
let (graph, vertices, _, _) = make_test_graph();
let (graph, vertices, _, _): ($T, _, _, _) =
$crate::testing::fixtures::MakeTestGraph::standard();
let distances = $crate::algorithms::bfs_distances(&graph, vertices[0]);
assert_bfs_distances(&distances, &vertices);
}
#[test]
fn bfs_find_source() {
use $crate::traits::GraphTopologyAddition;
let mut graph = <$T>::new();
let v = graph.add_vertex();
let (graph, v): ($T, _) = $crate::testing::fixtures::MakeTestGraph::single_vertex();
assert_eq!(
$crate::algorithms::bfs_find(&graph, v, v),
Some(0),
@@ -103,7 +101,8 @@ macro_rules! bfs_tests {
#[test]
fn bfs_find_disconnected() {
let (graph, vertices) = make_test_graph_disconnected();
let (graph, vertices): ($T, _) =
$crate::testing::fixtures::MakeTestGraph::disconnected();
assert_eq!(
$crate::algorithms::bfs_find(&graph, vertices[0], vertices[1]),
None,
@@ -113,7 +112,8 @@ macro_rules! bfs_tests {
#[test]
fn bfs_find() {
let (graph, vertices, _, _) = make_test_graph();
let (graph, vertices, _, _): ($T, _, _, _) =
$crate::testing::fixtures::MakeTestGraph::standard();
let expected_distances = [
Some(0),
Some(1),
@@ -139,9 +139,7 @@ macro_rules! bfs_tests {
#[test]
fn bfs_find_where_source_matches() {
use $crate::traits::GraphTopologyAddition;
let mut graph = <$T>::new();
let v = graph.add_vertex();
let (graph, v): ($T, _) = $crate::testing::fixtures::MakeTestGraph::single_vertex();
assert_eq!(
$crate::algorithms::bfs_find_where(&graph, v, |u| u == v),
Some((v, 0)),
@@ -151,7 +149,8 @@ macro_rules! bfs_tests {
#[test]
fn bfs_find_where_disconnected() {
let (graph, vertices) = make_test_graph_disconnected();
let (graph, vertices): ($T, _) =
$crate::testing::fixtures::MakeTestGraph::disconnected();
assert_eq!(
$crate::algorithms::bfs_find_where(&graph, vertices[0], |v| v == vertices[1]),
None,
@@ -162,7 +161,8 @@ macro_rules! bfs_tests {
#[test]
fn bfs_find_where_no_match() {
let (graph, vertices, _, _) = make_test_graph();
let (graph, vertices, _, _): ($T, _, _, _) =
$crate::testing::fixtures::MakeTestGraph::standard();
assert_eq!(
$crate::algorithms::bfs_find_where(&graph, vertices[0], |_| false),
None,
@@ -172,7 +172,8 @@ macro_rules! bfs_tests {
#[test]
fn bfs_find_where_nearest() {
let (graph, vertices, _, _) = make_test_graph();
let (graph, vertices, _, _): ($T, _, _, _) =
$crate::testing::fixtures::MakeTestGraph::standard();
// vertices[5], vertices[6], vertices[7], vertices[8] are all at distance 3 from vertices[0].
// vertices[9] is at distance 4. Predicate matches vertices[7], vertices[8], vertices[9].
// BFS must return one of the distance-3 ones, not vertices[9].
@@ -193,6 +194,7 @@ macro_rules! bfs_tests {
);
}
// TODO: Move out of macro.
fn assert_bfs_distances(
distances: &$crate::maps::ElementMap<
<$T as $crate::traits::GraphTopology>::Vertex,
@@ -221,6 +223,7 @@ macro_rules! bfs_tests {
}
}
// TODO: Move out of macro.
fn assert_bfs_predecessors(
predecessors: &$crate::maps::ElementMap<
<$T as $crate::traits::GraphTopology>::Vertex,
+27 -44
View File
@@ -4,9 +4,7 @@ macro_rules! dfs_tests {
($T:ty) => {
#[test]
fn dfs_single_vertex() {
use $crate::traits::GraphTopologyAddition;
let mut graph = <$T>::new();
let v = graph.add_vertex();
let (graph, v): ($T, _) = $crate::testing::fixtures::MakeTestGraph::single_vertex();
let result = $crate::algorithms::dfs(&graph, v);
assert!(result.visited[v], "source vertex should be visited");
assert_eq!(
@@ -17,7 +15,7 @@ macro_rules! dfs_tests {
#[test]
fn dfs_disconnected() {
let (graph, vertices) = make_test_graph_disconnected();
let (graph, vertices): ($T, _) = $crate::testing::fixtures::MakeTestGraph::disconnected();
let result = $crate::algorithms::dfs(&graph, vertices[0]);
assert!(
result.visited[vertices[0]],
@@ -41,7 +39,7 @@ macro_rules! dfs_tests {
#[test]
fn dfs() {
let (graph, vertices, _, _) = make_test_graph();
let (graph, vertices, _, _): ($T, _, _, _) = $crate::testing::fixtures::MakeTestGraph::standard();
let result = $crate::algorithms::dfs(&graph, vertices[0]);
assert_dfs_visited(&result.visited, &vertices);
assert_dfs_predecessors(&graph, &result.visited, &result.predecessors, &vertices);
@@ -49,16 +47,14 @@ macro_rules! dfs_tests {
#[test]
fn dfs_visited_single_vertex() {
use $crate::traits::GraphTopologyAddition;
let mut graph = <$T>::new();
let v = graph.add_vertex();
let (graph, v): ($T, _) = $crate::testing::fixtures::MakeTestGraph::single_vertex();
let visited = $crate::algorithms::dfs_visited(&graph, v);
assert!(visited[v], "source vertex should be visited");
}
#[test]
fn dfs_visited_disconnected() {
let (graph, vertices) = make_test_graph_disconnected();
let (graph, vertices): ($T, _) = $crate::testing::fixtures::MakeTestGraph::disconnected();
let visited = $crate::algorithms::dfs_visited(&graph, vertices[0]);
assert!(visited[vertices[0]], "source vertex should be visited");
for &v in &vertices[1..3] {
@@ -71,16 +67,14 @@ macro_rules! dfs_tests {
#[test]
fn dfs_visited() {
let (graph, vertices, _, _) = make_test_graph();
let (graph, vertices, _, _): ($T, _, _, _) = $crate::testing::fixtures::MakeTestGraph::standard();
let visited = $crate::algorithms::dfs_visited(&graph, vertices[0]);
assert_dfs_visited(&visited, &vertices);
}
#[test]
fn dfs_find_source() {
use $crate::traits::GraphTopologyAddition;
let mut graph = <$T>::new();
let v = graph.add_vertex();
let (graph, v): ($T, _) = $crate::testing::fixtures::MakeTestGraph::single_vertex();
assert!(
$crate::algorithms::dfs_find(&graph, v, v),
"source should find itself"
@@ -89,7 +83,7 @@ macro_rules! dfs_tests {
#[test]
fn dfs_find_disconnected() {
let (graph, vertices) = make_test_graph_disconnected();
let (graph, vertices): ($T, _) = $crate::testing::fixtures::MakeTestGraph::disconnected();
assert!(
!$crate::algorithms::dfs_find(&graph, vertices[0], vertices[1]),
"disconnected target should not be found"
@@ -98,7 +92,7 @@ macro_rules! dfs_tests {
#[test]
fn dfs_find() {
let (graph, vertices, _, _) = make_test_graph();
let (graph, vertices, _, _): ($T, _, _, _) = $crate::testing::fixtures::MakeTestGraph::standard();
for i in 0..10 {
assert!(
$crate::algorithms::dfs_find(&graph, vertices[0], vertices[i]),
@@ -111,9 +105,7 @@ macro_rules! dfs_tests {
#[test]
fn dfs_find_where_source_matches() {
use $crate::traits::GraphTopologyAddition;
let mut graph = <$T>::new();
let v = graph.add_vertex();
let (graph, v): ($T, _) = $crate::testing::fixtures::MakeTestGraph::single_vertex();
assert_eq!(
$crate::algorithms::dfs_find_where(&graph, v, |u| u == v),
Some(v),
@@ -123,7 +115,7 @@ macro_rules! dfs_tests {
#[test]
fn dfs_find_where_disconnected() {
let (graph, vertices) = make_test_graph_disconnected();
let (graph, vertices): ($T, _) = $crate::testing::fixtures::MakeTestGraph::disconnected();
assert_eq!(
$crate::algorithms::dfs_find_where(&graph, vertices[0], |v| v == vertices[1]),
None,
@@ -134,7 +126,7 @@ macro_rules! dfs_tests {
#[test]
fn dfs_find_where_no_match() {
let (graph, vertices, _, _) = make_test_graph();
let (graph, vertices, _, _): ($T, _, _, _) = $crate::testing::fixtures::MakeTestGraph::standard();
assert_eq!(
$crate::algorithms::dfs_find_where(&graph, vertices[0], |_| false),
None,
@@ -144,7 +136,7 @@ macro_rules! dfs_tests {
#[test]
fn dfs_find_where_adjacent() {
let (graph, vertices, _, _) = make_test_graph();
let (graph, vertices, _, _): ($T, _, _, _) = $crate::testing::fixtures::MakeTestGraph::standard();
assert_eq!(
$crate::algorithms::dfs_find_where(&graph, vertices[0], |v| v == vertices[1]),
Some(vertices[1]),
@@ -154,7 +146,7 @@ macro_rules! dfs_tests {
#[test]
fn dfs_find_where() {
let (graph, vertices, _, _) = make_test_graph();
let (graph, vertices, _, _): ($T, _, _, _) = $crate::testing::fixtures::MakeTestGraph::standard();
assert_eq!(
$crate::algorithms::dfs_find_where(&graph, vertices[0], |v| v == vertices[9]),
Some(vertices[9]),
@@ -162,6 +154,7 @@ macro_rules! dfs_tests {
);
}
// TODO: Move out of macro.
fn assert_dfs_visited(
visited: &$crate::maps::ElementMap<<$T as $crate::traits::GraphTopology>::Vertex, bool>,
vertices: &[<$T as $crate::traits::GraphTopology>::Vertex],
@@ -175,6 +168,7 @@ macro_rules! dfs_tests {
}
}
// TODO: Move out of macro.
fn assert_dfs_predecessors(
graph: &$T,
visited: &$crate::maps::ElementMap<<$T as $crate::traits::GraphTopology>::Vertex, bool>,
@@ -205,9 +199,7 @@ macro_rules! dfs_tests {
#[test]
fn dfs_find_path_source_equals_target() {
use $crate::traits::GraphTopologyAddition;
let mut graph = <$T>::new();
let v = graph.add_vertex();
let (graph, v): ($T, _) = $crate::testing::fixtures::MakeTestGraph::single_vertex();
assert_eq!(
$crate::algorithms::dfs_find_path(&graph, v, v),
Some(vec![]),
@@ -217,7 +209,7 @@ macro_rules! dfs_tests {
#[test]
fn dfs_find_path_disconnected() {
let (graph, vertices) = make_test_graph_disconnected();
let (graph, vertices): ($T, _) = $crate::testing::fixtures::MakeTestGraph::disconnected();
assert_eq!(
$crate::algorithms::dfs_find_path(&graph, vertices[0], vertices[1]),
None,
@@ -227,24 +219,16 @@ macro_rules! dfs_tests {
#[test]
fn dfs_find_path_adjacent() {
use $crate::traits::GraphTopologyAddition;
let mut graph = <$T>::new();
let v1 = graph.add_vertex();
let v2 = graph.add_vertex();
let e = graph.add_edge(v1, v2);
let path = $crate::algorithms::dfs_find_path(&graph, v1, v2)
let (graph, vertices, e): ($T, _, _) = $crate::testing::fixtures::MakeTestGraph::single_edge();
let path = $crate::algorithms::dfs_find_path(&graph, vertices[0], vertices[1])
.expect("path should exist between adjacent vertices");
assert_eq!(
path.len(),
1,
"unexpected path length between adjacent vertices"
);
assert_eq!(path.len(), 1, "unexpected path length between adjacent vertices");
assert_eq!(path[0], e, "path should use the connecting edge");
}
#[test]
fn dfs_find_path() {
let (graph, vertices, _, _) = make_test_graph();
let (graph, vertices, _, _): ($T, _, _, _) = $crate::testing::fixtures::MakeTestGraph::standard();
let path = $crate::algorithms::dfs_find_path(&graph, vertices[0], vertices[9])
.expect(&format!(
"path should exist between connected vertices {:?} and {:?}",
@@ -255,9 +239,7 @@ macro_rules! dfs_tests {
#[test]
fn dfs_find_path_where_source_matches() {
use $crate::traits::GraphTopologyAddition;
let mut graph = <$T>::new();
let v = graph.add_vertex();
let (graph, v): ($T, _) = $crate::testing::fixtures::MakeTestGraph::single_vertex();
assert_eq!(
$crate::algorithms::dfs_find_path_where(&graph, v, |u| u == v),
Some(vec![]),
@@ -267,7 +249,7 @@ macro_rules! dfs_tests {
#[test]
fn dfs_find_path_where_disconnected() {
let (graph, vertices) = make_test_graph_disconnected();
let (graph, vertices): ($T, _) = $crate::testing::fixtures::MakeTestGraph::disconnected();
assert_eq!(
$crate::algorithms::dfs_find_path_where(&graph, vertices[0], |v| v == vertices[1]),
None,
@@ -277,7 +259,7 @@ macro_rules! dfs_tests {
#[test]
fn dfs_find_path_where_no_match() {
let (graph, vertices, _, _) = make_test_graph();
let (graph, vertices, _, _): ($T, _, _, _) = $crate::testing::fixtures::MakeTestGraph::standard();
assert_eq!(
$crate::algorithms::dfs_find_path_where(&graph, vertices[0], |_| false),
None,
@@ -287,7 +269,7 @@ macro_rules! dfs_tests {
#[test]
fn dfs_find_path_where() {
let (graph, vertices, _, _) = make_test_graph();
let (graph, vertices, _, _): ($T, _, _, _) = $crate::testing::fixtures::MakeTestGraph::standard();
let path =
$crate::algorithms::dfs_find_path_where(&graph, vertices[0], |v| v == vertices[9])
.expect(&format!(
@@ -297,6 +279,7 @@ macro_rules! dfs_tests {
assert_valid_path(&graph, &path, vertices[0], vertices[9]);
}
// TODO: Move out of macro.
fn assert_valid_path(
graph: &$T,
path: &[<$T as $crate::traits::GraphTopology>::Edge],
+42 -27
View File
@@ -4,9 +4,7 @@ macro_rules! dijkstra_tests {
($T:ty) => {
#[test]
fn dijkstra_single_vertex() {
use $crate::traits::GraphTopologyAddition;
let mut graph = <$T>::new();
let v = graph.add_vertex();
let (graph, v): ($T, _) = $crate::testing::fixtures::MakeTestGraph::single_vertex();
let result = $crate::algorithms::dijkstra(&graph, v, |_| {
panic!("unexpected call of weight functor")
});
@@ -15,7 +13,8 @@ macro_rules! dijkstra_tests {
#[test]
fn dijkstra_disconnected() {
let (graph, vertices) = make_test_graph_disconnected();
let (graph, vertices): ($T, _) =
$crate::testing::fixtures::MakeTestGraph::disconnected();
let result = $crate::algorithms::dijkstra(&graph, vertices[0], |_| {
panic!("unexpected call of weight functor")
});
@@ -25,17 +24,7 @@ macro_rules! dijkstra_tests {
#[test]
fn dijkstra_zero_weight_loop() {
use $crate::traits::{GraphTopology, GraphTopologyAddition};
let mut graph = <$T>::new();
let vertices: [<$T as $crate::traits::GraphTopology>::Vertex; 3] =
core::array::from_fn(|_| graph.add_vertex());
let e1 = graph.add_edge(vertices[0], vertices[0]);
let e2 = graph.add_edge(vertices[1], vertices[1]);
graph.add_edge(vertices[0], vertices[1]);
graph.add_edge(vertices[1], vertices[2]);
let mut weights = graph.edge_map(1);
weights[e1] = 0;
weights[e2] = 0;
let (graph, vertices, _, weights) = make_two_edge_path_with_zero_weight_loops();
let result = $crate::algorithms::dijkstra(&graph, vertices[0], |e| weights[e]);
assert_single_vertex(&result, vertices[0]);
for i in 1..3 {
@@ -71,16 +60,15 @@ macro_rules! dijkstra_tests {
#[test]
fn dijkstra_unweighted_single_vertex() {
use $crate::traits::GraphTopologyAddition;
let mut graph = <$T>::new();
let v = graph.add_vertex();
let (graph, v): ($T, _) = $crate::testing::fixtures::MakeTestGraph::single_vertex();
let result = $crate::algorithms::dijkstra_unweighted(&graph, v);
assert_single_vertex(&result, v)
}
#[test]
fn dijkstra_unweighted_disconnected() {
let (graph, vertices) = make_test_graph_disconnected();
let (graph, vertices): ($T, _) =
$crate::testing::fixtures::MakeTestGraph::disconnected();
let result = $crate::algorithms::dijkstra_unweighted(&graph, vertices[0]);
assert_single_vertex(&result, vertices[0]);
assert_disconnected(&result, &vertices[1..3]);
@@ -88,23 +76,23 @@ macro_rules! dijkstra_tests {
#[test]
fn dijkstra_unweighted() {
let (graph, vertices, _, _) = make_test_graph();
let (graph, vertices, _, _): ($T, _, _, _) =
$crate::testing::fixtures::MakeTestGraph::standard();
let result = $crate::algorithms::dijkstra_unweighted(&graph, vertices[0]);
assert_unweighted_test_graph(&result, &vertices);
}
#[test]
fn dijkstra_distances_unweighted_single_vertex() {
use $crate::traits::GraphTopologyAddition;
let mut graph = <$T>::new();
let v = graph.add_vertex();
let (graph, v): ($T, _) = $crate::testing::fixtures::MakeTestGraph::single_vertex();
let distances = $crate::algorithms::dijkstra_distances_unweighted(&graph, v);
assert_distances_single_vertex(&distances, v);
}
#[test]
fn dijkstra_distances_unweighted_disconnected() {
let (graph, vertices) = make_test_graph_disconnected();
let (graph, vertices): ($T, _) =
$crate::testing::fixtures::MakeTestGraph::disconnected();
let distances = $crate::algorithms::dijkstra_distances_unweighted(&graph, vertices[0]);
assert_distances_single_vertex(&distances, vertices[0]);
assert_distances_disconnected(&distances, &vertices[1..3]);
@@ -112,11 +100,13 @@ macro_rules! dijkstra_tests {
#[test]
fn dijkstra_distances_unweighted() {
let (graph, vertices, _, _) = make_test_graph();
let (graph, vertices, _, _): ($T, _, _, _) =
$crate::testing::fixtures::MakeTestGraph::standard();
let distances = $crate::algorithms::dijkstra_distances_unweighted(&graph, vertices[0]);
assert_distances_unweighted_test_graph(&distances, &vertices);
}
// TODO: Move out of macro.
fn assert_single_vertex(
result: &$crate::algorithms::DijkstraResult<
<$T as $crate::traits::GraphTopology>::Vertex,
@@ -130,6 +120,7 @@ macro_rules! dijkstra_tests {
);
}
// TODO: Move out of macro.
fn assert_distances_single_vertex(
distances: &$crate::maps::ElementMap<
<$T as $crate::traits::GraphTopology>::Vertex,
@@ -144,6 +135,7 @@ macro_rules! dijkstra_tests {
);
}
// TODO: Move out of macro.
fn assert_disconnected(
result: &$crate::algorithms::DijkstraResult<
<$T as $crate::traits::GraphTopology>::Vertex,
@@ -159,6 +151,7 @@ macro_rules! dijkstra_tests {
}
}
// TODO: Move out of macro.
fn assert_distances_disconnected(
distances: &$crate::maps::ElementMap<
<$T as $crate::traits::GraphTopology>::Vertex,
@@ -174,6 +167,7 @@ macro_rules! dijkstra_tests {
}
}
// TODO: Move out of macro.
fn assert_test_graph(
result: &$crate::algorithms::DijkstraResult<
<$T as $crate::traits::GraphTopology>::Vertex,
@@ -203,6 +197,7 @@ macro_rules! dijkstra_tests {
}
}
// TODO: Move out of macro.
fn assert_distances_test_graph(
distances: &$crate::maps::ElementMap<
<$T as $crate::traits::GraphTopology>::Vertex,
@@ -231,6 +226,7 @@ macro_rules! dijkstra_tests {
}
}
// TODO: Move out of macro.
fn assert_unweighted_test_graph(
result: &$crate::algorithms::DijkstraResult<
<$T as $crate::traits::GraphTopology>::Vertex,
@@ -260,6 +256,7 @@ macro_rules! dijkstra_tests {
}
}
// TODO: Move out of macro.
fn assert_distances_unweighted_test_graph(
distances: &$crate::maps::ElementMap<
<$T as $crate::traits::GraphTopology>::Vertex,
@@ -288,6 +285,7 @@ macro_rules! dijkstra_tests {
}
}
// TODO: Move out of macro.
fn make_test_graph_weighted() -> (
$T,
[<$T as $crate::traits::GraphTopology>::Vertex; 10],
@@ -305,12 +303,29 @@ macro_rules! dijkstra_tests {
$crate::maps::ElementMap<<$T as $crate::traits::GraphTopology>::Edge, u32>,
) {
use $crate::traits::GraphTopology;
let (graph, vertices, edges, incidences) = make_test_graph();
let mut weights = graph.edge_map(99_u32);
let (graph, vertices, edges, incidences): ($T, _, _, _) =
$crate::testing::fixtures::MakeTestGraph::standard();
let mut weights = graph.edge_map(99);
for i in [1, 3, 7, 10, 12, 14, 15, 17] {
weights[edges[i].0] = i.try_into().unwrap();
}
(graph, vertices, edges, incidences, weights)
}
// TODO: Move out of macro.
fn make_two_edge_path_with_zero_weight_loops() -> (
$T,
[<$T as $crate::traits::GraphTopology>::Vertex; 3],
[<$T as $crate::traits::GraphTopology>::Edge; 4],
$crate::maps::ElementMap<<$T as $crate::traits::GraphTopology>::Edge, u32>,
) {
use $crate::traits::GraphTopology;
let (graph, vertices, edges): ($T, _, _) =
$crate::testing::fixtures::MakeTestGraph::two_edge_path_with_loops();
let mut weights = graph.edge_map(1);
weights[edges[2]] = 0;
weights[edges[3]] = 0;
(graph, vertices, edges, weights)
}
};
}
+164
View File
@@ -0,0 +1,164 @@
use crate::traits::{GraphTopology, GraphTopologyAddition, Incidence};
pub trait MakeTestGraph: GraphTopology + Sized {
fn standard() -> (
Self,
[Self::Vertex; 10],
[(Self::Edge, Self::Vertex, Self::Vertex); 18],
[Vec<Incidence<Self::Vertex, Self::Edge>>; 10],
);
fn empty() -> Self;
fn single_vertex() -> (Self, Self::Vertex);
fn single_edge() -> (Self, [Self::Vertex; 2], Self::Edge);
fn disconnected() -> (Self, [Self::Vertex; 3]);
fn loop_edge() -> (Self, Self::Vertex, Self::Edge);
fn multiple_edges<const K: usize>() -> (Self, [Self::Vertex; 2], [Self::Edge; K]);
fn two_edge_path() -> (Self, [Self::Vertex; 3], [Self::Edge; 2]);
fn two_edge_path_with_loops() -> (Self, [Self::Vertex; 3], [Self::Edge; 4]);
}
impl<G: GraphTopologyAddition> MakeTestGraph for G {
fn standard() -> (
Self,
[Self::Vertex; 10],
[(Self::Edge, Self::Vertex, Self::Vertex); 18],
[Vec<Incidence<Self::Vertex, Self::Edge>>; 10],
) {
let mut graph = Self::default();
let vertices = core::array::from_fn(|_| graph.add_vertex());
let edges = [
(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]),
]
.map(|(v1, v2)| (graph.add_edge(v1, v2), v1, v2));
let i = |vertex, edge| Incidence { vertex, edge };
let incidences = [
vec![i(vertices[1], edges[0].0), i(vertices[1], edges[1].0)],
vec![
i(vertices[0], edges[0].0),
i(vertices[0], edges[1].0),
i(vertices[2], edges[2].0),
i(vertices[3], edges[3].0),
i(vertices[4], edges[4].0),
],
vec![
i(vertices[2], edges[5].0),
i(vertices[2], edges[5].0),
i(vertices[1], edges[2].0),
i(vertices[4], edges[6].0),
i(vertices[4], edges[7].0),
i(vertices[5], edges[8].0),
i(vertices[6], edges[9].0),
],
vec![i(vertices[1], edges[3].0), i(vertices[6], edges[10].0)],
vec![
i(vertices[1], edges[4].0),
i(vertices[2], edges[6].0),
i(vertices[2], edges[7].0),
i(vertices[4], edges[11].0),
i(vertices[4], edges[11].0),
i(vertices[7], edges[12].0),
i(vertices[8], edges[13].0),
],
vec![i(vertices[2], edges[8].0), i(vertices[9], edges[14].0)],
vec![
i(vertices[2], edges[9].0),
i(vertices[3], edges[10].0),
i(vertices[9], edges[15].0),
],
vec![
i(vertices[4], edges[12].0),
i(vertices[8], edges[16].0),
i(vertices[9], edges[17].0),
],
vec![i(vertices[4], edges[13].0), i(vertices[7], edges[16].0)],
vec![
i(vertices[5], edges[14].0),
i(vertices[6], edges[15].0),
i(vertices[7], edges[17].0),
],
];
(graph, vertices, edges, incidences)
}
fn empty() -> Self {
Self::default()
}
fn single_vertex() -> (Self, Self::Vertex) {
let mut graph = Self::default();
let v = graph.add_vertex();
(graph, v)
}
fn single_edge() -> (Self, [Self::Vertex; 2], Self::Edge) {
let mut graph = Self::default();
let vertices = core::array::from_fn(|_| graph.add_vertex());
let e = graph.add_edge(vertices[0], vertices[1]);
(graph, vertices, e)
}
fn disconnected() -> (Self, [Self::Vertex; 3]) {
let mut graph = Self::default();
let vertices = core::array::from_fn(|_| graph.add_vertex());
graph.add_edge(vertices[1], vertices[2]);
(graph, vertices)
}
fn loop_edge() -> (Self, Self::Vertex, Self::Edge) {
let mut graph = Self::default();
let v = graph.add_vertex();
let e = graph.add_edge(v, v);
(graph, v, e)
}
fn multiple_edges<const K: usize>() -> (Self, [Self::Vertex; 2], [Self::Edge; K]) {
let mut graph = Self::default();
let vertices = core::array::from_fn(|_| graph.add_vertex());
let edges = core::array::from_fn(|_| graph.add_edge(vertices[0], vertices[1]));
(graph, vertices, edges)
}
fn two_edge_path() -> (Self, [Self::Vertex; 3], [Self::Edge; 2]) {
let mut graph = Self::default();
let vertices = core::array::from_fn(|_| graph.add_vertex());
let edges = core::array::from_fn(|i| graph.add_edge(vertices[i], vertices[i + 1]));
(graph, vertices, edges)
}
fn two_edge_path_with_loops() -> (Self, [Self::Vertex; 3], [Self::Edge; 4]) {
let mut graph = Self::default();
let vertices = core::array::from_fn(|_| graph.add_vertex());
// Path edges.
let e0 = graph.add_edge(vertices[0], vertices[1]);
let e1 = graph.add_edge(vertices[1], vertices[2]);
// Loops.
let e2 = graph.add_edge(vertices[0], vertices[0]);
let e3 = graph.add_edge(vertices[1], vertices[1]);
(graph, vertices, [e0, e1, e2, e3])
}
}
File diff suppressed because it is too large Load Diff
-2
View File
@@ -1,13 +1,11 @@
mod append_graph_tests {
use grapherity::models::AppendGraph;
grapherity::graph_topology_test_fixtures!(AppendGraph);
grapherity::bfs_tests!(AppendGraph);
}
mod graph_tests {
use grapherity::models::Graph;
grapherity::graph_topology_test_fixtures!(Graph);
grapherity::bfs_tests!(Graph);
}
-2
View File
@@ -1,13 +1,11 @@
mod append_graph_tests {
use grapherity::models::AppendGraph;
grapherity::graph_topology_test_fixtures!(AppendGraph);
grapherity::dfs_tests!(AppendGraph);
}
mod graph_tests {
use grapherity::models::Graph;
grapherity::graph_topology_test_fixtures!(Graph);
grapherity::dfs_tests!(Graph);
}
-2
View File
@@ -1,13 +1,11 @@
mod append_graph_tests {
use grapherity::models::AppendGraph;
grapherity::graph_topology_test_fixtures!(AppendGraph);
grapherity::dijkstra_tests!(AppendGraph);
}
mod graph_tests {
use grapherity::models::Graph;
grapherity::graph_topology_test_fixtures!(Graph);
grapherity::dijkstra_tests!(Graph);
}