#![allow(clippy::unwrap_used, clippy::expect_used)]
use timeglyph::interpret;
fn component(cands: &[interpret::Candidate], id: &str, name: &str) -> f64 {
let c = cands
.iter()
.find(|c| c.format_id == id)
.unwrap_or_else(|| panic!("no candidate {id}"));
c.components
.iter()
.find(|(n, _)| *n == name)
.unwrap_or_else(|| panic!("no component {name} on {id}"))
.1
}
#[test]
fn every_candidate_emits_named_components() {
let cands = interpret::interpret_int(1_577_836_800);
let unix = cands.iter().find(|c| c.format_id == "unix").unwrap();
for required in ["representable", "in_window", "granularity_match"] {
assert!(
unix.components.iter().any(|(n, _)| *n == required),
"missing component {required}"
);
}
}
#[test]
fn whole_second_value_is_a_poor_fit_for_a_sub_second_unit() {
let round_ms = interpret::interpret_int(1_577_836_800_000);
let g_round = component(&round_ms, "unix_ms", "granularity_match");
assert!(
g_round < 0.5,
"whole-second ms granularity = {g_round}, want < 0.5"
);
let real_ms = interpret::interpret_int(1_577_836_801_501);
let g_real = component(&real_ms, "unix_ms", "granularity_match");
assert!(
(g_real - 1.0).abs() < 1e-9,
"sub-second ms granularity = {g_real}, want 1.0"
);
}
#[test]
fn granularity_lifts_the_better_fitting_reading() {
let real = interpret::interpret_int(1_577_836_801_501);
let round = interpret::interpret_int(1_577_836_800_000);
let s_real = real
.iter()
.find(|c| c.format_id == "unix_ms")
.unwrap()
.score;
let s_round = round
.iter()
.find(|c| c.format_id == "unix_ms")
.unwrap()
.score;
assert!(
s_real > s_round,
"real-resolution {s_real} should beat round {s_round}"
);
}
#[test]
fn id_schemes_do_not_outrank_a_plain_unix_seconds_value() {
let cands = interpret::interpret_int(1_577_836_800);
let unix = cands.iter().find(|c| c.format_id == "unix").unwrap().score;
for id in ["snowflake", "discord"] {
if let Some(c) = cands.iter().find(|c| c.format_id == id) {
assert!(
unix > c.score,
"{id} ({}) must not outrank unix ({unix})",
c.score
);
}
}
}
#[test]
fn real_discord_id_surfaces_a_confident_discord_reading() {
let cands = interpret::interpret_int(175_928_847_299_117_063);
let d = cands
.iter()
.find(|c| c.format_id == "discord")
.expect("discord candidate");
assert!(d.rendered.as_deref().unwrap().starts_with("2016-04-30"));
assert!((component(&cands, "discord", "in_window") - 1.0).abs() < 1e-9);
assert!(
component(&cands, "discord", "magnitude_fit") > 0.5,
"a real id sits well past the epoch → high magnitude_fit"
);
}
#[test]
fn every_candidate_emits_the_epoch_distance_component() {
let cands = interpret::interpret_int(1_577_836_800);
let unix = cands.iter().find(|c| c.format_id == "unix").unwrap();
assert!(
unix.components.iter().any(|(n, _)| *n == "epoch_distance"),
"epoch_distance must be a visible, named component on every candidate"
);
}
#[test]
fn epoch_hugging_reading_scores_low_epoch_distance() {
let cands = interpret::interpret_int(1_487_100_001_000);
assert!(
component(&cands, "iostime", "epoch_distance") < 0.05,
"an epoch-hugging iostime reading must score ~0 epoch_distance"
);
assert!(
component(&cands, "unix_ms", "epoch_distance") > 0.95,
"a value decades past the unix epoch must score ~1 epoch_distance"
);
}
#[test]
fn epoch_distance_lifts_the_true_format_above_an_epoch_hugger() {
let cands = interpret::interpret_int(1_487_100_001_000);
assert_eq!(
cands[0].format_id, "unix_ms",
"unix_ms must rank #1 for a real 2017 Unix-ms value, not the epoch-hugging iostime"
);
}
#[test]
fn webkit_outranks_epoch_hugging_iostime() {
let cands = interpret::interpret_int(13_224_789_208_197_989);
assert_eq!(
cands[0].format_id, "webkit",
"webkit must rank #1 for a real 2020 Chrome µs value, not iostime"
);
}
#[test]
fn genuine_early_epoch_reading_still_appears() {
let cands = interpret::interpret_int(3_600); let cocoa = cands.iter().find(|c| c.format_id == "cocoa");
assert!(
cocoa.is_some(),
"a genuine early-epoch cocoa reading must still appear (ranked, not hidden)"
);
assert!(
component(&cands, "cocoa", "epoch_distance") < 0.05,
"an hour past the epoch scores low epoch_distance — but is still surfaced"
);
}
fn pos_int(value: i64, id: &str) -> usize {
interpret::interpret_int(value)
.iter()
.position(|c| c.format_id == id)
.unwrap_or_else(|| panic!("no candidate {id} for {value}"))
}
#[test]
fn every_candidate_emits_the_prevalence_component() {
let cands = interpret::interpret_int(1_577_836_800);
assert!(
cands[0].components.iter().any(|(n, _)| *n == "prevalence"),
"prevalence component must be emitted"
);
}
#[test]
fn prevalence_ranks_ubiquitous_filetime_above_niche_active() {
assert!(
pos_int(132_963_748_799_479_404, "filetime") < pos_int(132_963_748_799_479_404, "active"),
"filetime must outrank the niche `active` on a tie"
);
}
#[test]
fn prevalence_ranks_ubiquitous_ole_above_niche_excel1904() {
let cands = interpret::interpret_float(42_073.333_333_333_336);
let ole = cands.iter().position(|c| c.format_id == "ole").unwrap();
let excel = cands
.iter()
.position(|c| c.format_id == "excel1904")
.unwrap();
assert!(
ole < excel,
"ole {ole} must outrank excel1904 {excel} on a tie"
);
}
#[test]
fn new_niche_formats_dhcp6_and_hfs_are_rare_tail() {
assert!(
(component(
&interpret::interpret_int(700_000_000),
"dhcp6",
"prevalence"
) - 0.5)
.abs()
< 1e-9
);
assert!(
(component(
&interpret::interpret_int(3_574_260_000),
"hfs",
"prevalence"
) - 0.5)
.abs()
< 1e-9
);
assert!(
(component(&interpret::interpret_int(700_000_000), "unix", "prevalence") - 1.0).abs()
< 1e-9
);
}
#[cfg(feature = "artifact-hints")]
#[test]
fn forensicnomicon_artifact_hint_pins_the_authoritative_format() {
let ctx = interpret::InterpretContext {
artifact: Some("imessage"),
..Default::default()
};
let cands = interpret::interpret_int_with_context(133_908_455_300_649_390, &ctx);
assert!(
(component(&cands, "iostime", "artifact_match") - 1.0).abs() < 1e-9,
"iostime must be the authoritative match for 'imessage'"
);
assert!(
component(&cands, "filetime", "artifact_match") < 1.0,
"a format the artifact does not store scores below the authoritative one"
);
}