#![expect(
clippy::unwrap_used,
reason = "pre-existing escape unit test debt moved into hl7v2; cleanup is split from topology collapse"
)]
use super::*;
use crate::model::Delims;
#[test]
fn test_escape_field_separator() {
let delims = Delims::default();
let escaped = escape_text("a|b", &delims);
assert_eq!(escaped, "a\\F\\b");
}
#[test]
fn test_escape_component_separator() {
let delims = Delims::default();
let escaped = escape_text("a^b", &delims);
assert_eq!(escaped, "a\\S\\b");
}
#[test]
fn test_escape_repetition_separator() {
let delims = Delims::default();
let escaped = escape_text("a~b", &delims);
assert_eq!(escaped, "a\\R\\b");
}
#[test]
fn test_escape_escape_character() {
let delims = Delims::default();
let escaped = escape_text("a\\b", &delims);
assert_eq!(escaped, "a\\E\\b");
}
#[test]
fn test_escape_subcomponent_separator() {
let delims = Delims::default();
let escaped = escape_text("a&b", &delims);
assert_eq!(escaped, "a\\T\\b");
}
#[test]
fn test_escape_multiple_delimiters() {
let delims = Delims::default();
let escaped = escape_text("a|b^c~d\\e&f", &delims);
assert_eq!(escaped, "a\\F\\b\\S\\c\\R\\d\\E\\e\\T\\f");
}
#[test]
fn test_escape_no_special_chars() {
let delims = Delims::default();
let escaped = escape_text("normal text", &delims);
assert_eq!(escaped, "normal text");
}
#[test]
fn test_escape_empty_string() {
let delims = Delims::default();
let escaped = escape_text("", &delims);
assert_eq!(escaped, "");
}
#[test]
fn test_escape_only_delimiters() {
let delims = Delims::default();
let escaped = escape_text("|^~\\&", &delims);
assert_eq!(escaped, "\\F\\\\S\\\\R\\\\E\\\\T\\");
}
#[test]
fn test_unescape_field_separator() {
let delims = Delims::default();
let unescaped = unescape_text("a\\F\\b", &delims).unwrap();
assert_eq!(unescaped, "a|b");
}
#[test]
fn test_unescape_component_separator() {
let delims = Delims::default();
let unescaped = unescape_text("a\\S\\b", &delims).unwrap();
assert_eq!(unescaped, "a^b");
}
#[test]
fn test_unescape_repetition_separator() {
let delims = Delims::default();
let unescaped = unescape_text("a\\R\\b", &delims).unwrap();
assert_eq!(unescaped, "a~b");
}
#[test]
fn test_unescape_escape_character() {
let delims = Delims::default();
let unescaped = unescape_text("a\\E\\b", &delims).unwrap();
assert_eq!(unescaped, "a\\b");
}
#[test]
fn test_unescape_subcomponent_separator() {
let delims = Delims::default();
let unescaped = unescape_text("a\\T\\b", &delims).unwrap();
assert_eq!(unescaped, "a&b");
}
#[test]
fn test_unescape_multiple_sequences() {
let delims = Delims::default();
let unescaped = unescape_text("a\\F\\b\\S\\c\\R\\d\\E\\e\\T\\f", &delims).unwrap();
assert_eq!(unescaped, "a|b^c~d\\e&f");
}
#[test]
fn test_unescape_no_special_chars() {
let delims = Delims::default();
let unescaped = unescape_text("normal text", &delims).unwrap();
assert_eq!(unescaped, "normal text");
}
#[test]
fn test_unescape_empty_string() {
let delims = Delims::default();
let unescaped = unescape_text("", &delims).unwrap();
assert_eq!(unescaped, "");
}
#[test]
fn test_unescape_unknown_sequence() {
let delims = Delims::default();
let unescaped = unescape_text("a\\X\\b", &delims).unwrap();
assert_eq!(unescaped, "a\\X\\b");
}
#[test]
fn test_roundtrip_unknown_escape_sequence() {
let delims = Delims::default();
let original = "\\Hhighlight\\N text";
let unescaped = unescape_text(original, &delims).unwrap();
assert_eq!(unescaped, "\\Hhighlight\\N text");
let escaped = escape_text(&unescaped, &delims);
assert_eq!(escaped, "\\E\\Hhighlight\\E\\N text");
}
#[test]
fn test_roundtrip_basic() {
let delims = Delims::default();
let original = "test|value^with~special\\chars&here";
let escaped = escape_text(original, &delims);
let unescaped = unescape_text(&escaped, &delims).unwrap();
assert_eq!(unescaped, original);
}
#[test]
fn test_roundtrip_only_delimiters() {
let delims = Delims::default();
let original = "|^~\\&";
let escaped = escape_text(original, &delims);
let unescaped = unescape_text(&escaped, &delims).unwrap();
assert_eq!(unescaped, original);
}
#[test]
fn test_roundtrip_complex() {
let delims = Delims::default();
let original = "Patient|Name^First~Last\\Middle&Suffix";
let escaped = escape_text(original, &delims);
let unescaped = unescape_text(&escaped, &delims).unwrap();
assert_eq!(unescaped, original);
}
#[test]
fn test_roundtrip_unicode() {
let delims = Delims::default();
let original = "Patient|名前^姓~名\\中間名&サフィックス";
let escaped = escape_text(original, &delims);
let unescaped = unescape_text(&escaped, &delims).unwrap();
assert_eq!(unescaped, original);
}
#[test]
fn test_custom_delimiters_escape() {
let delims = Delims {
field: '#',
comp: ':',
rep: '*',
esc: '@',
sub: '%',
};
let escaped = escape_text("a#b:c", &delims);
assert_eq!(escaped, "a@F@b@S@c");
let unescaped = unescape_text(&escaped, &delims).unwrap();
assert_eq!(unescaped, "a#b:c");
}
#[test]
fn test_custom_delimiters_all() {
let delims = Delims {
field: '#',
comp: ':',
rep: '*',
esc: '@',
sub: '%',
};
let original = "a#b:c*d@e%f";
let escaped = escape_text(original, &delims);
assert_eq!(escaped, "a@F@b@S@c@R@d@E@e@T@f");
let unescaped = unescape_text(&escaped, &delims).unwrap();
assert_eq!(unescaped, original);
}
#[test]
fn test_needs_escaping_field() {
let delims = Delims::default();
assert!(needs_escaping("a|b", &delims));
}
#[test]
fn test_needs_escaping_component() {
let delims = Delims::default();
assert!(needs_escaping("a^b", &delims));
}
#[test]
fn test_needs_escaping_repetition() {
let delims = Delims::default();
assert!(needs_escaping("a~b", &delims));
}
#[test]
fn test_needs_escaping_escape() {
let delims = Delims::default();
assert!(needs_escaping("a\\b", &delims));
}
#[test]
fn test_needs_escaping_subcomponent() {
let delims = Delims::default();
assert!(needs_escaping("a&b", &delims));
}
#[test]
fn test_needs_escaping_none() {
let delims = Delims::default();
assert!(!needs_escaping("normal text", &delims));
}
#[test]
fn test_needs_unescaping_true() {
let delims = Delims::default();
assert!(needs_unescaping("a\\F\\b", &delims));
}
#[test]
fn test_needs_unescaping_false() {
let delims = Delims::default();
assert!(!needs_unescaping("normal text", &delims));
}
#[test]
fn test_escape_at_start() {
let delims = Delims::default();
let escaped = escape_text("|start", &delims);
assert_eq!(escaped, "\\F\\start");
}
#[test]
fn test_escape_at_end() {
let delims = Delims::default();
let escaped = escape_text("end|", &delims);
assert_eq!(escaped, "end\\F\\");
}
#[test]
fn test_escape_consecutive() {
let delims = Delims::default();
let escaped = escape_text("||", &delims);
assert_eq!(escaped, "\\F\\\\F\\");
}
#[test]
fn test_unescape_at_start() {
let delims = Delims::default();
let unescaped = unescape_text("\\F\\start", &delims).unwrap();
assert_eq!(unescaped, "|start");
}
#[test]
fn test_unescape_at_end() {
let delims = Delims::default();
let unescaped = unescape_text("end\\F\\", &delims).unwrap();
assert_eq!(unescaped, "end|");
}
#[test]
fn test_unescape_consecutive() {
let delims = Delims::default();
let unescaped = unescape_text("\\F\\\\F\\", &delims).unwrap();
assert_eq!(unescaped, "||");
}
#[test]
fn test_escape_long_string() {
let delims = Delims::default();
let original = "a|b".repeat(1000);
let escaped = escape_text(&original, &delims);
assert_eq!(escaped.matches("\\F\\").count(), 1000);
}
#[test]
fn test_unescape_long_string() {
let delims = Delims::default();
let escaped = "a\\F\\b".repeat(1000);
let unescaped = unescape_text(&escaped, &delims).unwrap();
assert_eq!(unescaped.matches('|').count(), 1000);
}
#[test]
fn test_unescape_incomplete_sequence() {
let delims = Delims::default();
let unescaped = unescape_text("a\\Fb", &delims).unwrap();
assert_eq!(unescaped, "a\\Fb");
}
#[test]
fn test_unescape_msh_encoding_chars() {
let delims = Delims::default();
let unescaped = unescape_text("^~\\&", &delims).unwrap();
assert_eq!(unescaped, "^~^~\\&");
}
#[test]
fn test_escape_preserves_non_delimiter_backslash() {
let delims = Delims::default();
let escaped = escape_text("a\\b", &delims);
assert_eq!(escaped, "a\\E\\b");
}
#[test]
fn test_multiple_escape_chars_in_sequence() {
let delims = Delims::default();
let escaped = escape_text("\\\\\\", &delims);
assert_eq!(escaped, "\\E\\\\E\\\\E\\");
let unescaped = unescape_text(&escaped, &delims).unwrap();
assert_eq!(unescaped, "\\\\\\");
}
#[test]
fn test_escape_unicode() {
let delims = Delims::default();
let original = "Patient|名前";
let escaped = escape_text(original, &delims);
assert_eq!(escaped, "Patient\\F\\名前");
}
#[test]
fn test_unescape_unicode() {
let delims = Delims::default();
let unescaped = unescape_text("Patient\\F\\名前", &delims).unwrap();
assert_eq!(unescaped, "Patient|名前");
}
#[test]
fn test_escape_newlines() {
let delims = Delims::default();
let escaped = escape_text("line1\nline2\rline3", &delims);
assert_eq!(escaped, "line1\nline2\rline3");
}
#[test]
fn test_escape_tabs() {
let delims = Delims::default();
let escaped = escape_text("col1\tcol2", &delims);
assert_eq!(escaped, "col1\tcol2");
}
#[test]
fn test_escape_mixed_content() {
let delims = Delims::default();
let original = "Name|Smith^John~Doe\\Jane&Middle";
let escaped = escape_text(original, &delims);
assert_eq!(
escaped,
"Name\\F\\Smith\\S\\John\\R\\Doe\\E\\Jane\\T\\Middle"
);
}
#[test]
fn test_unescape_mixed_content() {
let delims = Delims::default();
let escaped = "Name\\F\\Smith\\S\\John\\R\\Doe\\E\\Jane\\T\\Middle";
let unescaped = unescape_text(escaped, &delims).unwrap();
assert_eq!(unescaped, "Name|Smith^John~Doe\\Jane&Middle");
}
#[test]
fn test_escape_allocation_efficiency() {
let delims = Delims::default();
let original = "short";
let escaped = escape_text(original, &delims);
assert_eq!(escaped, "short");
assert!(escaped.capacity() <= original.len() * 3);
}
#[test]
fn test_unescape_allocation_efficiency() {
let delims = Delims::default();
let escaped = "short";
let unescaped = unescape_text(escaped, &delims).unwrap();
assert_eq!(unescaped, "short");
assert!(unescaped.capacity() <= escaped.len() + 10);
}