#![allow(dead_code)]
use std::time::Instant;
pub trait Clock {
fn now(&self) -> Instant;
}
#[derive(Clone, Copy)]
pub struct RealClock;
impl Clock for RealClock {
fn now(&self) -> Instant {
Instant::now()
}
}
#[derive(Clone)]
pub struct FakeClock {
current: Instant,
}
impl FakeClock {
#[must_use]
pub fn new(anchor: Instant) -> Self {
Self { current: anchor }
}
pub fn advance(&mut self, delta: std::time::Duration) {
self.current += delta;
}
pub fn set(&mut self, instant: Instant) {
self.current = instant;
}
}
impl Clock for FakeClock {
fn now(&self) -> Instant {
self.current
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::time::Duration;
#[test]
fn real_clock_returns_instant() {
let clock = RealClock;
let before = Instant::now();
let t = clock.now();
let after = Instant::now();
assert!(t >= before);
assert!(t <= after);
}
#[test]
fn fake_clock_starts_at_anchor() {
let anchor = Instant::now();
let clock = FakeClock::new(anchor);
assert_eq!(clock.now(), anchor);
}
#[test]
fn fake_clock_advances() {
let anchor = Instant::now();
let mut clock = FakeClock::new(anchor);
clock.advance(Duration::from_secs(5));
assert_eq!(clock.now(), anchor + Duration::from_secs(5));
}
#[test]
fn fake_clock_set() {
let anchor = Instant::now();
let mut clock = FakeClock::new(anchor);
let target = anchor + Duration::from_secs(100);
clock.set(target);
assert_eq!(clock.now(), target);
}
}