From f20e764edc84eca9a97a3118f209c6a7b36192b9 Mon Sep 17 00:00:00 2001 From: Andreas Longva Date: Mon, 23 Nov 2020 10:16:18 +0100 Subject: [PATCH] nalgebra-sparse: Move slow tests and imports into 'slow' child module This way it's easier to prevent accidental unused imports when running tests without the slow-tests feature. --- nalgebra-sparse/tests/unit_tests/proptest.rs | 228 +++++++++---------- 1 file changed, 114 insertions(+), 114 deletions(-) diff --git a/nalgebra-sparse/tests/unit_tests/proptest.rs b/nalgebra-sparse/tests/unit_tests/proptest.rs index 23afa741..72a3d40c 100644 --- a/nalgebra-sparse/tests/unit_tests/proptest.rs +++ b/nalgebra-sparse/tests/unit_tests/proptest.rs @@ -1,134 +1,134 @@ -use nalgebra_sparse::proptest::{coo_with_duplicates, coo_no_duplicates}; -use nalgebra::DMatrix; - -use proptest::prelude::*; -use itertools::Itertools; - -use std::collections::HashSet; -use std::iter::repeat; +#[test] +#[ignore] +fn coo_no_duplicates_generates_admissible_matrices() { + //TODO +} #[cfg(feature = "slow-tests")] -use { - proptest::test_runner::TestRunner, - proptest::strategy::ValueTree -}; -use std::ops::RangeInclusive; +mod slow { + use nalgebra_sparse::proptest::{coo_with_duplicates, coo_no_duplicates}; + use nalgebra::DMatrix; -#[cfg(feature = "slow-tests")] -fn generate_all_possible_matrices(value_range: RangeInclusive, - rows_range: RangeInclusive, - cols_range: RangeInclusive) - -> HashSet> -{ - // Enumerate all possible combinations - let mut all_combinations = HashSet::new(); - for nrows in rows_range { - for ncols in cols_range.clone() { - // For the given number of rows and columns - let n_values = nrows * ncols; + use proptest::test_runner::TestRunner; + use proptest::strategy::ValueTree; + use itertools::Itertools; - if n_values == 0 { - // If we have zero rows or columns, the set of matrices with the given - // rows and columns is a single element: an empty matrix - all_combinations.insert(DMatrix::from_row_slice(nrows, ncols, &[])); - } else { - // Otherwise, we need to sample all possible matrices. - // To do this, we generate the values as the (multi) Cartesian product - // of the value sets. For example, for a 2x2 matrices, we consider - // all possible 4-element arrays that the matrices can take by - // considering all elements in the cartesian product - // V x V x V x V - // where V is the set of eligible values, e.g. V := -1 ..= 1 - let values_iter = repeat(value_range.clone()) - .take(n_values) - .multi_cartesian_product(); - for matrix_values in values_iter { - all_combinations.insert(DMatrix::from_row_slice(nrows, ncols, &matrix_values)); + use proptest::prelude::*; + + use std::collections::HashSet; + use std::iter::repeat; + use std::ops::RangeInclusive; + + fn generate_all_possible_matrices(value_range: RangeInclusive, + rows_range: RangeInclusive, + cols_range: RangeInclusive) + -> HashSet> + { + // Enumerate all possible combinations + let mut all_combinations = HashSet::new(); + for nrows in rows_range { + for ncols in cols_range.clone() { + // For the given number of rows and columns + let n_values = nrows * ncols; + + if n_values == 0 { + // If we have zero rows or columns, the set of matrices with the given + // rows and columns is a single element: an empty matrix + all_combinations.insert(DMatrix::from_row_slice(nrows, ncols, &[])); + } else { + // Otherwise, we need to sample all possible matrices. + // To do this, we generate the values as the (multi) Cartesian product + // of the value sets. For example, for a 2x2 matrices, we consider + // all possible 4-element arrays that the matrices can take by + // considering all elements in the cartesian product + // V x V x V x V + // where V is the set of eligible values, e.g. V := -1 ..= 1 + let values_iter = repeat(value_range.clone()) + .take(n_values) + .multi_cartesian_product(); + for matrix_values in values_iter { + all_combinations.insert(DMatrix::from_row_slice(nrows, ncols, &matrix_values)); + } } } } - } - all_combinations -} - -#[cfg(feature = "slow-tests")] -#[test] -fn coo_no_duplicates_samples_all_admissible_outputs() { - // Note: This test basically mirrors a similar test for `matrix` in the `nalgebra` repo. - - // Test that the proptest generation covers all possible outputs for a small space of inputs - // given enough samples. - - // We use a deterministic test runner to make the test "stable". - let mut runner = TestRunner::deterministic(); - - // This number needs to be high enough so that we with high probability sample - // all possible cases - let num_generated_matrices = 500000; - - let values = -1..=1; - let rows = 0..=2; - let cols = 0..=3; - let strategy = coo_no_duplicates(values.clone(), rows.clone(), cols.clone(), 2 * 3); - - // Enumerate all possible combinations - let all_combinations = generate_all_possible_matrices(values, rows, cols); - - let mut visited_combinations = HashSet::new(); - for _ in 0..num_generated_matrices { - let tree = strategy - .new_tree(&mut runner) - .expect("Tree generation should not fail"); - let matrix = tree.current(); - visited_combinations.insert(DMatrix::from(&matrix)); + all_combinations } - assert_eq!(visited_combinations.len(), all_combinations.len()); - assert_eq!(visited_combinations, all_combinations, "Did not sample all possible values."); -} + #[cfg(feature = "slow-tests")] + #[test] + fn coo_no_duplicates_samples_all_admissible_outputs() { + // Note: This test basically mirrors a similar test for `matrix` in the `nalgebra` repo. -#[cfg(feature = "slow-tests")] -#[test] -fn coo_with_duplicates_samples_all_admissible_outputs() { - // This is almost the same as the test for coo_no_duplicates, except that we need - // a different "success" criterion, since coo_with_duplicates is able to generate - // matrices with values outside of the value constraints. See below for details. + // Test that the proptest generation covers all possible outputs for a small space of inputs + // given enough samples. - // We use a deterministic test runner to make the test "stable". - let mut runner = TestRunner::deterministic(); + // We use a deterministic test runner to make the test "stable". + let mut runner = TestRunner::deterministic(); - // This number needs to be high enough so that we with high probability sample - // all possible cases - let num_generated_matrices = 500000; + // This number needs to be high enough so that we with high probability sample + // all possible cases + let num_generated_matrices = 500000; - let values = -1..=1; - let rows = 0..=2; - let cols = 0..=3; - let strategy = coo_with_duplicates(values.clone(), rows.clone(), cols.clone(), 2 * 3, 2); + let values = -1..=1; + let rows = 0..=2; + let cols = 0..=3; + let strategy = coo_no_duplicates(values.clone(), rows.clone(), cols.clone(), 2 * 3); - // Enumerate all possible combinations that fit the constraints - // (note: this is only a subset of the matrices that can be generated by - // `coo_with_duplicates`) - let all_combinations = generate_all_possible_matrices(values, rows, cols); + // Enumerate all possible combinations + let all_combinations = generate_all_possible_matrices(values, rows, cols); - let mut visited_combinations = HashSet::new(); - for _ in 0..num_generated_matrices { - let tree = strategy - .new_tree(&mut runner) - .expect("Tree generation should not fail"); - let matrix = tree.current(); - visited_combinations.insert(DMatrix::from(&matrix)); + let mut visited_combinations = HashSet::new(); + for _ in 0..num_generated_matrices { + let tree = strategy + .new_tree(&mut runner) + .expect("Tree generation should not fail"); + let matrix = tree.current(); + visited_combinations.insert(DMatrix::from(&matrix)); + } + + assert_eq!(visited_combinations.len(), all_combinations.len()); + assert_eq!(visited_combinations, all_combinations, "Did not sample all possible values."); } - // Here we cannot verify that the set of visited combinations is *equal* to - // all possible outcomes with the given constraints, however the - // strategy should be able to generate all matrices that fit the constraints. - // In other words, we need to determine that set of all admissible matrices - // is contained in the set of visited matrices - assert!(all_combinations.is_subset(&visited_combinations)); -} + #[cfg(feature = "slow-tests")] + #[test] + fn coo_with_duplicates_samples_all_admissible_outputs() { + // This is almost the same as the test for coo_no_duplicates, except that we need + // a different "success" criterion, since coo_with_duplicates is able to generate + // matrices with values outside of the value constraints. See below for details. -#[test] -fn coo_no_duplicates_generates_admissible_matrices() { + // We use a deterministic test runner to make the test "stable". + let mut runner = TestRunner::deterministic(); + // This number needs to be high enough so that we with high probability sample + // all possible cases + let num_generated_matrices = 500000; + + let values = -1..=1; + let rows = 0..=2; + let cols = 0..=3; + let strategy = coo_with_duplicates(values.clone(), rows.clone(), cols.clone(), 2 * 3, 2); + + // Enumerate all possible combinations that fit the constraints + // (note: this is only a subset of the matrices that can be generated by + // `coo_with_duplicates`) + let all_combinations = generate_all_possible_matrices(values, rows, cols); + + let mut visited_combinations = HashSet::new(); + for _ in 0..num_generated_matrices { + let tree = strategy + .new_tree(&mut runner) + .expect("Tree generation should not fail"); + let matrix = tree.current(); + visited_combinations.insert(DMatrix::from(&matrix)); + } + + // Here we cannot verify that the set of visited combinations is *equal* to + // all possible outcomes with the given constraints, however the + // strategy should be able to generate all matrices that fit the constraints. + // In other words, we need to determine that set of all admissible matrices + // is contained in the set of visited matrices + assert!(all_combinations.is_subset(&visited_combinations)); + } } \ No newline at end of file