Skip to content

Commit

Permalink
nucleotide-count: sync (#1981)
Browse files Browse the repository at this point in the history
[no important files changed]

part of #1824
  • Loading branch information
senekor committed Aug 16, 2024
1 parent cbae121 commit 40fc5c8
Show file tree
Hide file tree
Showing 4 changed files with 174 additions and 53 deletions.
72 changes: 72 additions & 0 deletions exercises/practice/nucleotide-count/.meta/additional-tests.json
Original file line number Diff line number Diff line change
@@ -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)"
}
]
39 changes: 39 additions & 0 deletions exercises/practice/nucleotide-count/.meta/test_template.tera
Original file line number Diff line number Diff line change
@@ -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 %}
28 changes: 25 additions & 3 deletions exercises/practice/nucleotide-count/.meta/tests.toml
Original file line number Diff line number Diff line change
@@ -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"
88 changes: 38 additions & 50 deletions exercises/practice/nucleotide-count/tests/nucleotide-count.rs
Original file line number Diff line number Diff line change
@@ -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<char, usize> = 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<(&char, &usize)>>(), 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());
}

0 comments on commit 40fc5c8

Please sign in to comment.