use noyalib::{Value, from_str, to_string};
fn first_key(v: &Value) -> String {
match v {
Value::Mapping(m) => m.keys().next().expect("one key").clone(),
other => panic!("expected a mapping, got {other:?}"),
}
}
#[test]
fn bare_specials_keep_their_spelling_as_keys() {
for key in [
"nAn", "nan", "NaN", "NAN", "iNf", "inf", "INF", "Infinity", "-inf", "+inf",
] {
let parsed: Value = from_str(&format!("{key}: null\n")).expect(key);
assert_eq!(first_key(&parsed), key, "key {key:?} lost its spelling");
}
}
#[test]
fn bare_specials_are_strings_as_values() {
for text in ["nan", "nAn", "inf", "iNf", "-inf", "infinity"] {
let parsed: Value = from_str(&format!("v: {text}\n")).expect(text);
let Value::Mapping(m) = &parsed else {
panic!("expected mapping")
};
assert_eq!(
m.get("v"),
Some(&Value::String(text.to_owned())),
"bare {text:?} should stay a string"
);
}
}
#[test]
fn dotted_specials_still_resolve_to_floats() {
for (text, check) in [
(".nan", "nan"),
(".NaN", "nan"),
(".inf", "inf"),
(".INF", "inf"),
("-.inf", "-inf"),
] {
let parsed: Value = from_str(&format!("v: {text}\n")).expect(text);
let Value::Mapping(m) = &parsed else {
panic!("expected mapping")
};
let Some(Value::Number(n)) = m.get("v") else {
panic!("{text} should resolve to a float, got {:?}", m.get("v"));
};
let f = n.as_f64();
match check {
"nan" => assert!(f.is_nan(), "{text} should be NaN"),
"inf" => assert!(
f.is_infinite() && f.is_sign_positive(),
"{text} should be +inf"
),
_ => assert!(
f.is_infinite() && f.is_sign_negative(),
"{text} should be -inf"
),
}
}
}
#[test]
fn ordinary_floats_are_unaffected() {
for text in ["1.5", "-2.25", "1e3", "0.0"] {
let parsed: Value = from_str(&format!("v: {text}\n")).expect(text);
let Value::Mapping(m) = &parsed else {
panic!("expected mapping")
};
assert!(
matches!(m.get("v"), Some(Value::Number(_))),
"{text} should still parse as a number"
);
}
}
#[test]
fn the_proptest_case_round_trips() {
let original: Value = from_str("nAn: null\n").expect("parse");
let yaml = to_string(&original).expect("serialise");
let reparsed: Value = from_str(&yaml).expect("reparse");
assert_eq!(original, reparsed, "round-trip changed the value");
}