use std::time::Duration;
pub use telltale_types::effects::{Clock, MockClock, Rng, SeededRng, WallClock};
pub trait AsyncClock: Clock {
fn sleep(&self, duration: Duration) -> impl std::future::Future<Output = ()> + Send;
}
impl AsyncClock for MockClock {
async fn sleep(&self, duration: Duration) {
self.advance(duration);
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_seeded_rng_reproducible() {
let mut rng1 = SeededRng::new(12345);
let mut rng2 = SeededRng::new(12345);
for _ in 0..100 {
assert_eq!(rng1.next_u64(), rng2.next_u64());
}
}
#[test]
fn test_seeded_rng_different_seeds() {
let mut rng1 = SeededRng::new(12345);
let mut rng2 = SeededRng::new(54321);
assert_ne!(rng1.next_u64(), rng2.next_u64());
}
#[test]
fn test_mock_clock_advance() {
let clock = MockClock::new();
let start = clock.now();
clock.advance(Duration::from_secs(1));
assert!(clock.elapsed(start) >= Duration::from_secs(1));
clock.advance(Duration::from_millis(500));
assert!(clock.elapsed(start) >= Duration::from_millis(1500));
}
#[test]
fn test_mock_wall_clock() {
let clock = MockClock::new();
assert_eq!(clock.now_unix_ns(), 0);
clock.advance(Duration::from_millis(2));
assert_eq!(clock.now_unix_ns(), 2_000_000);
}
#[test]
fn test_rng_choose() {
let mut rng = SeededRng::new(42);
let items = vec![1, 2, 3, 4, 5];
let chosen = rng.choose(&items);
assert!(chosen.is_some());
assert!(items.contains(chosen.expect("must choose an element")));
}
#[test]
fn test_rng_duration_between() {
let mut rng = SeededRng::new(42);
let min = Duration::from_millis(100);
let max = Duration::from_millis(200);
for _ in 0..100 {
let d = rng.duration_between(min, max);
assert!(d >= min);
assert!(d < max);
}
}
}