diff --git a/src/testing.rs b/src/testing.rs index a345512..c8ded87 100644 --- a/src/testing.rs +++ b/src/testing.rs @@ -1,6 +1,5 @@ pub(crate) mod bfs_testing; pub(crate) mod dfs_testing; pub(crate) mod dijkstra_testing; -pub(crate) mod find_path_testing; pub(crate) mod graph_topology_testing; pub(crate) mod maps_testing; diff --git a/src/testing/dfs_testing.rs b/src/testing/dfs_testing.rs index eb59676..d302773 100644 --- a/src/testing/dfs_testing.rs +++ b/src/testing/dfs_testing.rs @@ -202,5 +202,124 @@ macro_rules! dfs_tests { ); } } + + #[test] + fn dfs_find_path_source_equals_target() { + use $crate::traits::GraphTopology; + let mut graph = <$T>::new(); + let v = graph.add_vertex(); + assert_eq!( + $crate::algorithms::dfs_find_path(&graph, v, v), + Some(vec![]), + "path from source to itself should be empty" + ); + } + + #[test] + fn dfs_find_path_disconnected() { + let (graph, vertices) = make_test_graph_disconnected(); + assert_eq!( + $crate::algorithms::dfs_find_path(&graph, vertices[0], vertices[1]), + None, + "no path should exist to disconnected vertex" + ); + } + + #[test] + fn dfs_find_path_adjacent() { + use $crate::traits::GraphTopology; + 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) + .expect("path should exist 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 path = $crate::algorithms::dfs_find_path(&graph, vertices[0], vertices[9]) + .expect(&format!( + "path should exist between connected vertices {:?} and {:?}", + vertices[0], vertices[9] + )); + assert_valid_path(&graph, &path, vertices[0], vertices[9]); + } + + #[test] + fn dfs_find_path_where_source_matches() { + use $crate::traits::GraphTopology; + let mut graph = <$T>::new(); + let v = graph.add_vertex(); + assert_eq!( + $crate::algorithms::dfs_find_path_where(&graph, v, |u| u == v), + Some(vec![]), + "path from source to itself should be empty" + ); + } + + #[test] + fn dfs_find_path_where_disconnected() { + let (graph, vertices) = make_test_graph_disconnected(); + assert_eq!( + $crate::algorithms::dfs_find_path_where(&graph, vertices[0], |v| v == vertices[1]), + None, + "no path should exist to disconnected vertex" + ); + } + + #[test] + fn dfs_find_path_where_no_match() { + let (graph, vertices, _, _) = make_test_graph(); + assert_eq!( + $crate::algorithms::dfs_find_path_where(&graph, vertices[0], |_| false), + None, + "no path should exist when predicate never matches" + ); + } + + #[test] + fn dfs_find_path_where() { + let (graph, vertices, _, _) = make_test_graph(); + let path = + $crate::algorithms::dfs_find_path_where(&graph, vertices[0], |v| v == vertices[9]) + .expect(&format!( + "path should exist between connected vertices {:?} and {:?}", + vertices[0], vertices[9] + )); + assert_valid_path(&graph, &path, vertices[0], vertices[9]); + } + + fn assert_valid_path( + graph: &$T, + path: &[<$T as $crate::traits::GraphTopology>::Edge], + source: <$T as $crate::traits::GraphTopology>::Vertex, + target: <$T as $crate::traits::GraphTopology>::Vertex, + ) { + use $crate::traits::GraphTopology; + assert!(!path.is_empty(), "path should be non-empty"); + // Walks the path: tracks current vertex, confirm each edge is incident to it. + let mut current = source; + for (i, &e) in path.iter().enumerate() { + let (v1, v2) = graph.incident_vertices(e); + assert_ne!(v1, v2, "path should not contain loop edge {e:?}"); + assert!( + v1 == current || v2 == current, + "path edge {e:?} (index {i}, from {v1:?} to {v2:?}) is not incident to current path vertex {current:?}" + ); + current = if v1 == current { v2 } else { v1 }; + } + assert_eq!( + current, target, + "path should end at target {target:?}, but ended at {current:?}" + ); + } }; } diff --git a/src/testing/find_path_testing.rs b/src/testing/find_path_testing.rs deleted file mode 100644 index c9c4e42..0000000 --- a/src/testing/find_path_testing.rs +++ /dev/null @@ -1,124 +0,0 @@ -#[doc(hidden)] -#[macro_export] -macro_rules! find_path_tests { - ($T:ty) => { - #[test] - fn find_path_source_equals_target() { - use $crate::traits::GraphTopology; - let mut graph = <$T>::new(); - let v = graph.add_vertex(); - assert_eq!( - $crate::algorithms::dfs_find_path(&graph, v, v), - Some(vec![]), - "path from source to itself should be empty" - ); - } - - #[test] - fn find_path_disconnected() { - let (graph, vertices) = make_test_graph_disconnected(); - assert_eq!( - $crate::algorithms::dfs_find_path(&graph, vertices[0], vertices[1]), - None, - "no path should exist to disconnected vertex" - ); - } - - #[test] - fn find_path_adjacent() { - use $crate::traits::GraphTopology; - 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) - .expect("path should exist 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 find_path() { - let (graph, vertices, _, _) = make_test_graph(); - let path = $crate::algorithms::dfs_find_path(&graph, vertices[0], vertices[9]) - .expect(&format!( - "path should exist between connected vertices {:?} and {:?}", - vertices[0], vertices[9] - )); - assert_valid_path(&graph, &path, vertices[0], vertices[9]); - } - - #[test] - fn find_path_where_source_matches() { - use $crate::traits::GraphTopology; - let mut graph = <$T>::new(); - let v = graph.add_vertex(); - assert_eq!( - $crate::algorithms::dfs_find_path_where(&graph, v, |u| u == v), - Some(vec![]), - "path from source to itself should be empty" - ); - } - - #[test] - fn find_path_where_disconnected() { - let (graph, vertices) = make_test_graph_disconnected(); - assert_eq!( - $crate::algorithms::dfs_find_path_where(&graph, vertices[0], |v| v == vertices[1]), - None, - "no path should exist to disconnected vertex" - ); - } - - #[test] - fn find_path_where_no_match() { - let (graph, vertices, _, _) = make_test_graph(); - assert_eq!( - $crate::algorithms::dfs_find_path_where(&graph, vertices[0], |_| false), - None, - "no path should exist when predicate never matches" - ); - } - - #[test] - fn find_path_where() { - let (graph, vertices, _, _) = make_test_graph(); - let path = - $crate::algorithms::dfs_find_path_where(&graph, vertices[0], |v| v == vertices[9]) - .expect(&format!( - "path should exist between connected vertices {:?} and {:?}", - vertices[0], vertices[9] - )); - assert_valid_path(&graph, &path, vertices[0], vertices[9]); - } - - fn assert_valid_path( - graph: &$T, - path: &[<$T as $crate::traits::GraphTopology>::Edge], - source: <$T as $crate::traits::GraphTopology>::Vertex, - target: <$T as $crate::traits::GraphTopology>::Vertex, - ) { - use $crate::traits::GraphTopology; - assert!(!path.is_empty(), "path should be non-empty"); - // Walks the path: tracks current vertex, confirm each edge is incident to it. - let mut current = source; - for (i, &e) in path.iter().enumerate() { - let (v1, v2) = graph.incident_vertices(e); - assert_ne!(v1, v2, "path should not contain loop edge {e:?}"); - assert!( - v1 == current || v2 == current, - "path edge {e:?} (index {i}, from {v1:?} to {v2:?}) is not incident to current path vertex {current:?}" - ); - current = if v1 == current { v2 } else { v1 }; - } - assert_eq!( - current, target, - "path should end at target {target:?}, but ended at {current:?}" - ); - } - }; -} diff --git a/tests/find_path.rs b/tests/find_path.rs deleted file mode 100644 index 7f296c8..0000000 --- a/tests/find_path.rs +++ /dev/null @@ -1,13 +0,0 @@ -mod append_graph_tests { - use grapherity::models::AppendGraph; - - grapherity::graph_topology_test_fixtures!(AppendGraph); - grapherity::find_path_tests!(AppendGraph); -} - -mod graph_tests { - use grapherity::models::Graph; - - grapherity::graph_topology_test_fixtures!(Graph); - grapherity::find_path_tests!(Graph); -}