#![cfg(test)]
#![allow(clippy::unwrap_used, clippy::expect_used, reason = "unit tests")]
use super::{from_hns, sample_duration_hns, to_hns};
const TIMEBASES: &[(u64, u32)] = &[
(1, 60), (1, 30), (1, 24), (1001, 30000), (1001, 24000), (1, 1_000), (1, 48_000), (1, 90_000), (1, 10_000_000), ];
#[test]
fn the_hns_round_trip_is_an_exact_inverse() {
for &(num, den) in TIMEBASES {
for tick in 0..2_000i64 {
let back = from_hns(to_hns(tick, num, den), num, den);
assert_eq!(
back, tick,
"tick {tick} did not survive time_base {num}/{den}"
);
}
}
}
#[test]
fn it_is_an_exact_inverse_for_negative_timestamps_too() {
for &(num, den) in TIMEBASES {
for tick in -2_000..0i64 {
let back = from_hns(to_hns(tick, num, den), num, den);
assert_eq!(
back, tick,
"tick {tick} did not survive time_base {num}/{den}"
);
}
}
}
#[test]
fn distinct_ticks_never_share_a_timestamp() {
for &(num, den) in TIMEBASES {
let mut previous = from_hns(to_hns(0, num, den), num, den);
for tick in 1..2_000i64 {
let current = from_hns(to_hns(tick, num, den), num, den);
assert!(
current > previous,
"time_base {num}/{den}: tick {tick} came back as {current}, \
not greater than the previous {previous}"
);
previous = current;
}
}
}
#[test]
fn the_measured_regression_case_survives() {
assert_eq!(to_hns(7, 1, 60), 1_166_666);
assert_eq!(from_hns(1_166_666, 1, 60), 7);
assert_eq!(to_hns(8, 1, 60), 1_333_333);
assert_eq!(from_hns(1_333_333, 1, 60), 8);
}
#[test]
fn a_timestamp_the_mft_recomputed_lands_on_the_tick_it_meant() {
for tick in 1..1_000i64 {
let scaled = tick * 10_000_000;
let from_below = scaled / 60;
let from_above = (scaled + 59) / 60;
assert_eq!(from_hns(from_above, 1, 60), tick, "rounded up by the MFT");
assert_eq!(from_hns(from_below, 1, 60), tick, "rounded down by the MFT");
}
}
#[test]
fn a_timebase_finer_than_mf_can_represent_loses_precision_on_the_way_in() {
let (num, den) = (1, 20_000_000);
assert_eq!(to_hns(1, num, den), to_hns(0, num, den));
}
#[test]
fn a_zero_timebase_yields_zero_instead_of_dividing_by_it() {
assert_eq!(to_hns(42, 1, 0), 0);
assert_eq!(from_hns(42, 1, 0), 0);
assert_eq!(from_hns(42, 0, 60), 0);
}
#[test]
fn unknown_duration_is_one_tick_not_one_hns() {
for &(num, den) in TIMEBASES {
assert_eq!(
sample_duration_hns(0, num, den),
sample_duration_hns(1, num, den),
"duration 0 differs from one tick at {num}/{den}"
);
}
assert_eq!(sample_duration_hns(0, 1, 30), 333_333);
}
#[test]
fn declared_duration_is_kept() {
assert_eq!(sample_duration_hns(3, 1, 30), 1_000_000);
assert_eq!(sample_duration_hns(2, 1001, 30000), to_hns(2, 1001, 30000));
}
#[test]
fn an_oversized_duration_is_treated_as_unknown() {
assert_eq!(
sample_duration_hns(u64::MAX, 1, 30),
sample_duration_hns(1, 1, 30)
);
}
#[test]
fn a_sub_hns_tick_is_floored_at_one() {
assert_eq!(sample_duration_hns(0, 1, 100_000_000), 1);
}