// Update snapshot tests by running:
//
// `cargo insta test --all-features --accept`
#![expect(
clippy::approx_constant,
clippy::excessive_precision,
clippy::lossy_float_literal
)]
use std::str::FromStr as _;
use eon::Value;
#[track_caller]
fn test_roundtrip_value(value: impl Into<Value>) {
let value = value.into();
let formatted = value.format(&Default::default());
let parsed = Value::from_str(&formatted).expect("Failed to parse formatted value");
assert!(
value == parsed,
"Roundtrip failed for {value:?}, formatted as {formatted}, parsed as {parsed:?}"
);
}
#[track_caller]
fn test_roundtrip_eon(eon: &str) {
let value = Value::from_str(eon).expect("Failed to parse Eon value");
let serialized = value.format(&Default::default());
assert_eq!(eon, serialized, "Roundtrip failed. Value {value:?}");
}
#[track_caller]
fn test_serialize(value: impl Into<Value>, expected: &str) {
let value = value.into();
let formatted = value.format(&Default::default());
assert_eq!(formatted, expected, "Serialization failed for: {value}");
}
#[track_caller]
fn test_f64(eon: &str, expected: f64) {
let output = Value::from_str(eon)
.expect("Failed to parse number")
.as_number()
.expect("Expected a number")
.as_f64()
.expect("Expected an f64");
assert_eq!(output, expected, "Failed to parse f64: {eon} != {expected}");
}
#[track_caller]
fn test_i128(eon: &str, expected: i128) {
let value = Value::from_str(eon).expect("Failed to parse number");
let number = value
.as_number()
.expect("Expected a number")
.as_i128()
.expect("Expected an i128");
assert_eq!(
number, expected,
"Expected {eon} to parse as {expected}, but got {value:?}"
);
}
#[test]
fn test_numbers() {
test_roundtrip_value(0.1);
test_roundtrip_value(3.14);
test_roundtrip_value(3.14000010490417);
test_roundtrip_value(1234567890123456_i128);
test_serialize(3.14, "3.14");
test_serialize(3.14_f32, "3.14");
}
#[test]
fn test_roundtrip_string() {
test_roundtrip_eon("42");
test_roundtrip_eon("-42");
test_roundtrip_eon("9223372036854775807");
test_roundtrip_eon("-9223372036854775808");
test_roundtrip_eon("0.0");
test_roundtrip_eon("-0.0");
test_roundtrip_eon("1.0");
test_roundtrip_eon("-1.0");
test_roundtrip_eon("5e-324");
test_roundtrip_eon("2.225073858507201e-308");
test_roundtrip_eon("2.2250738585072014e-308");
test_roundtrip_eon("1.7976931348623157e308");
test_roundtrip_eon("3.14");
}
#[test]
fn test_f64s() {
// Tests from https://github.com/miloyip/nativejson-benchmark
test_f64("0.0", 0.0);
test_f64("-0.0", -0.0);
test_f64("1.0", 1.0);
test_f64("-1.0", -1.0);
test_f64("1.5", 1.5);
test_f64("-1.5", -1.5);
test_f64("3.1416", 3.1416);
test_f64("1E10", 1E10);
test_f64("1e10", 1e10);
test_f64("1E+10", 1E+10);
test_f64("1E-10", 1E-10);
test_f64("-1E10", -1E10);
test_f64("-1e10", -1e10);
test_f64("-1E+10", -1E+10);
test_f64("-1E-10", -1E-10);
test_f64("1.234E+10", 1.234E+10);
test_f64("1.234E-10", 1.234E-10);
test_f64("1.79769e+308", 1.79769e+308);
test_f64("2.22507e-308", 2.22507e-308);
test_f64("-1.79769e+308", -1.79769e+308);
test_f64("-2.22507e-308", -2.22507e-308);
test_f64("4.9406564584124654e-324", 4.9406564584124654e-324); // minimum denormal
test_f64("2.2250738585072009e-308", 2.2250738585072009e-308); // Max subnormal f64
test_f64("2.2250738585072014e-308", 2.2250738585072014e-308); // Min normal positive f64
test_f64("1.7976931348623157e+308", 1.7976931348623157e+308); // Max f64
test_f64("1e-10000", 0.0); // must underflow
test_f64("18446744073709551616", 18446744073709551616.0); // 2^64 (max of uint64_t + 1, force to use f64)
test_i128("-9223372036854775809", -9223372036854775809); // -2^63 - 1(min of int64_t + 1, force to use f64)
test_f64("0.9868011474609375", 0.9868011474609375);
test_f64("123e34", 123e34); // Fast Path Cases In Disguise
test_f64("45913141877270640000.0", 45913141877270640000.0);
test_f64("2.2250738585072011e-308", 2.2250738585072011e-308);
test_f64("1e-00011111111111", 0.0);
test_f64("-1e-00011111111111", -0.0);
test_f64("1e-214748363", 0.0);
test_f64("1e-214748364", 0.0);
test_f64("1e-21474836311", 0.0);
test_f64("0.017976931348623157e+310", 1.7976931348623157e+308); // Max f64 in another form
// Since
// abs((2^-1022 - 2^-1074) - 2.2250738585072012e-308) = 3.109754131239141401123495768877590405345064751974375599... ¡Á 10^-324
// abs((2^-1022) - 2.2250738585072012e-308) = 1.830902327173324040642192159804623318305533274168872044... ¡Á 10 ^ -324
// So 2.2250738585072012e-308 should round to 2^-1022 = 2.2250738585072014e-308
test_f64("2.2250738585072012e-308", 2.2250738585072014e-308);
// More closer to normal/subnormal boundary
// boundary = 2^-1022 - 2^-1075 = 2.225073858507201136057409796709131975934819546351645648... ¡Á 10^-308
test_f64(
"2.22507385850720113605740979670913197593481954635164564e-308",
2.2250738585072009e-308,
);
test_f64(
"2.22507385850720113605740979670913197593481954635164565e-308",
2.2250738585072014e-308,
);
// 1.0 is in (1.0 - 2^-54, 1.0 + 2^-53)
// 1.0 - 2^-54 = 0.999999999999999944488848768742172978818416595458984375
test_f64(
"0.999999999999999944488848768742172978818416595458984375",
1.0,
); // round to even
test_f64(
"0.999999999999999944488848768742172978818416595458984374",
0.99999999999999989,
); // previous f64
test_f64(
"0.999999999999999944488848768742172978818416595458984376",
1.0,
); // next f64
// 1.0 + 2^-53 = 1.00000000000000011102230246251565404236316680908203125
test_f64(
"1.00000000000000011102230246251565404236316680908203125",
1.0,
); // round to even
test_f64(
"1.00000000000000011102230246251565404236316680908203124",
1.0,
); // previous f64
test_f64(
"1.00000000000000011102230246251565404236316680908203126",
1.00000000000000022,
); // next f64
// Numbers from https://github.com/floitsch/double-conversion/blob/master/test/cctest/test-strtod.cc
test_f64("72057594037927928.0", 72057594037927928.0);
test_f64("72057594037927936.0", 72057594037927936.0);
test_f64("72057594037927932.0", 72057594037927936.0);
test_f64("7205759403792793199999e-5", 72057594037927928.0);
test_f64("7205759403792793200001e-5", 72057594037927936.0);
test_f64("9223372036854774784.0", 9223372036854774784.0);
test_f64("9223372036854775808.0", 9223372036854775808.0);
test_f64("9223372036854775296.0", 9223372036854775808.0);
test_f64("922337203685477529599999e-5", 9223372036854774784.0);
test_f64("922337203685477529600001e-5", 9223372036854775808.0);
test_i128(
"10141204801825834086073718800384",
10141204801825834086073718800384,
);
test_i128(
"10141204801825835211973625643008",
10141204801825835211973625643008,
);
test_i128(
"10141204801825834649023672221696",
10141204801825834649023672221696,
);
test_f64(
"1014120480182583464902367222169599999e-5",
10141204801825834086073718800384.0,
);
test_f64(
"1014120480182583464902367222169600001e-5",
10141204801825835211973625643008.0,
);
test_f64(
"5708990770823838890407843763683279797179383808",
5708990770823838890407843763683279797179383808.0,
);
test_f64(
"5708990770823839524233143877797980545530986496",
5708990770823839524233143877797980545530986496.0,
);
test_f64(
"5708990770823839207320493820740630171355185152",
5708990770823839524233143877797980545530986496.0,
);
test_f64(
"5708990770823839207320493820740630171355185151999e-3",
5708990770823838890407843763683279797179383808.0,
);
test_f64(
"5708990770823839207320493820740630171355185152001e-3",
5708990770823839524233143877797980545530986496.0,
);
test_f64(&format!("1{}", "0".repeat(308)), 1E308);
// Cover trimming
test_f64(
"2.225073858507201136057409796709131975934819546351645648023426109724822222021076945516529523908135087914149158913039621106870086438694594645527657207407820621743379988141063267329253552286881372149012981122451451889849057222307285255133155755015914397476397983411801999323962548289017107081850690630666655994938275772572015763062690663332647565300009245888316433037779791869612049497390377829704905051080609940730262937128958950003583799967207254304360284078895771796150945516748243471030702609144621572289880258182545180325707018860872113128079512233426288368622321503775666622503982534335974568884423900265498198385487948292206894721689831099698365846814022854243330660339850886445804001034933970427567186443383770486037861622771738545623065874679014086723327636718751234567890123456789012345678901e-308",
2.2250738585072014e-308,
);
}