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. 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) +``` diff --git a/exercises/perfect-numbers/tests/perfect-numbers.rs b/exercises/perfect-numbers/tests/perfect-numbers.rs index 24b276d1c..9d4d4a0e5 100644 --- a/exercises/perfect-numbers/tests/perfect-numbers.rs +++ b/exercises/perfect-numbers/tests/perfect-numbers.rs @@ -2,32 +2,42 @@ 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); } }