use super::{HashedWheelTimer, TimeWheelError};
#[test]
fn schedule_returns_incremental_ids() {
let mut wheel = HashedWheelTimer::new(4);
let first = wheel.schedule(0, 42);
let second = wheel.schedule(10, 42);
assert_eq!(first.id, 1);
assert_eq!(second.id, 2);
assert_eq!(wheel.count_all(), 2);
assert_eq!(wheel.count_in_bucket(0).unwrap(), 1);
assert_eq!(wheel.count_in_bucket(1).unwrap(), 0);
}
#[test]
fn pop_events_works_by_delta_waves_on_same_tick() {
let mut wheel = HashedWheelTimer::new(4);
let _ = wheel.schedule(0, 1);
let _ = wheel.schedule(0, 1);
let first_wave = wheel.pop_events();
let _ = wheel.schedule(0, 3);
let second_wave = wheel.pop_events();
assert_eq!(first_wave.len(), 2);
assert_eq!(first_wave[0].id(), 1);
assert_eq!(first_wave[1].id(), 2);
assert_eq!(second_wave.len(), 1);
assert_eq!(second_wave[0].id(), 3);
}
#[test]
fn remove_update_and_reschedule_by_id() {
let mut wheel = HashedWheelTimer::new(8);
let created = wheel.schedule(5, 10);
let id = created.id;
let updated = wheel.update(id, 0, 20).expect("event should exist");
assert_eq!(updated.id, id);
assert_eq!(wheel.get(id).map(|e| e.data()), Some(&20));
assert_eq!(wheel.get(id).map(|e| e.tick()), Some(0));
let moved = wheel.reschedule(id, 7).expect("event should exist");
assert_eq!(moved.id, id);
assert_eq!(wheel.get(id).map(|e| e.tick()), Some(7));
let removed = wheel.remove(id).expect("event should be removed");
assert_eq!(removed.id(), id);
assert!(wheel.get(id).is_none());
assert!(wheel.is_empty());
}
#[test]
fn step_advances_time_and_unlocks_future_event() {
let mut wheel = HashedWheelTimer::new(4);
let scheduled = wheel.schedule(2, 1);
assert!(wheel.pop_events().is_empty());
wheel.step();
assert!(wheel.pop_events().is_empty());
wheel.step();
let events = wheel.pop_events();
assert_eq!(events.len(), 1);
assert_eq!(events[0].id(), scheduled.id);
}
#[test]
fn invalid_bucket_index_returns_error() {
let wheel = HashedWheelTimer::<u32>::new(2);
let err = wheel.count_in_bucket(10).unwrap_err();
assert_eq!(
err,
TimeWheelError::InvalidBucketIndex {
index: 10,
buckets: 2,
}
);
}
#[test]
fn is_empty_bucket_reflects_bucket_state() {
let mut wheel = HashedWheelTimer::new(2);
assert!(wheel.is_empty_bucket(0).unwrap());
let _ = wheel.schedule(0, 99);
assert!(!wheel.is_empty_bucket(0).unwrap());
}
#[test]
fn has_events_in_current_tick_ignores_future_events_in_same_bucket() {
let mut wheel = HashedWheelTimer::new(2);
let _ = wheel.schedule(2, 10);
assert!(!wheel.has_events_in_current_tick());
let _ = wheel.schedule(0, 20);
assert!(wheel.has_events_in_current_tick());
let popped = wheel.pop_events();
assert_eq!(popped.len(), 1);
assert!(!wheel.has_events_in_current_tick());
}