#![allow(missing_docs)]
#![allow(clippy::unwrap_used)]
use noyalib::{Number, Value, from_value};
#[cfg(feature = "lossless-u64")]
#[test]
fn unsigned_within_i64_range_deserializes_to_i64() {
let v = Value::Number(Number::Unsigned(42));
let got: i64 = from_value(&v).unwrap();
assert_eq!(got, 42);
}
#[cfg(feature = "lossless-u64")]
#[test]
fn unsigned_above_i64_max_rejected_for_i64() {
let v = Value::Number(Number::Unsigned(u64::MAX));
let err = from_value::<i64>(&v).unwrap_err();
assert!(
matches!(err, noyalib::Error::TypeMismatch { .. }),
"expected TypeMismatch, got: {err:?}"
);
assert_eq!(
err.to_string(),
format!(
"type mismatch: expected signed integer (i64), \
found unsigned integer {}, above i64::MAX",
u64::MAX
)
);
}
#[test]
fn negative_integer_rejected_for_u64_names_the_sign() {
let v = Value::Number(Number::Integer(-1));
let err = from_value::<u64>(&v).unwrap_err();
assert_eq!(
err.to_string(),
"type mismatch: expected unsigned integer, found negative integer -1"
);
}
#[cfg(feature = "lossless-u64")]
#[test]
fn unsigned_at_i64_max_boundary_converts() {
let v = Value::Number(Number::Unsigned(i64::MAX as u64));
let got: i64 = from_value(&v).unwrap();
assert_eq!(got, i64::MAX);
}
#[cfg(feature = "lossless-u64")]
#[test]
fn unsigned_widens_to_f64() {
let v = Value::Number(Number::Unsigned(u64::MAX));
let got: f64 = from_value(&v).unwrap();
assert_eq!(got, u64::MAX as f64);
}
#[cfg(feature = "lossless-u64")]
#[test]
fn unsigned_round_trips_through_deserialize_any() {
let v = Value::Number(Number::Unsigned(u64::MAX));
let got: Value = from_value(&v).unwrap();
assert_eq!(got, v);
}
#[cfg(feature = "lossless-u64")]
#[test]
fn unsigned_through_newtype_struct() {
#[derive(Debug, serde::Deserialize, PartialEq)]
struct Wrapper(u64);
let v = Value::Number(Number::Unsigned(u64::MAX));
let got: Wrapper = from_value(&v).unwrap();
assert_eq!(got, Wrapper(u64::MAX));
}
#[test]
fn format_preserves_flow_mapping_verbatim() {
let src = "a: {x: 1, y: 2}\n";
assert_eq!(noyalib::cst::format(src).unwrap(), src);
}
#[test]
fn format_preserves_flow_sequence_verbatim() {
let src = "a: [1, 2, 3]\n";
assert_eq!(noyalib::cst::format(src).unwrap(), src);
}
#[test]
fn format_does_not_normalise_inside_a_flow_collection() {
let src = "a: {x: 1}\n";
assert_eq!(
noyalib::cst::format(src).unwrap(),
src,
"flow interior must not be re-spaced"
);
}
#[test]
fn format_sequence_items_with_nested_nodes_and_tokens() {
let src = "list:\n - plain\n - nested:\n inner: 1\n - [1, 2]\n";
let out = noyalib::cst::format(src).unwrap();
assert_eq!(out, src);
}
#[test]
fn format_is_idempotent_across_flow_and_block() {
let src = "a: {x: 1}\nb:\n - 1\n - [2, 3]\nc: plain\n";
let once = noyalib::cst::format(src).unwrap();
let twice = noyalib::cst::format(&once).unwrap();
assert_eq!(once, twice, "format should be idempotent");
}