From cadd869155a3b6b6b32dccce02990bde275006dc Mon Sep 17 00:00:00 2001 From: raj_mathe Date: Fri, 8 Apr 2022 23:36:29 +0200 Subject: [PATCH] =?UTF-8?q?master=20>=20master:=20code-rust=20-=20unit=20t?= =?UTF-8?q?ests=20f=C3=BCr=20gph=20+=20tarjan?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/rust/tests/mod.rs | 1 + code/rust/tests/test_core/test_utils.rs | 27 ++++++++ code/rust/tests/test_graphs/test_graph.rs | 73 ++++++++++++++++++++ code/rust/tests/test_graphs/test_tarjan.rs | 80 ++++++++++++++++++++++ 4 files changed, 181 insertions(+) create mode 100644 code/rust/tests/test_graphs/test_graph.rs create mode 100644 code/rust/tests/test_graphs/test_tarjan.rs diff --git a/code/rust/tests/mod.rs b/code/rust/tests/mod.rs index feb8881..9e6933e 100644 --- a/code/rust/tests/mod.rs +++ b/code/rust/tests/mod.rs @@ -1,4 +1,5 @@ extern crate ads2; +extern crate rstest; pub mod test_core; pub mod test_stacks; diff --git a/code/rust/tests/test_core/test_utils.rs b/code/rust/tests/test_core/test_utils.rs index 96bc59a..97c089b 100644 --- a/code/rust/tests/test_core/test_utils.rs +++ b/code/rust/tests/test_core/test_utils.rs @@ -49,6 +49,7 @@ pub fn test_restrict() { assert_eq!(x[1], 100, "Result should be a copy."); } +#[test] pub fn test_remove_first_last() { let x: Vec = vec!["merkur", "venus", "mars", "terra", "jupiter", "saturn", "uranus", "neptun"] .iter() @@ -60,3 +61,29 @@ pub fn test_remove_first_last() { assert_eq!(utils::remove_first(&x), Vec::::new()); assert_eq!(utils::remove_last(&x), Vec::::new()); } + +// ---------------------------------------------------------------- +// Test vector-to-set-conversions +// ---------------------------------------------------------------- + +#[test] +pub fn test_vec_to_set() { + let x = vec!["b", "a", "a", "d", "d", "c", "b", "a"]; + let y1 = vec!["a", "a", "a", "b", "b", "c", "d", "d"]; + let y2 = vec!["d", "c", "b", "a", "d"]; + let z = vec!["b", "e", "f"]; + assert_eq!(utils::vec_to_set(&x), utils::vec_to_set(&y1), "Should match when both lists have similar elements"); + assert_eq!(utils::vec_to_set(&x), utils::vec_to_set(&y2), "Should match when both lists have similar elements, regardless of counts"); + assert_ne!(utils::vec_to_set(&x), utils::vec_to_set(&z), "Should not match when lists different elements"); +} + +#[test] +pub fn test_vec_to_multiset() { + let x = vec!["b", "a", "a", "d", "d", "c", "b", "a"]; + let y1 = vec!["a", "a", "a", "b", "b", "c", "d", "d"]; + let y2 = vec!["d", "c", "b", "a", "d"]; + let z = vec!["b", "e", "f"]; + assert_eq!(utils::vec_to_multiset(&x), utils::vec_to_multiset(&y1), "Should match when both lists have similar elements with the same element counts"); + assert_ne!(utils::vec_to_multiset(&x), utils::vec_to_multiset(&y2), "Should not match when both lists have similar elements but different counts"); + assert_ne!(utils::vec_to_multiset(&x), utils::vec_to_multiset(&z), "Should not match when lists different elements"); +} diff --git a/code/rust/tests/test_graphs/test_graph.rs b/code/rust/tests/test_graphs/test_graph.rs new file mode 100644 index 0000000..46ff7e1 --- /dev/null +++ b/code/rust/tests/test_graphs/test_graph.rs @@ -0,0 +1,73 @@ +// ---------------------------------------------------------------- +// IMPORTS +// ---------------------------------------------------------------- + +use rstest::fixture; +use rstest::rstest; + +use ads2::core::utils; +use ads2::graphs::graph; + +// ---------------------------------------------------------------- +// Fixtures +// ---------------------------------------------------------------- + +#[fixture] +fn fixture_graph() -> graph::Graph { + return graph::Graph::new( + vec![1,2,3,4,5,6,7,8], + vec![(1,2), (1, 3), (2,3), (3,4), (4, 5), (5, 6), (6, 2), (6, 7), (6, 8)] + ); +} + +// ---------------------------------------------------------------- +// Test Graph +// ---------------------------------------------------------------- + +#[test] +fn test_graph_create_noerror() { + let result = std::panic::catch_unwind(|| { + let gph = graph::Graph::new( + vec![5, 7, 8], + vec![(5,7), (7, 8)] + ); + assert_eq!(gph.len(), 3); + }); + assert!(result.is_ok()); + let result = std::panic::catch_unwind(|| { + let gph = graph::Graph::new( + vec!["5", "7", "8", "10"], + vec![("5", "7"), ("7", "8")] + ); + assert_eq!(gph.len(), 4); + }); + assert!(result.is_ok()); + let result = std::panic::catch_unwind(|| { + let gph = graph::Graph::::new(Vec::new(), Vec::new()); + assert_eq!(gph.len(), 0); + }); + assert!(result.is_ok()); +} + +#[rstest] +fn test_graph_subgraph(fixture_graph: graph::Graph) { + let sub_gph = fixture_graph.subgraph(vec![2,4,5,6,8]); + assert_eq!(utils::vec_to_set(&sub_gph.edges), utils::vec_to_set(&vec![(6,2), (4,5), (5,6), (6,8)])); +} + +#[rstest] +fn test_graph_successors_and_predecessors(fixture_graph: graph::Graph) { + let u = 1; + assert_eq!(utils::vec_to_set(&fixture_graph.successors(&u)), utils::vec_to_set(&vec![2, 3])); + let u = 8; + assert_eq!(utils::vec_to_set(&fixture_graph.successors(&u)).len(), 0); + let u = 6; + assert_eq!(utils::vec_to_set(&fixture_graph.successors(&u)), utils::vec_to_set(&vec![2, 7, 8])); + + let u = 1; + assert_eq!(utils::vec_to_set(&fixture_graph.predecessors(&u)).len(), 0); + let u = 8; + assert_eq!(utils::vec_to_set(&fixture_graph.predecessors(&u)), utils::vec_to_set(&vec![6])); + let u = 6; + assert_eq!(utils::vec_to_set(&fixture_graph.predecessors(&u)), utils::vec_to_set(&vec![5])); +} diff --git a/code/rust/tests/test_graphs/test_tarjan.rs b/code/rust/tests/test_graphs/test_tarjan.rs new file mode 100644 index 0000000..f6ecb14 --- /dev/null +++ b/code/rust/tests/test_graphs/test_tarjan.rs @@ -0,0 +1,80 @@ +// ---------------------------------------------------------------- +// IMPORTS +// ---------------------------------------------------------------- + +use rstest::fixture; +use rstest::rstest; +use std::fmt::Display; +use std::hash::Hash; + +use ads2::core::utils; +use ads2::graphs::graph; +use ads2::graphs::tarjan; + +// ---------------------------------------------------------------- +// Fixtures +// ---------------------------------------------------------------- + +#[fixture] +fn fixture_graph1() -> graph::Graph { + return graph::Graph::::new( + vec![1,2,3,4], + vec![(1,2), (2,4), (4,2)] + ); +} + +#[fixture] +fn fixture_graph2() -> graph::Graph { + return graph::Graph::::new( + vec![1,2,3,4,5,6,7], + vec![(1,2), (1,3), (2,3), (3,4), (4,5), (5,2), (5,6), (5,7), (6,7)] + ); +} + +// ---------------------------------------------------------------- +// Test Graph +// ---------------------------------------------------------------- + +#[rstest] +#[case(fixture_graph1(), vec![vec![1], vec![3], vec![2,4]])] +#[case(fixture_graph2(), vec![vec![1], vec![6], vec![7], vec![2,3,4,5]])] +fn test_tarjan(#[case] gph: graph::Graph, #[case] expected: Vec>) + where T: Eq + Hash + Clone + Display +{ + assert_components_eq( + &tarjan::tarjan_algorithm(&gph), + &expected + ) +} + +// ---------------------------------------------------------------- +// AUXILIARY METHODS +// ---------------------------------------------------------------- + +fn check_components_eq(components1: &Vec>, components2: &Vec>) -> bool + where T: Eq + Hash + Clone +{ + if components1.len() != components2.len() { + return false + } + + for component1 in components1 { + let mut found = false; + for component2 in components2 { + if utils::vec_to_set(component1) == utils::vec_to_set(component2) { + found = true; + break; + } + } + if !found { + return false; + } + } + return true; +} + +fn assert_components_eq(components1: &Vec>, components2: &Vec>) + where T: Eq + Hash + Clone +{ + assert!(check_components_eq(components1, components2)); +}