From 1fded48142cace9878b5fd0b79f5652641190b71 Mon Sep 17 00:00:00 2001 From: Brummel Date: Sun, 31 May 2026 18:53:17 +0200 Subject: [PATCH] test: red for un-padded --chapters filter input MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pins the property that the `--chapters` CLI token list normalizes to the zero-padded chapter-tag form ("01".."22") that Filter::accepts compares against, so "4" filters identically to "04", and any token mapping to no known chapter is surfaced as unrecognised (for a stderr warning) rather than silently collapsing the result set to empty. RED: alpha_id::model::normalize_chapters does not exist yet — the test fails to compile. The GREEN side follows in the next commit. refs #1 Co-Authored-By: Claude Opus 4.8 (1M context) --- tests/chapter_filter_normalize_tests.rs | 46 +++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 tests/chapter_filter_normalize_tests.rs diff --git a/tests/chapter_filter_normalize_tests.rs b/tests/chapter_filter_normalize_tests.rs new file mode 100644 index 0000000..9c1f829 --- /dev/null +++ b/tests/chapter_filter_normalize_tests.rs @@ -0,0 +1,46 @@ +//! Property: the `--chapters` CLI token list is normalized to the zero-padded +//! chapter-tag form ("01".."22") that `Filter::accepts` compares against, so a +//! bare number ("4") filters identically to its padded form ("04"). Any token +//! that maps to no known ICD-10-GM chapter is surfaced as unrecognised (for a +//! stderr warning) instead of silently collapsing the result set to empty. +//! +//! Regression for: `--chapters 4,9` / `--chapters E` silently returned zero +//! suggestions because the CLI passed raw split+trim tokens straight into the +//! filter, which compares by exact string equality against padded tags. + +use alpha_id::model::normalize_chapters; + +#[test] +fn bare_and_padded_numbers_normalize_to_the_same_padded_tag() { + let (padded_bare, unknown_bare) = normalize_chapters("4,9"); + let (padded_pad, unknown_pad) = normalize_chapters("04,09"); + + assert_eq!(padded_bare, vec!["04".to_string(), "09".to_string()]); + assert_eq!(padded_bare, padded_pad); + assert!(unknown_bare.is_empty()); + assert!(unknown_pad.is_empty()); +} + +#[test] +fn out_of_range_number_is_surfaced_as_unrecognised() { + // "99" is a syntactically-valid number but not one of the 22 chapters. + let (padded, unknown) = normalize_chapters("99"); + assert!(padded.is_empty()); + assert_eq!(unknown, vec!["99".to_string()]); +} + +#[test] +fn non_numeric_token_is_surfaced_as_unrecognised() { + // Under the contract a letter like "E" is simply an unknown token: it must + // be reported, not silently dropped into an empty-result filter. + let (padded, unknown) = normalize_chapters("E"); + assert!(padded.is_empty()); + assert_eq!(unknown, vec!["E".to_string()]); +} + +#[test] +fn mixed_known_and_unknown_tokens_split_correctly() { + let (padded, unknown) = normalize_chapters("4, 99, 9"); + assert_eq!(padded, vec!["04".to_string(), "09".to_string()]); + assert_eq!(unknown, vec!["99".to_string()]); +}