Skip to main content

klauthed_testing/
clock.rs

1//! Clock helpers for tests.
2//!
3//! These are thin conveniences around [`klauthed_core::time::FixedClock`], the
4//! controllable test clock. Construct one pinned to a known instant, then pin or
5//! [`advance`](klauthed_core::time::FixedClock::advance) it explicitly so
6//! time-dependent logic is fully deterministic.
7//!
8//! [`Clock`] and [`Timestamp`] are re-exported here so tests can pull everything
9//! time-related from one place.
10
11pub use klauthed_core::time::{Clock, Duration, FixedClock, Timestamp};
12
13/// A [`FixedClock`] pinned to `unix_millis` milliseconds since the Unix epoch.
14///
15/// A terse alias for [`FixedClock::at_unix_millis`] so tests read clearly:
16///
17/// ```
18/// use klauthed_testing::clock::{fixed_clock, Clock, Duration};
19///
20/// let clock = fixed_clock(1_700_000_000_000);
21/// let t0 = clock.now();
22/// clock.advance(Duration::seconds(5));
23/// assert_eq!(clock.now().duration_since(t0).whole_seconds(), 5);
24/// ```
25pub fn fixed_clock(unix_millis: i64) -> FixedClock {
26    FixedClock::at_unix_millis(unix_millis)
27}
28
29/// A [`FixedClock`] pinned to the Unix epoch (`0` ms).
30///
31/// Handy when the absolute instant is irrelevant and you only care about
32/// relative progress via [`advance`](FixedClock::advance).
33pub fn epoch_clock() -> FixedClock {
34    fixed_clock(0)
35}
36
37#[cfg(test)]
38mod tests {
39    use super::*;
40
41    #[test]
42    fn fixed_clock_pins_and_advances() {
43        let clock = fixed_clock(1_000);
44        let t0 = clock.now();
45        assert_eq!(t0.unix_millis(), 1_000);
46        assert_eq!(clock.now(), t0); // does not move on its own
47
48        clock.advance(Duration::seconds(2));
49        assert_eq!(clock.now().duration_since(t0).whole_seconds(), 2);
50    }
51
52    #[test]
53    fn epoch_clock_starts_at_zero() {
54        let clock = epoch_clock();
55        assert_eq!(clock.now().unix_millis(), 0);
56    }
57
58    #[test]
59    fn usable_behind_dyn_clock() {
60        let clock: std::sync::Arc<dyn Clock> = std::sync::Arc::new(fixed_clock(42));
61        assert_eq!(clock.now().unix_millis(), 42);
62    }
63}