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:
+1
-1
@@ -149,4 +149,4 @@ pub mod prelude {
|
||||
};
|
||||
}
|
||||
|
||||
mod testing;
|
||||
pub mod testing;
|
||||
|
||||
@@ -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
@@ -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() {
|
||||
|
||||
@@ -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
@@ -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
@@ -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],
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user