From 76cfb6a40f6425ba4dc6037614ef2e311e93fee4 Mon Sep 17 00:00:00 2001 From: Remo Senekowitsch Date: Wed, 13 Dec 2023 14:10:33 +0100 Subject: [PATCH] Sync series with problem-specifications --- .../practice/series/.meta/test_template.tera | 24 +++++ exercises/practice/series/.meta/tests.toml | 73 ++++++++++++++- exercises/practice/series/tests/series.rs | 90 +++++++++++++++---- 3 files changed, 165 insertions(+), 22 deletions(-) create mode 100644 exercises/practice/series/.meta/test_template.tera diff --git a/exercises/practice/series/.meta/test_template.tera b/exercises/practice/series/.meta/test_template.tera new file mode 100644 index 000000000..64a9fc5fc --- /dev/null +++ b/exercises/practice/series/.meta/test_template.tera @@ -0,0 +1,24 @@ +use {{ crate_name }}::*; + +{% for test in cases %} +#[test] +{% if loop.index != 1 -%} +#[ignore] +{% endif -%} +fn {{ test.description | slugify | replace(from="-", to="_") }}() { + let input = {{ test.input.series | json_encode() }}; + let length = {{ test.input.sliceLength | json_encode() }}; + let output = {{ fn_names[0] }}(input, length); +{%- if test.expected is object -%} + {# + The author of the exercise chose to define the semantics such that + "invalid" series return empty vectors. Adding error handling to the + exercise later would be a breaking change. + #} + let expected: &[&str] = &[]; +{% else %} + let expected = &{{ test.expected | json_encode() }}; +{% endif -%} + assert_eq!(output, expected); +} +{% endfor -%} diff --git a/exercises/practice/series/.meta/tests.toml b/exercises/practice/series/.meta/tests.toml index be690e975..778d6b794 100644 --- a/exercises/practice/series/.meta/tests.toml +++ b/exercises/practice/series/.meta/tests.toml @@ -1,3 +1,70 @@ -# 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. + +[7ae7a46a-d992-4c2a-9c15-a112d125ebad] +description = "slices of one from one" + +[3143b71d-f6a5-4221-aeae-619f906244d2] +description = "slices of one from two" + +[dbb68ff5-76c5-4ccd-895a-93dbec6d5805] +description = "slices of two" + +[19bbea47-c987-4e11-a7d1-e103442adf86] +description = "slices of two overlap" + +[8e17148d-ba0a-4007-a07f-d7f87015d84c] +description = "slices can include duplicates" + +[bd5b085e-f612-4f81-97a8-6314258278b0] +description = "slices of a long series" + +[6d235d85-46cf-4fae-9955-14b6efef27cd] +description = "slice length is too large" + +[d7957455-346d-4e47-8e4b-87ed1564c6d7] +description = "slice length is way too large" + +[d34004ad-8765-4c09-8ba1-ada8ce776806] +description = "slice length cannot be zero" +include = false +comment = """ + This test case has caused a certain amount of confusion. + In the original implementation of the exercise, the test expected: + + series("12345", 0) -> ["", "", "", "", "", ""] + + Reasonable arguments have been made on both sides: + https://github.com/exercism/rust/pull/402 + https://github.com/exercism/rust/issues/671 + + The problem-specifications repository defines this case to return an error. + But the existing interface of the exercise doesn't allow error handling, + so changing it now would be a breaking change. + + It was decided to simply exclude this test case. + Handling this specific edge case in the very specific way it was designed + in the original implementation doesn't further the student's understanding + of Rust as a language. + + In order to avoid breaking existing solutions, there should not be any + tests added in the future where the length of the slice is exactly one more + than the length of the input string. If such tests are added in + problem-specifications, they should be excluded as well. +""" + +[10ab822d-8410-470a-a85d-23fbeb549e54] +description = "slice length cannot be negative" +include = false +comment = "the function signature already prevents this (usize)" + +[c7ed0812-0e4b-4bf3-99c4-28cbbfc246a2] +description = "empty series is invalid" diff --git a/exercises/practice/series/tests/series.rs b/exercises/practice/series/tests/series.rs index 4757d8b55..dc73172ee 100644 --- a/exercises/practice/series/tests/series.rs +++ b/exercises/practice/series/tests/series.rs @@ -1,40 +1,92 @@ use series::*; #[test] -fn with_zero_length() { - let expected = vec!["".to_string(); 6]; - assert_eq!(series("92017", 0), expected); +fn slices_of_one_from_one() { + let input = "1"; + let length = 1; + let output = series(input, length); + let expected = &["1"]; + assert_eq!(output, expected); } #[test] #[ignore] -fn with_length_2() { - let expected = vec![ - "92".to_string(), - "20".to_string(), - "01".to_string(), - "17".to_string(), +fn slices_of_one_from_two() { + let input = "12"; + let length = 1; + let output = series(input, length); + let expected = &["1", "2"]; + assert_eq!(output, expected); +} + +#[test] +#[ignore] +fn slices_of_two() { + let input = "35"; + let length = 2; + let output = series(input, length); + let expected = &["35"]; + assert_eq!(output, expected); +} + +#[test] +#[ignore] +fn slices_of_two_overlap() { + let input = "9142"; + let length = 2; + let output = series(input, length); + let expected = &["91", "14", "42"]; + assert_eq!(output, expected); +} + +#[test] +#[ignore] +fn slices_can_include_duplicates() { + let input = "777777"; + let length = 3; + let output = series(input, length); + let expected = &["777", "777", "777", "777"]; + assert_eq!(output, expected); +} + +#[test] +#[ignore] +fn slices_of_a_long_series() { + let input = "918493904243"; + let length = 5; + let output = series(input, length); + let expected = &[ + "91849", "18493", "84939", "49390", "93904", "39042", "90424", "04243", ]; - assert_eq!(series("92017", 2), expected); + assert_eq!(output, expected); } #[test] #[ignore] -fn with_numbers_length() { - let expected = vec!["92017".to_string()]; - assert_eq!(series("92017", 5), expected); +fn slice_length_is_too_large() { + let input = "12345"; + let length = 6; + let output = series(input, length); + let expected: &[&str] = &[]; + assert_eq!(output, expected); } #[test] #[ignore] -fn too_long() { - let expected: Vec = vec![]; - assert_eq!(series("92017", 6), expected); +fn slice_length_is_way_too_large() { + let input = "12345"; + let length = 42; + let output = series(input, length); + let expected: &[&str] = &[]; + assert_eq!(output, expected); } #[test] #[ignore] -fn way_too_long() { - let expected: Vec = vec![]; - assert_eq!(series("92017", 42), expected); +fn empty_series_is_invalid() { + let input = ""; + let length = 1; + let output = series(input, length); + let expected: &[&str] = &[]; + assert_eq!(output, expected); }