diff --git a/exercises/practice/anagram/.meta/test_template.tera b/exercises/practice/anagram/.meta/test_template.tera new file mode 100644 index 000000000..c6f1533f7 --- /dev/null +++ b/exercises/practice/anagram/.meta/test_template.tera @@ -0,0 +1,16 @@ +use {{ crate_name }}::*; +use std::collections::HashSet; + +{% for test in cases %} +#[test] +{% if loop.index != 1 -%} +#[ignore] +{% endif -%} +fn {{ test.description | slugify | replace(from="-", to="_") }}() { + let word = {{ test.input.subject | json_encode() }}; + let inputs = &{{ test.input.candidates | json_encode() }}; + let output = {{ fn_names[0] }}(word, inputs); + let expected = HashSet::from_iter({{ test.expected | json_encode() }}); + assert_eq!(output, expected); +} +{% endfor -%} diff --git a/exercises/practice/anagram/.meta/tests.toml b/exercises/practice/anagram/.meta/tests.toml index be690e975..4f43811d2 100644 --- a/exercises/practice/anagram/.meta/tests.toml +++ b/exercises/practice/anagram/.meta/tests.toml @@ -1,3 +1,80 @@ -# 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. + +[dd40c4d2-3c8b-44e5-992a-f42b393ec373] +description = "no matches" + +[b3cca662-f50a-489e-ae10-ab8290a09bdc] +description = "detects two anagrams" +include = false + +[03eb9bbe-8906-4ea0-84fa-ffe711b52c8b] +description = "detects two anagrams" +reimplements = "b3cca662-f50a-489e-ae10-ab8290a09bdc" + +[a27558ee-9ba0-4552-96b1-ecf665b06556] +description = "does not detect anagram subsets" + +[64cd4584-fc15-4781-b633-3d814c4941a4] +description = "detects anagram" + +[99c91beb-838f-4ccd-b123-935139917283] +description = "detects three anagrams" + +[78487770-e258-4e1f-a646-8ece10950d90] +description = "detects multiple anagrams with different case" + +[1d0ab8aa-362f-49b7-9902-3d0c668d557b] +description = "does not detect non-anagrams with identical checksum" + +[9e632c0b-c0b1-4804-8cc1-e295dea6d8a8] +description = "detects anagrams case-insensitively" + +[b248e49f-0905-48d2-9c8d-bd02d8c3e392] +description = "detects anagrams using case-insensitive subject" + +[f367325c-78ec-411c-be76-e79047f4bd54] +description = "detects anagrams using case-insensitive possible matches" + +[7cc195ad-e3c7-44ee-9fd2-d3c344806a2c] +description = "does not detect an anagram if the original word is repeated" +include = false + +[630abb71-a94e-4715-8395-179ec1df9f91] +description = "does not detect an anagram if the original word is repeated" +reimplements = "7cc195ad-e3c7-44ee-9fd2-d3c344806a2c" + +[9878a1c9-d6ea-4235-ae51-3ea2befd6842] +description = "anagrams must use all letters exactly once" + +[85757361-4535-45fd-ac0e-3810d40debc1] +description = "words are not anagrams of themselves (case-insensitive)" +include = false + +[68934ed0-010b-4ef9-857a-20c9012d1ebf] +description = "words are not anagrams of themselves" +reimplements = "85757361-4535-45fd-ac0e-3810d40debc1" + +[589384f3-4c8a-4e7d-9edc-51c3e5f0c90e] +description = "words are not anagrams of themselves even if letter case is partially different" +reimplements = "85757361-4535-45fd-ac0e-3810d40debc1" + +[ba53e423-7e02-41ee-9ae2-71f91e6d18e6] +description = "words are not anagrams of themselves even if letter case is completely different" +reimplements = "85757361-4535-45fd-ac0e-3810d40debc1" + +[a0705568-628c-4b55-9798-82e4acde51ca] +description = "words other than themselves can be anagrams" +include = false + +[33d3f67e-fbb9-49d3-a90e-0beb00861da7] +description = "words other than themselves can be anagrams" +reimplements = "a0705568-628c-4b55-9798-82e4acde51ca" diff --git a/exercises/practice/anagram/tests/anagram.rs b/exercises/practice/anagram/tests/anagram.rs index 4ac7a283c..44cab71a0 100644 --- a/exercises/practice/anagram/tests/anagram.rs +++ b/exercises/practice/anagram/tests/anagram.rs @@ -1,78 +1,50 @@ +use anagram::*; use std::collections::HashSet; -fn process_anagram_case(word: &str, inputs: &[&str], expected: &[&str]) { - let result = anagram::anagrams_for(word, inputs); - - let expected: HashSet<&str> = expected.iter().cloned().collect(); - - assert_eq!(result, expected); -} - #[test] fn no_matches() { let word = "diaper"; - - let inputs = ["hello", "world", "zombies", "pants"]; - - let outputs = vec![]; - - process_anagram_case(word, &inputs, &outputs); + let inputs = &["hello", "world", "zombies", "pants"]; + let output = anagrams_for(word, inputs); + let expected = HashSet::from_iter([]); + assert_eq!(output, expected); } #[test] #[ignore] -fn detect_simple_anagram() { - let word = "ant"; - - let inputs = ["tan", "stand", "at"]; - - let outputs = vec!["tan"]; - - process_anagram_case(word, &inputs, &outputs); +fn detects_two_anagrams() { + let word = "solemn"; + let inputs = &["lemons", "cherry", "melons"]; + let output = anagrams_for(word, inputs); + let expected = HashSet::from_iter(["lemons", "melons"]); + assert_eq!(output, expected); } #[test] #[ignore] -fn does_not_confuse_different_duplicates() { - let word = "galea"; - - let inputs = ["eagle"]; - - let outputs = vec![]; - - process_anagram_case(word, &inputs, &outputs); -} - -#[test] -#[ignore] -fn eliminate_anagram_subsets() { +fn does_not_detect_anagram_subsets() { let word = "good"; - - let inputs = ["dog", "goody"]; - - let outputs = vec![]; - - process_anagram_case(word, &inputs, &outputs); + let inputs = &["dog", "goody"]; + let output = anagrams_for(word, inputs); + let expected = HashSet::from_iter([]); + assert_eq!(output, expected); } #[test] #[ignore] -fn detect_anagram() { +fn detects_anagram() { let word = "listen"; - - let inputs = ["enlists", "google", "inlets", "banana"]; - - let outputs = vec!["inlets"]; - - process_anagram_case(word, &inputs, &outputs); + let inputs = &["enlists", "google", "inlets", "banana"]; + let output = anagrams_for(word, inputs); + let expected = HashSet::from_iter(["inlets"]); + assert_eq!(output, expected); } #[test] #[ignore] -fn multiple_anagrams() { +fn detects_three_anagrams() { let word = "allergy"; - - let inputs = [ + let inputs = &[ "gallery", "ballerina", "regally", @@ -80,107 +52,117 @@ fn multiple_anagrams() { "largely", "leading", ]; + let output = anagrams_for(word, inputs); + let expected = HashSet::from_iter(["gallery", "regally", "largely"]); + assert_eq!(output, expected); +} - let outputs = vec!["gallery", "regally", "largely"]; +#[test] +#[ignore] +fn detects_multiple_anagrams_with_different_case() { + let word = "nose"; + let inputs = &["Eons", "ONES"]; + let output = anagrams_for(word, inputs); + let expected = HashSet::from_iter(["Eons", "ONES"]); + assert_eq!(output, expected); +} - process_anagram_case(word, &inputs, &outputs); +#[test] +#[ignore] +fn does_not_detect_non_anagrams_with_identical_checksum() { + let word = "mass"; + let inputs = &["last"]; + let output = anagrams_for(word, inputs); + let expected = HashSet::from_iter([]); + assert_eq!(output, expected); } #[test] #[ignore] -fn case_insensitive_anagrams() { +fn detects_anagrams_case_insensitively() { let word = "Orchestra"; - - let inputs = ["cashregister", "Carthorse", "radishes"]; - - let outputs = vec!["Carthorse"]; - - process_anagram_case(word, &inputs, &outputs); + let inputs = &["cashregister", "Carthorse", "radishes"]; + let output = anagrams_for(word, inputs); + let expected = HashSet::from_iter(["Carthorse"]); + assert_eq!(output, expected); } #[test] #[ignore] -fn unicode_anagrams() { - let word = "ΑΒΓ"; - - // These words don't make sense, they're just greek letters cobbled together. - let inputs = ["ΒΓΑ", "ΒΓΔ", "γβα"]; - - let outputs = vec!["ΒΓΑ", "γβα"]; - - process_anagram_case(word, &inputs, &outputs); +fn detects_anagrams_using_case_insensitive_subject() { + let word = "Orchestra"; + let inputs = &["cashregister", "carthorse", "radishes"]; + let output = anagrams_for(word, inputs); + let expected = HashSet::from_iter(["carthorse"]); + assert_eq!(output, expected); } #[test] #[ignore] -fn misleading_unicode_anagrams() { - // Despite what a human might think these words contain different letters, the input uses Greek - // A and B while the list of potential anagrams uses Latin A and B. - let word = "ΑΒΓ"; - - let inputs = ["ABΓ"]; - - let outputs = vec![]; - - process_anagram_case(word, &inputs, &outputs); +fn detects_anagrams_using_case_insensitive_possible_matches() { + let word = "orchestra"; + let inputs = &["cashregister", "Carthorse", "radishes"]; + let output = anagrams_for(word, inputs); + let expected = HashSet::from_iter(["Carthorse"]); + assert_eq!(output, expected); } #[test] #[ignore] -fn does_not_detect_a_word_as_its_own_anagram() { - let word = "banana"; - - let inputs = ["banana"]; - - let outputs = vec![]; - - process_anagram_case(word, &inputs, &outputs); +fn does_not_detect_an_anagram_if_the_original_word_is_repeated() { + let word = "go"; + let inputs = &["goGoGO"]; + let output = anagrams_for(word, inputs); + let expected = HashSet::from_iter([]); + assert_eq!(output, expected); } #[test] #[ignore] -fn does_not_detect_a_differently_cased_word_as_its_own_anagram() { - let word = "banana"; - - let inputs = ["bAnana"]; - - let outputs = vec![]; - - process_anagram_case(word, &inputs, &outputs); +fn anagrams_must_use_all_letters_exactly_once() { + let word = "tapper"; + let inputs = &["patter"]; + let output = anagrams_for(word, inputs); + let expected = HashSet::from_iter([]); + assert_eq!(output, expected); } #[test] #[ignore] -fn does_not_detect_a_differently_cased_unicode_word_as_its_own_anagram() { - let word = "ΑΒΓ"; - - let inputs = ["ΑΒγ"]; - - let outputs = vec![]; - - process_anagram_case(word, &inputs, &outputs); +fn words_are_not_anagrams_of_themselves() { + let word = "BANANA"; + let inputs = &["BANANA"]; + let output = anagrams_for(word, inputs); + let expected = HashSet::from_iter([]); + assert_eq!(output, expected); } #[test] #[ignore] -fn same_bytes_different_chars() { - let word = "a⬂"; // 61 E2 AC 82 - - let inputs = ["€a"]; // E2 82 AC 61 - - let outputs = vec![]; - - process_anagram_case(word, &inputs, &outputs); +fn words_are_not_anagrams_of_themselves_even_if_letter_case_is_partially_different() { + let word = "BANANA"; + let inputs = &["Banana"]; + let output = anagrams_for(word, inputs); + let expected = HashSet::from_iter([]); + assert_eq!(output, expected); } #[test] #[ignore] -fn different_words_but_same_ascii_sum() { - let word = "bc"; - - let inputs = ["ad"]; - - let outputs = vec![]; +fn words_are_not_anagrams_of_themselves_even_if_letter_case_is_completely_different() { + let word = "BANANA"; + let inputs = &["banana"]; + let output = anagrams_for(word, inputs); + let expected = HashSet::from_iter([]); + assert_eq!(output, expected); +} - process_anagram_case(word, &inputs, &outputs); +#[test] +#[ignore] +fn words_other_than_themselves_can_be_anagrams() { + let word = "LISTEN"; + let inputs = &["LISTEN", "Silent"]; + let output = anagrams_for(word, inputs); + let expected = HashSet::from_iter(["Silent"]); + assert_eq!(output, expected); }