From e84bf04206f1550df7fe8c41fe3993b8bb80beec Mon Sep 17 00:00:00 2001 From: Remo Senekowitsch Date: Fri, 16 Aug 2024 07:57:21 +0200 Subject: [PATCH] luhn: sync part of https://github.com/exercism/rust/issues/1824 --- exercises/practice/luhn/.docs/instructions.md | 3 +- .../practice/luhn/.meta/test_template.tera | 9 ++ exercises/practice/luhn/.meta/tests.toml | 79 +++++++++++++++- exercises/practice/luhn/tests/luhn.rs | 91 +++++++++---------- 4 files changed, 128 insertions(+), 54 deletions(-) create mode 100644 exercises/practice/luhn/.meta/test_template.tera diff --git a/exercises/practice/luhn/.docs/instructions.md b/exercises/practice/luhn/.docs/instructions.md index 8cbe791fc..49934c106 100644 --- a/exercises/practice/luhn/.docs/instructions.md +++ b/exercises/practice/luhn/.docs/instructions.md @@ -22,7 +22,8 @@ The first step of the Luhn algorithm is to double every second digit, starting f We will be doubling ```text -4_3_ 3_9_ 0_4_ 6_6_ +4539 3195 0343 6467 +↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ (double these) ``` If doubling the number results in a number greater than 9 then subtract 9 from the product. diff --git a/exercises/practice/luhn/.meta/test_template.tera b/exercises/practice/luhn/.meta/test_template.tera new file mode 100644 index 000000000..d726197ed --- /dev/null +++ b/exercises/practice/luhn/.meta/test_template.tera @@ -0,0 +1,9 @@ +use luhn::*; + +{% for test in cases %} +#[test] +#[ignore] +fn {{ test.description | make_ident }}() { + assert!({% if not test.expected %} ! {% endif %}is_valid({{ test.input.value | json_encode() }})); +} +{% endfor -%} diff --git a/exercises/practice/luhn/.meta/tests.toml b/exercises/practice/luhn/.meta/tests.toml index be690e975..c0be0c4d9 100644 --- a/exercises/practice/luhn/.meta/tests.toml +++ b/exercises/practice/luhn/.meta/tests.toml @@ -1,3 +1,76 @@ -# This is an auto-generated file. Regular comments will be removed when this -# file is regenerated. Regenerating will not touch any manually added keys, -# so comments can be added in a "comment" key. +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[792a7082-feb7-48c7-b88b-bbfec160865e] +description = "single digit strings can not be valid" + +[698a7924-64d4-4d89-8daa-32e1aadc271e] +description = "a single zero is invalid" + +[73c2f62b-9b10-4c9f-9a04-83cee7367965] +description = "a simple valid SIN that remains valid if reversed" + +[9369092e-b095-439f-948d-498bd076be11] +description = "a simple valid SIN that becomes invalid if reversed" + +[8f9f2350-1faf-4008-ba84-85cbb93ffeca] +description = "a valid Canadian SIN" + +[1cdcf269-6560-44fc-91f6-5819a7548737] +description = "invalid Canadian SIN" + +[656c48c1-34e8-4e60-9a5a-aad8a367810a] +description = "invalid credit card" + +[20e67fad-2121-43ed-99a8-14b5b856adb9] +description = "invalid long number with an even remainder" + +[7e7c9fc1-d994-457c-811e-d390d52fba5e] +description = "invalid long number with a remainder divisible by 5" + +[ad2a0c5f-84ed-4e5b-95da-6011d6f4f0aa] +description = "valid number with an even number of digits" + +[ef081c06-a41f-4761-8492-385e13c8202d] +description = "valid number with an odd number of spaces" + +[bef66f64-6100-4cbb-8f94-4c9713c5e5b2] +description = "valid strings with a non-digit added at the end become invalid" + +[2177e225-9ce7-40f6-b55d-fa420e62938e] +description = "valid strings with punctuation included become invalid" + +[ebf04f27-9698-45e1-9afe-7e0851d0fe8d] +description = "valid strings with symbols included become invalid" + +[08195c5e-ce7f-422c-a5eb-3e45fece68ba] +description = "single zero with space is invalid" + +[12e63a3c-f866-4a79-8c14-b359fc386091] +description = "more than a single zero is valid" + +[ab56fa80-5de8-4735-8a4a-14dae588663e] +description = "input digit 9 is correctly converted to output digit 9" + +[b9887ee8-8337-46c5-bc45-3bcab51bc36f] +description = "very long input is valid" + +[8a7c0e24-85ea-4154-9cf1-c2db90eabc08] +description = "valid luhn with an odd number of digits and non zero first digit" + +[39a06a5a-5bad-4e0f-b215-b042d46209b1] +description = "using ascii value for non-doubled non-digit isn't allowed" + +[f94cf191-a62f-4868-bc72-7253114aa157] +description = "using ascii value for doubled non-digit isn't allowed" + +[8b72ad26-c8be-49a2-b99c-bcc3bf631b33] +description = "non-numeric, non-space char in the middle with a sum that's divisible by 10 isn't allowed" diff --git a/exercises/practice/luhn/tests/luhn.rs b/exercises/practice/luhn/tests/luhn.rs index c2ce6839b..15fb8e8e6 100644 --- a/exercises/practice/luhn/tests/luhn.rs +++ b/exercises/practice/luhn/tests/luhn.rs @@ -1,141 +1,132 @@ use luhn::*; -fn process_valid_case(number: &str, is_luhn_expected: bool) { - assert_eq!(is_valid(number), is_luhn_expected); -} - #[test] fn single_digit_strings_can_not_be_valid() { - process_valid_case("1", false); + assert!(!is_valid("1")); } #[test] #[ignore] fn a_single_zero_is_invalid() { - process_valid_case("0", false); + assert!(!is_valid("0")); } #[test] #[ignore] fn a_simple_valid_sin_that_remains_valid_if_reversed() { - process_valid_case("059", true); + assert!(is_valid("059")); } #[test] #[ignore] fn a_simple_valid_sin_that_becomes_invalid_if_reversed() { - process_valid_case("59", true); + assert!(is_valid("59")); } #[test] #[ignore] fn a_valid_canadian_sin() { - process_valid_case("055 444 285", true); + assert!(is_valid("055 444 285")); } #[test] #[ignore] fn invalid_canadian_sin() { - process_valid_case("055 444 286", false); + assert!(!is_valid("055 444 286")); } #[test] #[ignore] fn invalid_credit_card() { - process_valid_case("8273 1232 7352 0569", false); + assert!(!is_valid("8273 1232 7352 0569")); } #[test] #[ignore] -fn valid_number_with_an_even_number_of_digits() { - process_valid_case("095 245 88", true); +fn invalid_long_number_with_an_even_remainder() { + assert!(!is_valid("1 2345 6789 1234 5678 9012")); } #[test] #[ignore] -fn strings_that_contain_non_digits_are_invalid() { - process_valid_case("055a 444 285", false); +fn invalid_long_number_with_a_remainder_divisible_by_5() { + assert!(!is_valid("1 2345 6789 1234 5678 9013")); } #[test] #[ignore] -fn valid_strings_with_punctuation_included_become_invalid() { - process_valid_case("055-444-285", false); +fn valid_number_with_an_even_number_of_digits() { + assert!(is_valid("095 245 88")); } #[test] #[ignore] -fn symbols_are_invalid() { - process_valid_case("055£ 444$ 285", false); +fn valid_number_with_an_odd_number_of_spaces() { + assert!(is_valid("234 567 891 234")); } #[test] #[ignore] -fn single_zero_with_space_is_invalid() { - process_valid_case(" 0", false); +fn valid_strings_with_a_non_digit_added_at_the_end_become_invalid() { + assert!(!is_valid("059a")); } #[test] #[ignore] -fn more_than_a_single_zero_is_valid() { - process_valid_case("0000 0", true); +fn valid_strings_with_punctuation_included_become_invalid() { + assert!(!is_valid("055-444-285")); } #[test] #[ignore] -fn input_digit_9_is_correctly_converted_to_output_digit_9() { - process_valid_case("091", true); +fn valid_strings_with_symbols_included_become_invalid() { + assert!(!is_valid("055# 444$ 285")); } #[test] #[ignore] -/// using ASCII value for doubled non-digit isn't allowed -/// Convert non-digits to their ASCII values and then offset them by 48 sometimes accidentally declare an invalid string to be valid. -/// This test is designed to avoid that solution. -fn using_ascii_value_for_doubled_nondigit_isnt_allowed() { - process_valid_case(":9", false); +fn single_zero_with_space_is_invalid() { + assert!(!is_valid(" 0")); } #[test] #[ignore] -/// valid strings with a non-digit added at the end become invalid -fn valid_strings_with_a_nondigit_added_at_the_end_become_invalid() { - process_valid_case("059a", false); +fn more_than_a_single_zero_is_valid() { + assert!(is_valid("0000 0")); } #[test] #[ignore] -/// valid strings with symbols included become invalid -fn valid_strings_with_symbols_included_become_invalid() { - process_valid_case("055# 444$ 285", false); +fn input_digit_9_is_correctly_converted_to_output_digit_9() { + assert!(is_valid("091")); } #[test] #[ignore] -/// using ASCII value for non-doubled non-digit isn't allowed -/// Convert non-digits to their ASCII values and then offset them by 48 sometimes accidentally declare an invalid string to be valid. -/// This test is designed to avoid that solution. -fn using_ascii_value_for_nondoubled_nondigit_isnt_allowed() { - process_valid_case("055b 444 285", false); +fn very_long_input_is_valid() { + assert!(is_valid("9999999999 9999999999 9999999999 9999999999")); } #[test] #[ignore] -/// valid number with an odd number of spaces -fn valid_number_with_an_odd_number_of_spaces() { - process_valid_case("234 567 891 234", true); +fn valid_luhn_with_an_odd_number_of_digits_and_non_zero_first_digit() { + assert!(is_valid("109")); +} + +#[test] +#[ignore] +fn using_ascii_value_for_non_doubled_non_digit_isn_t_allowed() { + assert!(!is_valid("055b 444 285")); } #[test] #[ignore] -/// non-numeric, non-space char in the middle with a sum that's divisible by 10 isn't allowed -fn invalid_char_in_middle_with_sum_divisible_by_10_isnt_allowed() { - process_valid_case("59%59", false); +fn using_ascii_value_for_doubled_non_digit_isn_t_allowed() { + assert!(!is_valid(":9")); } #[test] #[ignore] -/// unicode numeric characters are not allowed in a otherwise valid number -fn valid_strings_with_numeric_unicode_characters_become_invalid() { - process_valid_case("1249①", false); +fn non_numeric_non_space_char_in_the_middle_with_a_sum_that_s_divisible_by_10_isn_t_allowed() { + assert!(!is_valid("59%59")); }