#![allow(clippy::unwrap_used, clippy::expect_used)]
use std::process::Command;
use timeglyph::{format, PosixNs};
fn inst_2020() -> PosixNs {
format("unix").unwrap().decode_int(1_577_836_800).unwrap()
}
fn oracle_available() -> bool {
Command::new("time-decode")
.arg("--formats")
.output()
.is_ok_and(|o| o.status.success())
}
fn time_decode(flag: &str, repr: &str) -> String {
let out = Command::new("time-decode")
.arg(flag)
.arg(repr)
.output()
.expect("time-decode invocation failed");
String::from_utf8_lossy(&out.stdout).into_owned()
}
fn assert_decodes_to_2020(stdout: &str, flag: &str, repr: &str) {
assert!(
stdout.contains("2020-01-01 00:00:00"),
"oracle {flag} {repr} did not decode to 2020-01-01 00:00:00: {stdout}"
);
}
#[test]
fn logtime_live_roundtrips_through_time_decode() {
if !oracle_available() {
eprintln!("skipping: time-decode not on PATH");
return;
}
let n = format("logtime").unwrap().encode_int(inst_2020()).unwrap();
let repr = format!("{:016x}", n as u64);
assert_decodes_to_2020(&time_decode("--logtime", &repr), "--logtime", &repr);
}
#[test]
fn logtime_committed_matches_oracle_value() {
assert_eq!(
format("logtime").unwrap().encode_int(inst_2020()).unwrap(),
0x0000_0001_0178_0000
);
}
#[test]
fn logtime_rejects_out_of_range() {
let y1899 = format("unix").unwrap().decode_int(-2_240_524_800).unwrap(); assert!(format("logtime").unwrap().encode_int(y1899).is_err());
}
#[test]
fn semioctet_live_roundtrips_through_time_decode() {
if !oracle_available() {
eprintln!("skipping: time-decode not on PATH");
return;
}
let n = format("semioctet")
.unwrap()
.encode_int(inst_2020())
.unwrap();
let repr = format!("{n:012}");
assert_decodes_to_2020(&time_decode("--semioctet", &repr), "--semioctet", &repr);
}
#[test]
fn semioctet_committed_matches_oracle_value() {
assert_eq!(
format("semioctet")
.unwrap()
.encode_int(inst_2020())
.unwrap(),
21_010_000_000
);
}
#[test]
fn semioctet_rejects_out_of_range() {
let y1999 = format("unix").unwrap().decode_int(915_148_800).unwrap(); assert!(format("semioctet").unwrap().encode_int(y1999).is_err());
}
#[test]
fn gsm_live_roundtrips_through_time_decode() {
if !oracle_available() {
eprintln!("skipping: time-decode not on PATH");
return;
}
let n = format("gsm").unwrap().encode_int(inst_2020()).unwrap();
let repr = format!("{:014x}", n as u64);
assert_decodes_to_2020(&time_decode("--gsm", &repr), "--gsm", &repr);
}
#[test]
fn gsm_committed_matches_oracle_value() {
assert_eq!(
format("gsm").unwrap().encode_int(inst_2020()).unwrap(),
0x0002_1010_0000_0000
);
}
#[test]
fn gsm_rejects_out_of_range() {
let y1999 = format("unix").unwrap().decode_int(915_148_800).unwrap();
assert!(format("gsm").unwrap().encode_int(y1999).is_err());
}
#[test]
fn nokiale_live_roundtrips_through_time_decode() {
if !oracle_available() {
eprintln!("skipping: time-decode not on PATH");
return;
}
let n = format("nokiale").unwrap().encode_int(inst_2020()).unwrap();
let repr = format!("{:08x}", n as u32);
assert_decodes_to_2020(&time_decode("--nokiale", &repr), "--nokiale", &repr);
}
#[test]
fn nokiale_committed_matches_oracle_value() {
assert_eq!(
format("nokiale").unwrap().encode_int(inst_2020()).unwrap(),
0xff6a_91c7
);
}
#[test]
fn nokiale_rejects_out_of_range() {
let y2100 = format("unix").unwrap().decode_int(4_102_444_800).unwrap(); assert!(format("nokiale").unwrap().encode_int(y2100).is_err());
}
#[test]
fn sqlserver_committed_matches_spec_construction() {
assert_eq!(
format("sqlserver")
.unwrap()
.encode_int(inst_2020())
.unwrap(),
43_829_i64 << 32
);
}
#[test]
fn sqlserver_rejects_out_of_range() {
assert!(format("sqlserver")
.unwrap()
.encode_int(PosixNs(i128::MAX))
.is_err());
let over_i32_days = (i128::from(i32::MAX) + 1) * 86_400 * 1_000_000_000;
assert!(format("sqlserver")
.unwrap()
.encode_int(PosixNs(over_i32_days))
.is_err());
}