#![allow(clippy::all, clippy::pedantic, clippy::restriction, warnings)]
use deep_time::{Dt, constants::ATTOS_PER_SEC_I128};
const APS: i128 = ATTOS_PER_SEC_I128;
#[test]
fn test_from_sec_f() {
let test_cases: &[(f64, &str)] = &[
(0.0, "zero"),
(1.0, "positive integer"),
(-1.0, "negative integer"),
(0.5, "simple fraction"),
(1.0 + 1e-10, "just above integer"),
(1.0 - 1e-10, "just below integer"),
(1.0 + 1e-16, "very tiny positive frac"),
(1.0 - 1e-16, "very tiny negative frac"),
(1e-17, "extremely small positive"),
(-1e-17, "extremely small negative"),
(
(0.81f64 * 0.81 - 0.81 + 1.0).sqrt() - 1.0,
"saturation test δ=0.81 (the one that differed by 111 attos)",
),
(1.0 + 0.9999999999999999, "almost 2.0"),
(-0.0000000000000001, "tiny negative near zero"),
(123.45678901234567, "random-looking decimal"),
(1e10 + 0.123, "large integer + fraction"),
];
for (sec_f, label) in test_cases {
let dt = Dt::span_f(*sec_f);
let roundtrip = dt.to_sec_f();
assert_eq!(
roundtrip, *sec_f,
"Roundtrip failed for input {} ({})\n → Dt: {:?}\n → back: {}",
sec_f, label, dt, roundtrip
);
}
}
#[test]
fn test_mul_by_f() {
let three_sec = Dt::span(3 * APS);
let neg_three_sec = Dt::span(-(3 * APS));
let two_sec = Dt::span(2 * APS);
assert_eq!(three_sec.mul_by_f(2.0).to_attos(), 6 * APS);
assert_eq!(three_sec.mul_by_f(0.5).to_attos(), (3 * APS) / 2);
assert_eq!(three_sec.mul_by_f(-2.5).to_attos(), -(7 * APS + APS / 2));
assert_eq!(neg_three_sec.mul_by_f(2.0).to_attos(), -(6 * APS));
assert_eq!(neg_three_sec.mul_by_f(-2.5).to_attos(), 7 * APS + APS / 2);
assert_eq!(two_sec.mul_by_f(-1.0).to_attos(), -(2 * APS));
assert_eq!(three_sec.mul_by_f(f64::NAN), Dt::ZERO);
assert_eq!(Dt::ZERO.mul_by_f(f64::INFINITY), Dt::ZERO);
assert_eq!(three_sec.mul_by_f(0.0), Dt::ZERO);
assert_eq!(three_sec.mul_by_f(f64::INFINITY), Dt::MAX);
assert_eq!(three_sec.mul_by_f(f64::NEG_INFINITY), Dt::MIN);
assert_eq!(Dt::MAX.mul_by_f(1.0), Dt::MAX);
assert_eq!(Dt::MAX.mul_by_f(2.0), Dt::MAX);
assert_eq!(Dt::MIN.mul_by_f(2.0), Dt::MIN);
assert_eq!(Dt::span(10 * APS).div_by_f(4.0).to_attos(), (10 * APS) / 4);
}
#[test]
fn test_from_str_sec_f() {
use deep_time::Scale;
let d = Dt::from_str_sec_f("123", Some(Scale::TAI)).unwrap();
assert_eq!(d.to_sec64(), 123);
assert_eq!(d.to_sec_ufrac(), 0);
let d = Dt::from_str_sec_f("123.5", Some(Scale::TAI)).unwrap();
assert_eq!(d.to_sec64(), 123);
assert_eq!(d.to_sec_ufrac(), 500_000_000_000_000_000);
let d = Dt::from_str_sec_f("-42", Some(Scale::TAI)).unwrap();
assert_eq!(d.to_sec64(), -42);
let d = Dt::from_str_sec_f("-1.25", Some(Scale::TAI)).unwrap();
assert_eq!(d.to_sec64(), -2); assert_eq!(d.to_sec_ufrac(), 750_000_000_000_000_000);
let d = Dt::from_str_sec_f(".5", Some(Scale::TAI)).unwrap();
assert_eq!(d.to_sec64(), 0);
assert_eq!(d.to_sec_ufrac(), 500_000_000_000_000_000);
let d = Dt::from_str_sec_f("-.5", Some(Scale::TAI)).unwrap();
assert!(d.to_attos() < 0);
assert_eq!(d.to_sec64(), -1);
assert_eq!(d.to_sec_ufrac(), 500_000_000_000_000_000);
let d = Dt::from_str_sec_f("+0.25", Some(Scale::TAI)).unwrap();
assert_eq!(d.to_sec_ufrac(), 250_000_000_000_000_000);
let d = Dt::from_str_sec_f("99.", Some(Scale::TAI)).unwrap();
assert_eq!(d.to_sec64(), 99);
assert_eq!(d.to_sec_ufrac(), 0);
let d = Dt::from_str_sec_f("0.123456789012345678", Some(Scale::TAI)).unwrap();
assert_eq!(d.to_sec_ufrac(), 123_456_789_012_345_678);
let d = Dt::from_str_sec_f("0.1234567890123456789", Some(Scale::TAI)).unwrap();
assert_eq!(d.to_sec_ufrac(), 123_456_789_012_345_678);
let d = Dt::from_str_sec_f("0.000000000000000001", Some(Scale::TAI)).unwrap();
assert_eq!(d.to_sec_ufrac(), 1);
let d = Dt::from_str_sec_f("+.000000000000000001", Some(Scale::TAI)).unwrap();
assert_eq!(d.to_sec_ufrac(), 1);
assert!(Dt::from_str_sec_f("", Some(Scale::TAI)).is_none());
assert!(Dt::from_str_sec_f("-", Some(Scale::TAI)).is_none());
assert!(Dt::from_str_sec_f(".", Some(Scale::TAI)).is_none());
assert!(Dt::from_str_sec_f("abc", Some(Scale::TAI)).is_none());
assert!(Dt::from_str_sec_f("+", Some(Scale::TAI)).is_none());
assert!(Dt::from_str_sec_f("---", Some(Scale::TAI)).is_none());
let d = Dt::from_str_sec_f("123x", Some(Scale::TAI)).unwrap();
assert_eq!(d.to_sec64(), 123);
let d = Dt::from_str_sec_f("prefix:123.45.67", Some(Scale::TAI)).unwrap();
assert_eq!(d.to_sec64(), 123);
assert_eq!(d.to_sec_ufrac(), 450_000_000_000_000_000);
let d = Dt::from_str_sec_f("time = -42.75 (end)", Some(Scale::TAI)).unwrap();
assert_eq!(d.to_sec64(), -43);
assert_eq!(d.to_sec_ufrac(), 250_000_000_000_000_000);
let big = "9223372036854775807"; let d = Dt::from_str_sec_f(big, Some(Scale::TAI)).unwrap();
assert_eq!(d.to_sec64(), i64::MAX);
let min = "-9223372036854775808";
let d = Dt::from_str_sec_f(min, Some(Scale::TAI)).unwrap();
assert_eq!(d.to_sec64(), i64::MIN);
let huge_pos = "1234567890123456789012345678901234567890.123";
let d = Dt::from_str_sec_f(huge_pos, Some(Scale::TAI)).unwrap();
assert_eq!(d.to_sec64(), i64::MAX);
assert!(d.to_sec_ufrac() > 0);
let huge_neg = "-99999999999999999999999999999999999999.9";
let d = Dt::from_str_sec_f(huge_neg, Some(Scale::TAI)).unwrap();
assert_eq!(d.to_sec64(), i64::MIN);
let too_long = "1".repeat(600);
assert!(Dt::from_str_sec_f(&too_long, Some(Scale::TAI)).is_none());
let d = Dt::from_str_sec_f("123.5 GPS", None).unwrap();
assert_eq!(d.target, Scale::GPS);
let d_auto = Dt::from_str_sec_f("9876.25 GPS", None).unwrap();
let d_exp = Dt::from_str_sec_f("9876.25", Some(Scale::GPS)).unwrap();
assert_eq!(d_auto, d_exp);
let d = Dt::from_str_sec_f("val= 10 TAI", None).unwrap();
assert_eq!(d.target, Scale::TAI);
let d = Dt::from_str_sec_f("55.5", None).unwrap();
assert_eq!(d.target, Scale::TAI);
}