#![allow(missing_docs)]
use noyalib::{Value, from_str};
#[test]
fn surrogate_pair_encodes_musical_g_clef() {
let yaml = "music: \"\\uD834\\uDD1E\"";
let v: Value = from_str(yaml).unwrap();
assert_eq!(v["music"].as_str(), Some("𝄞"));
assert_eq!(
v["music"].as_str().unwrap().as_bytes(),
&[0xF0, 0x9D, 0x84, 0x9E]
);
}
#[test]
fn surrogate_pair_encodes_emoji_face() {
let yaml = "emoji: \"\\uD83D\\uDE00\"";
let v: Value = from_str(yaml).unwrap();
assert_eq!(v["emoji"].as_str(), Some("😀"));
}
#[test]
fn multiple_surrogate_pairs_in_one_string() {
let yaml = "music: \"\\uD834\\uDD1E\\uD83C\\uDFB5\\uD83C\\uDFB6\"";
let v: Value = from_str(yaml).unwrap();
assert_eq!(v["music"].as_str(), Some("𝄞🎵🎶"));
}
#[test]
fn surrogate_pair_mixed_with_bmp_escapes() {
let yaml = "s: \"\\u00E9\\uD834\\uDD1E\\u00E9\"";
let v: Value = from_str(yaml).unwrap();
assert_eq!(v["s"].as_str(), Some("é𝄞é"));
}
#[test]
fn lone_high_surrogate_errors() {
let yaml = "bad: \"\\uD834\"";
let err = from_str::<Value>(yaml).unwrap_err();
let msg = err.to_string();
assert!(
msg.contains("D834") || msg.contains("surrogate"),
"expected surrogate-rejection error, got: {msg}"
);
}
#[test]
fn lone_high_surrogate_followed_by_non_escape_errors() {
let yaml = "bad: \"\\uD834z\"";
let err = from_str::<Value>(yaml).unwrap_err();
let msg = err.to_string();
assert!(
msg.contains("D834") || msg.contains("surrogate"),
"expected surrogate-rejection error, got: {msg}"
);
}
#[test]
fn high_followed_by_non_surrogate_escape_errors() {
let yaml = "bad: \"\\uD834\\u0041\"";
let err = from_str::<Value>(yaml).unwrap_err();
let msg = err.to_string();
assert!(
msg.contains("low surrogate") || msg.contains("surrogate"),
"expected low-surrogate-required error, got: {msg}"
);
}
#[test]
fn reversed_surrogate_pair_errors() {
let yaml = "bad: \"\\uDC00\\uD800\"";
let err = from_str::<Value>(yaml).unwrap_err();
let msg = err.to_string();
assert!(
msg.contains("DC00") || msg.contains("surrogate"),
"expected reversed-pair rejection, got: {msg}"
);
}
#[test]
fn lone_low_surrogate_errors() {
let yaml = "bad: \"\\uDC00\"";
let err = from_str::<Value>(yaml).unwrap_err();
let msg = err.to_string();
assert!(
msg.contains("DC00") || msg.contains("surrogate"),
"expected lone-low-surrogate rejection, got: {msg}"
);
}
#[test]
fn high_surrogate_with_truncated_low_surrogate_errors() {
let yaml = "bad: \"\\uD834\\uDD1\"";
let err = from_str::<Value>(yaml).unwrap_err();
let msg = err.to_string();
assert!(
msg.contains("low surrogate") || msg.contains("hex"),
"expected low-surrogate truncation error, got: {msg}"
);
}
#[test]
fn high_surrogate_with_non_hex_after_backslash_u_errors() {
let yaml = "bad: \"\\uD834\\uDDXY\"";
let err = from_str::<Value>(yaml).unwrap_err();
let msg = err.to_string();
assert!(
msg.contains("hex") || msg.contains("low surrogate"),
"expected hex-digit / low-surrogate error, got: {msg}"
);
}
#[test]
fn surrogate_high_at_eof_errors() {
let yaml = "x: \"\\uD834";
let err = from_str::<Value>(yaml).unwrap_err();
let msg = err.to_string();
assert!(
msg.contains("D834") || msg.contains("surrogate") || msg.contains("quote"),
"expected surrogate-or-string error, got: {msg}"
);
}
#[test]
fn surrogate_pair_round_trips() {
let yaml = "music: \"\\uD834\\uDD1E\"";
let v: Value = from_str(yaml).unwrap();
let serialized = noyalib::to_string(&v).unwrap();
let v2: Value = from_str(&serialized).unwrap();
assert_eq!(v, v2);
assert_eq!(v2["music"].as_str(), Some("𝄞"));
}