diff --git a/exercises/practice/nucleotide-count/.meta/additional-tests.json b/exercises/practice/nucleotide-count/.meta/additional-tests.json new file mode 100644 index 000000000..bad9e678a --- /dev/null +++ b/exercises/practice/nucleotide-count/.meta/additional-tests.json @@ -0,0 +1,72 @@ +[ + { + "uuid": "3e5c30a8-87e2-4845-a815-a49671ade970", + "description": "count_empty", + "comments": [ + "The exercise was designed with a `count` method", + "which should be tested as well." + ], + "property": "count", + "input": { + "nucleotide": "A", + "strand": "" + }, + "expected": "Ok(0)" + }, + { + "uuid": "3e5c30a8-87e2-4845-a815-a49671ade970", + "description": "count_invalid_nucleotide", + "comments": [ + "The exercise was designed with a `count` method", + "which should be tested as well." + ], + "property": "count", + "input": { + "nucleotide": "X", + "strand": "A" + }, + "expected": "Err('X')" + }, + { + "uuid": "3e5c30a8-87e2-4845-a815-a49671ade970", + "description": "count_invalid_dna", + "comments": [ + "The exercise was designed with a `count` method", + "which should be tested as well." + ], + "property": "count", + "input": { + "nucleotide": "A", + "strand": "AX" + }, + "expected": "Err('X')" + }, + { + "uuid": "3e5c30a8-87e2-4845-a815-a49671ade970", + "description": "count_repetitive_cytosine", + "comments": [ + "The exercise was designed with a `count` method", + "which should be tested as well." + ], + "property": "count", + "input": { + "nucleotide": "C", + "strand": "CCCCC" + }, + "expected": "Ok(5)" + }, + { + "uuid": "3e5c30a8-87e2-4845-a815-a49671ade970", + "description": "count_only_thymine", + "comments": [ + "The exercise was designed with a `count` method", + "which should be tested as well." + ], + "property": "count", + "input": { + "nucleotide": "T", + "strand": "GGGGGTAACCCGG" + }, + "expected": "Ok(1)" + } +] diff --git a/exercises/practice/nucleotide-count/.meta/test_template.tera b/exercises/practice/nucleotide-count/.meta/test_template.tera new file mode 100644 index 000000000..bd1d4baa1 --- /dev/null +++ b/exercises/practice/nucleotide-count/.meta/test_template.tera @@ -0,0 +1,39 @@ +use std::collections::HashMap; + +use nucleotide_count::*; + +{% for test in cases %} +{# + Additional tests are appended, but we want to test the `count` API first. +#} +{% if test.property != "count" %} + {% continue %} +{% endif %} + +#[test] +#[ignore] +fn {{ test.description | make_ident }}() { + assert_eq!(count('{{ test.input.nucleotide }}', {{ test.input.strand | json_encode() }}), {{ test.expected }}); +} +{% endfor %} + +{% for test in cases %} +{% if test.property == "count" %} + {% continue %} +{% endif %} + +#[test] +#[ignore] +fn {{ test.description | make_ident }}() { + let output = nucleotide_counts({{ test.input.strand | json_encode() }}); + {% if "error" in test.expected -%} + assert!(output.is_err()); + {% else -%} + let mut expected = HashMap::new(); + {% for key, val in test.expected -%} + expected.insert('{{ key }}', {{ val }}); + {% endfor -%} + assert_eq!(output, Ok(expected)); + {% endif -%} +} +{% endfor %} diff --git a/exercises/practice/nucleotide-count/.meta/tests.toml b/exercises/practice/nucleotide-count/.meta/tests.toml index be690e975..7c55e53f2 100644 --- a/exercises/practice/nucleotide-count/.meta/tests.toml +++ b/exercises/practice/nucleotide-count/.meta/tests.toml @@ -1,3 +1,25 @@ -# 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. + +[3e5c30a8-87e2-4845-a815-a49671ade970] +description = "empty strand" + +[a0ea42a6-06d9-4ac6-828c-7ccaccf98fec] +description = "can count one nucleotide in single-character input" + +[eca0d565-ed8c-43e7-9033-6cefbf5115b5] +description = "strand with repeated nucleotide" + +[40a45eac-c83f-4740-901a-20b22d15a39f] +description = "strand with multiple nucleotides" + +[b4c47851-ee9e-4b0a-be70-a86e343bd851] +description = "strand with invalid nucleotides" diff --git a/exercises/practice/nucleotide-count/tests/nucleotide-count.rs b/exercises/practice/nucleotide-count/tests/nucleotide-count.rs index 83b3bf5e2..e820b0d9e 100644 --- a/exercises/practice/nucleotide-count/tests/nucleotide-count.rs +++ b/exercises/practice/nucleotide-count/tests/nucleotide-count.rs @@ -1,100 +1,88 @@ -use nucleotide_count as dna; - use std::collections::HashMap; -fn process_nucleotidecounts_case(s: &str, pairs: &[(char, usize)]) { - // The reason for the awkward code in here is to ensure that the failure - // message for assert_eq! is as informative as possible. A simpler - // solution would simply check the length of the map, and then - // check for the presence and value of each key in the given pairs vector. - let mut m: HashMap = dna::nucleotide_counts(s).unwrap(); - for &(k, v) in pairs.iter() { - assert_eq!((k, m.remove(&k)), (k, Some(v))); - } - - // may fail with a message that clearly shows all extra pairs in the map - assert_eq!(m.iter().collect::>(), vec![]); -} - -#[test] -fn count_returns_result() { - assert!(dna::count('A', "").is_ok()); -} +use nucleotide_count::*; #[test] -#[ignore] fn count_empty() { - assert_eq!(dna::count('A', ""), Ok(0)); + assert_eq!(count('A', ""), Ok(0)); } #[test] #[ignore] fn count_invalid_nucleotide() { - assert_eq!(dna::count('X', "A"), Err('X')); + assert_eq!(count('X', "A"), Err('X')); } #[test] #[ignore] fn count_invalid_dna() { - assert_eq!(dna::count('A', "AX"), Err('X')); + assert_eq!(count('A', "AX"), Err('X')); } #[test] #[ignore] fn count_repetitive_cytosine() { - assert_eq!(dna::count('C', "CCCCC"), Ok(5)); + assert_eq!(count('C', "CCCCC"), Ok(5)); } #[test] #[ignore] fn count_only_thymine() { - assert_eq!(dna::count('T', "GGGGGTAACCCGG"), Ok(1)); -} - -#[test] -#[ignore] -fn counts_returns_result() { - assert!(dna::nucleotide_counts("ACGT").is_ok()); + assert_eq!(count('T', "GGGGGTAACCCGG"), Ok(1)); } #[test] #[ignore] fn empty_strand() { - process_nucleotidecounts_case("", &[('A', 0), ('T', 0), ('C', 0), ('G', 0)]); + let output = nucleotide_counts(""); + let mut expected = HashMap::new(); + expected.insert('A', 0); + expected.insert('C', 0); + expected.insert('G', 0); + expected.insert('T', 0); + assert_eq!(output, Ok(expected)); } #[test] #[ignore] -/// can count one nucleotide in single-character input -fn can_count_one_nucleotide_in_singlecharacter_input() { - process_nucleotidecounts_case("G", &[('A', 0), ('C', 0), ('G', 1), ('T', 0)]); +fn can_count_one_nucleotide_in_single_character_input() { + let output = nucleotide_counts("G"); + let mut expected = HashMap::new(); + expected.insert('A', 0); + expected.insert('C', 0); + expected.insert('G', 1); + expected.insert('T', 0); + assert_eq!(output, Ok(expected)); } #[test] #[ignore] fn strand_with_repeated_nucleotide() { - process_nucleotidecounts_case("GGGGGGG", &[('A', 0), ('T', 0), ('C', 0), ('G', 7)]); + let output = nucleotide_counts("GGGGGGG"); + let mut expected = HashMap::new(); + expected.insert('A', 0); + expected.insert('C', 0); + expected.insert('G', 7); + expected.insert('T', 0); + assert_eq!(output, Ok(expected)); } #[test] #[ignore] -/// strand with multiple nucleotides fn strand_with_multiple_nucleotides() { - process_nucleotidecounts_case( - "AGCTTTTCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAAAAAGAGTGTCTGATAGCAGC", - &[('A', 20), ('T', 21), ('C', 12), ('G', 17)], - ); -} - -#[test] -#[ignore] -fn counts_invalid_nucleotide_results_in_err() { - assert_eq!(dna::nucleotide_counts("GGXXX"), Err('X')); + let output = + nucleotide_counts("AGCTTTTCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAAAAAGAGTGTCTGATAGCAGC"); + let mut expected = HashMap::new(); + expected.insert('A', 20); + expected.insert('C', 12); + expected.insert('G', 17); + expected.insert('T', 21); + assert_eq!(output, Ok(expected)); } #[test] #[ignore] -/// strand with invalid nucleotides fn strand_with_invalid_nucleotides() { - assert_eq!(dna::nucleotide_counts("AGXXACT"), Err('X'),); + let output = nucleotide_counts("AGXXACT"); + assert!(output.is_err()); }