From f092dacf17ba66ce6d87d0d94daeb4ff06bd6084 Mon Sep 17 00:00:00 2001 From: Peter Goodspeed-Niklaus Date: Mon, 13 Nov 2017 21:39:33 +0100 Subject: [PATCH 1/4] perfect-numbers: Update tests from table-based to macro-based This PR is in response to #392. Perfect-numbers currently uses table-based testing. For reasons outlined in https://github.com/exercism/rust/issues/392#issuecomment-343865993 I believe that table-based testing is not the appropriate way to do things. This is what macro-based tests might look like. Are they abstruse and opaque? Yes. However, they at least become individual tests, and I believe that this is _better than the status quo_. --- .../perfect-numbers/tests/perfect-numbers.rs | 65 ++++++++++++------- 1 file changed, 43 insertions(+), 22 deletions(-) diff --git a/exercises/perfect-numbers/tests/perfect-numbers.rs b/exercises/perfect-numbers/tests/perfect-numbers.rs index 24b276d1c..a1cc48354 100644 --- a/exercises/perfect-numbers/tests/perfect-numbers.rs +++ b/exercises/perfect-numbers/tests/perfect-numbers.rs @@ -2,32 +2,53 @@ extern crate perfect_numbers; use perfect_numbers::{Classification, classify}; +macro_rules! tests { + ($property_test_func:ident { + $( $(#[$attr:meta])* $test_name:ident( $( $param:expr ),* ); )+ + }) => { + $( + $(#[$attr])* + #[test] + fn $test_name() { + $property_test_func($( $param ),* ) + } + )+ + } +} + +fn test_classification(num: u64, result: Classification) { + assert_eq!(classify(num), Ok(result)); +} + #[test] fn basic() { assert_eq!(classify(0), Err("Number must be positive")); } -#[test] -#[ignore] -fn test_all() { - struct TestClassification { - num: u64, - result: perfect_numbers::Classification - } - let test_table: Vec = vec![ - TestClassification { num: 6, result: Classification::Perfect }, - TestClassification { num: 28, result: Classification::Perfect }, - TestClassification { num: 33550336, result: Classification::Perfect }, - TestClassification { num: 12, result: Classification::Abundant }, - TestClassification { num: 30, result: Classification::Abundant }, - TestClassification { num: 33550335, result: Classification::Abundant }, - TestClassification { num: 2, result: Classification::Deficient }, - TestClassification { num: 4, result: Classification::Deficient }, - TestClassification { num: 32, result: Classification::Deficient }, - TestClassification { num: 33550337, result: Classification::Deficient }, - TestClassification { num: 1, result: Classification::Deficient }, - ]; - for t in test_table { - assert_eq!(classify(t.num), Ok(t.result)); + +tests! { + test_classification { + #[ignore] + test_1(1, Classification::Deficient); + #[ignore] + test_2(2, Classification::Deficient); + #[ignore] + test_4(4, Classification::Deficient); + #[ignore] + test_6(6, Classification::Perfect); + #[ignore] + test_12(12, Classification::Abundant); + #[ignore] + test_28(28, Classification::Perfect); + #[ignore] + test_30(30, Classification::Abundant); + #[ignore] + test_32(32, Classification::Deficient); + #[ignore] + test_33550335(33550335, Classification::Abundant); + #[ignore] + test_33550336(33550336, Classification::Perfect); + #[ignore] + test_33550337(33550337, Classification::Deficient); } } From a4c02a0d60418a3722849d587dd24091d8e1bd7d Mon Sep 17 00:00:00 2001 From: Peter Goodspeed-Niklaus Date: Tue, 14 Nov 2017 12:29:42 +0100 Subject: [PATCH 2/4] Conditionally disable count-ignores.sh; disable for perfect-numbers --- _test/count-ignores.sh | 23 ++++++++++++------- .../.meta/ignore-count-ignores | 6 +++++ 2 files changed, 21 insertions(+), 8 deletions(-) create mode 100644 exercises/perfect-numbers/.meta/ignore-count-ignores diff --git a/_test/count-ignores.sh b/_test/count-ignores.sh index 41c274e36..96f30b083 100644 --- a/_test/count-ignores.sh +++ b/_test/count-ignores.sh @@ -3,14 +3,21 @@ repo=$(cd "$(dirname "$0")/.." && pwd) exitcode=0 -for t in $repo/exercises/*/tests/*.rs; do - tests=$(grep "^\s*\#\[test\]" $t | wc -l | tr -d '[:space:]') - ignores=$(grep "^\s*\#\[ignore\]" $t | wc -l | tr -d '[:space:]') - want_ignores=$(expr $tests - 1) - if [ "$ignores" != "$want_ignores" ]; then - echo "\033[1;31m$t: Has $tests tests and $ignores ignores (should be $want_ignores)\033[0m" - exitcode=1 - fi +for e in $repo/exercises/*; do + if [ -f "$e/.meta/ignore-count-ignores" ]; then + continue + fi + if [ -d "$e/tests" ]; then + for t in $e/tests/*.rs; do + tests=$(grep "^\s*\#\[test\]" $t | wc -l | tr -d '[:space:]') + ignores=$(grep "^\s*\#\[ignore\]" $t | wc -l | tr -d '[:space:]') + want_ignores=$(expr $tests - 1) + if [ "$ignores" != "$want_ignores" ]; then + echo "\033[1;31m$t: Has $tests tests and $ignores ignores (should be $want_ignores)\033[0m" + exitcode=1 + fi + done + fi done exit $exitcode diff --git a/exercises/perfect-numbers/.meta/ignore-count-ignores b/exercises/perfect-numbers/.meta/ignore-count-ignores new file mode 100644 index 000000000..368bdedca --- /dev/null +++ b/exercises/perfect-numbers/.meta/ignore-count-ignores @@ -0,0 +1,6 @@ +Perfect numbers has tests generated by macro. +This breaks the count-ignores.sh script: + +```text +exercises/perfect-numbers/tests/perfect-numbers.rs: Has 2 tests and 11 ignores (should be 1) +``` From 92e54da5f60b7b4e9b889ef7361ba9971d850360 Mon Sep 17 00:00:00 2001 From: coriolinus Date: Tue, 14 Nov 2017 12:52:34 +0100 Subject: [PATCH 3/4] Document .meta/ignore-count-ignores --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 7a40bb094..62ecde47d 100644 --- a/README.md +++ b/README.md @@ -96,6 +96,8 @@ Note that: - If the test suite is appreciably sped up by running in release mode, and there is reason to be confident that the example implementation does not contain any overflow errors, consider adding a file `.meta/test-in-release-mode`. This should contain brief comments explaining the situation. +- If your exercise implements macro-based testing (see [#392](https://github.com/exercism/rust/issues/392#issuecomment-343865993) and [`perfect-numbers.rs`](https://github.com/exercism/rust/blob/master/exercises/perfect-numbers/tests/perfect-numbers.rs)), you will likely run afoul of a CI check which counts the `#[ignore]` lines and compares the result to the number of `#[test]` lines. To fix this, add a file `.meta/ignore-count-ignores` to disable that check for your exercise. + - `README.md` may be [regenerated](https://github.com/exercism/docs/blob/master/maintaining-a-track/regenerating-exercise-readmes.md) from Exercism data. The generator will use the `description.md` from the exercise directory in the [problem-specifications repository](https://github.com/exercism/problem-specifications/tree/master/exercises), then any hints in `.meta/hints.md`, then the [Rust-specific instructions](https://github.com/exercism/rust/blob/master/config/exercise-readme-insert.md). The `## Source` section comes from the `metadata.yml` in the same directory. Convention is that the description of the source remains text and the link is both name and hyperlink of the markdown link. - Be sure to add the exercise to an appropriate place in the `config.json` file. The position in the file determines the order exercises are sent. Generate a unique UUID for the exercise. Current difficuly levels in use are 1, 4, 7 and 10. From 42e4d9489a7fbf0b21994d6f796c9cdbd62a8722 Mon Sep 17 00:00:00 2001 From: Peter Goodspeed-Niklaus Date: Sun, 19 Nov 2017 11:17:14 +0100 Subject: [PATCH 4/4] Update to use inline ignores --- .../perfect-numbers/tests/perfect-numbers.rs | 33 +++++++------------ 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/exercises/perfect-numbers/tests/perfect-numbers.rs b/exercises/perfect-numbers/tests/perfect-numbers.rs index a1cc48354..9d4d4a0e5 100644 --- a/exercises/perfect-numbers/tests/perfect-numbers.rs +++ b/exercises/perfect-numbers/tests/perfect-numbers.rs @@ -28,27 +28,16 @@ fn basic() { tests! { test_classification { - #[ignore] - test_1(1, Classification::Deficient); - #[ignore] - test_2(2, Classification::Deficient); - #[ignore] - test_4(4, Classification::Deficient); - #[ignore] - test_6(6, Classification::Perfect); - #[ignore] - test_12(12, Classification::Abundant); - #[ignore] - test_28(28, Classification::Perfect); - #[ignore] - test_30(30, Classification::Abundant); - #[ignore] - test_32(32, Classification::Deficient); - #[ignore] - test_33550335(33550335, Classification::Abundant); - #[ignore] - test_33550336(33550336, Classification::Perfect); - #[ignore] - test_33550337(33550337, Classification::Deficient); + #[ignore] test_1(1, Classification::Deficient); + #[ignore] test_2(2, Classification::Deficient); + #[ignore] test_4(4, Classification::Deficient); + #[ignore] test_6(6, Classification::Perfect); + #[ignore] test_12(12, Classification::Abundant); + #[ignore] test_28(28, Classification::Perfect); + #[ignore] test_30(30, Classification::Abundant); + #[ignore] test_32(32, Classification::Deficient); + #[ignore] test_33550335(33550335, Classification::Abundant); + #[ignore] test_33550336(33550336, Classification::Perfect); + #[ignore] test_33550337(33550337, Classification::Deficient); } }