Skip to content

perfect-numbers: Update tests from table-based to macro-based #394

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
23 changes: 15 additions & 8 deletions _test/count-ignores.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
6 changes: 6 additions & 0 deletions exercises/perfect-numbers/.meta/ignore-count-ignores
Original file line number Diff line number Diff line change
@@ -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)
```
54 changes: 32 additions & 22 deletions exercises/perfect-numbers/tests/perfect-numbers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<TestClassification> = 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);
}
}