use wasm_bindgen_test::{wasm_bindgen_test, wasm_bindgen_test_configure}; #[cfg(browser)] wasm_bindgen_test_configure!(run_in_browser); #[cfg(feature = "serde")] #[wasm_bindgen_test] pub fn test_serde() { use wasmtimer::std::SystemTime; let now = SystemTime::now(); let serialized = serde_json::to_string(&now).unwrap(); let deserialized: SystemTime = serde_json::from_str(&serialized).unwrap(); assert_eq!(now, deserialized); } #[cfg(feature = "tokio-test-util")] pub mod tokio_tests { use super::*; use std::{pin::Pin, sync::Once, time::Duration}; use futures::{task::noop_waker_ref, Future}; use std::task::{Context, Poll}; use wasmtimer::std::Instant; use wasmtimer::tokio::{advance, pause}; static INIT: Once = Once::new(); pub fn initialize() { INIT.call_once(|| { pause(); }); } #[wasm_bindgen_test] pub async fn test_micro_second_precision() { initialize(); let a = Instant::now(); advance(Duration::from_micros(435)).await; let b = Instant::now(); let diff = b - a; assert_eq!(diff.as_micros(), 435); } pub mod sleep_tests { use super::*; use wasmtimer::tokio::sleep; #[wasm_bindgen_test] async fn is_elapsed_test() { initialize(); let slept = sleep(Duration::from_millis(1000)); assert!(!slept.is_elapsed()); advance(Duration::from_millis(1005)).await; assert!(slept.is_elapsed()); } #[wasm_bindgen_test] async fn poll_test() { initialize(); let waker = noop_waker_ref(); let mut cx = Context::from_waker(waker); let mut slept = sleep(Duration::from_millis(1000)); assert_eq!(Pin::new(&mut slept).poll(&mut cx), Poll::Pending); advance(Duration::from_millis(1005)).await; assert_eq!(Pin::new(&mut slept).poll(&mut cx), Poll::Ready(())); } #[wasm_bindgen_test] async fn reset_before_exec_test() { initialize(); let waker = noop_waker_ref(); let mut cx = Context::from_waker(waker); let mut slept = sleep(Duration::from_millis(1000)); Pin::new(&mut slept).reset(Instant::now() + Duration::from_millis(2000)); assert_eq!(Pin::new(&mut slept).poll(&mut cx), Poll::Pending); advance(Duration::from_millis(1005)).await; assert_eq!(Pin::new(&mut slept).poll(&mut cx), Poll::Pending); advance(Duration::from_millis(1005)).await; assert_eq!(Pin::new(&mut slept).poll(&mut cx), Poll::Ready(())); } #[wasm_bindgen_test] async fn reset_after_exec_test() { initialize(); let waker = noop_waker_ref(); let mut cx = Context::from_waker(waker); let mut slept = sleep(Duration::from_millis(1000)); assert_eq!(Pin::new(&mut slept).poll(&mut cx), Poll::Pending); advance(Duration::from_millis(1005)).await; assert_eq!(Pin::new(&mut slept).poll(&mut cx), Poll::Ready(())); Pin::new(&mut slept).reset(Instant::now() + Duration::from_millis(1500)); assert_eq!(Pin::new(&mut slept).poll(&mut cx), Poll::Pending); advance(Duration::from_millis(1505)).await; assert_eq!(Pin::new(&mut slept).poll(&mut cx), Poll::Ready(())); } } pub mod interval_tests { use wasmtimer::tokio::{interval, interval_at, MissedTickBehavior}; use super::*; #[wasm_bindgen_test] async fn interval_tick_test() { initialize(); let waker = noop_waker_ref(); let mut cx = Context::from_waker(waker); let mut interval = interval(Duration::from_millis(500)); let mut fut = interval.tick(); unsafe { assert_ne!(Pin::new_unchecked(&mut fut).poll(&mut cx), Poll::Pending); } drop(fut); let mut fut2 = interval.tick(); unsafe { assert_eq!(Pin::new_unchecked(&mut fut2).poll(&mut cx), Poll::Pending); } advance(Duration::from_millis(501)).await; unsafe { assert!(matches!( Pin::new_unchecked(&mut fut2).poll(&mut cx), Poll::Ready(_) )); } drop(fut2); let mut fut3 = interval.tick(); unsafe { assert_eq!(Pin::new_unchecked(&mut fut3).poll(&mut cx), Poll::Pending); } advance(Duration::from_millis(501)).await; unsafe { assert!(matches!( Pin::new_unchecked(&mut fut3).poll(&mut cx), Poll::Ready(_) )); } } #[wasm_bindgen_test] async fn interval_at_tick_test() { initialize(); let waker = noop_waker_ref(); let mut cx = Context::from_waker(waker); let mut interval = interval_at( Instant::now() + Duration::from_millis(1000), Duration::from_millis(500), ); let mut fut = interval.tick(); unsafe { assert_eq!(Pin::new_unchecked(&mut fut).poll(&mut cx), Poll::Pending); } advance(Duration::from_millis(501)).await; unsafe { assert_eq!(Pin::new_unchecked(&mut fut).poll(&mut cx), Poll::Pending); } advance(Duration::from_millis(501)).await; unsafe { assert!(matches!( Pin::new_unchecked(&mut fut).poll(&mut cx), Poll::Ready(_) )); } drop(fut); let mut fut2 = interval.tick(); unsafe { assert_eq!(Pin::new_unchecked(&mut fut2).poll(&mut cx), Poll::Pending); } advance(Duration::from_millis(501)).await; unsafe { assert!(matches!( Pin::new_unchecked(&mut fut2).poll(&mut cx), Poll::Ready(_) )); } } #[wasm_bindgen_test] async fn interval_poll_tick_test() { initialize(); let waker = noop_waker_ref(); let mut cx = Context::from_waker(waker); let mut interval = interval(Duration::from_millis(500)); assert_ne!(interval.poll_tick(&mut cx), Poll::Pending); assert_eq!(interval.poll_tick(&mut cx), Poll::Pending); advance(Duration::from_millis(501)).await; assert!(matches!(interval.poll_tick(&mut cx), Poll::Ready(_))); assert_eq!(interval.poll_tick(&mut cx), Poll::Pending); advance(Duration::from_millis(501)).await; assert!(matches!(interval.poll_tick(&mut cx), Poll::Ready(_))); } #[wasm_bindgen_test] async fn interval_at_poll_tick_test() { initialize(); let waker = noop_waker_ref(); let mut cx = Context::from_waker(waker); let mut interval = interval_at( Instant::now() + Duration::from_millis(1000), Duration::from_millis(500), ); assert_eq!(interval.poll_tick(&mut cx), Poll::Pending); advance(Duration::from_millis(501)).await; assert_eq!(interval.poll_tick(&mut cx), Poll::Pending); advance(Duration::from_millis(501)).await; assert!(matches!(interval.poll_tick(&mut cx), Poll::Ready(_))); assert_eq!(interval.poll_tick(&mut cx), Poll::Pending); advance(Duration::from_millis(501)).await; assert!(matches!(interval.poll_tick(&mut cx), Poll::Ready(_))); } #[wasm_bindgen_test] async fn reset_test() { initialize(); let waker = noop_waker_ref(); let mut cx = Context::from_waker(waker); let mut interval = interval(Duration::from_millis(500)); assert_ne!(interval.poll_tick(&mut cx), Poll::Pending); assert_eq!(interval.poll_tick(&mut cx), Poll::Pending); advance(Duration::from_millis(301)).await; assert_eq!(interval.poll_tick(&mut cx), Poll::Pending); interval.reset(); advance(Duration::from_millis(201)).await; assert_eq!(interval.poll_tick(&mut cx), Poll::Pending); advance(Duration::from_millis(301)).await; assert!(matches!(interval.poll_tick(&mut cx), Poll::Ready(_))); } #[wasm_bindgen_test] async fn interval_at_reset_test() { initialize(); let waker = noop_waker_ref(); let mut cx = Context::from_waker(waker); let mut interval = interval_at( Instant::now() + Duration::from_millis(1000), Duration::from_millis(500), ); assert_eq!(interval.poll_tick(&mut cx), Poll::Pending); advance(Duration::from_millis(301)).await; assert_eq!(interval.poll_tick(&mut cx), Poll::Pending); interval.reset(); advance(Duration::from_millis(201)).await; assert_eq!(interval.poll_tick(&mut cx), Poll::Pending); advance(Duration::from_millis(301)).await; assert!(matches!(interval.poll_tick(&mut cx), Poll::Ready(_))); } #[wasm_bindgen_test] async fn missed_tick_behavior_burst_test() { initialize(); let waker = noop_waker_ref(); let mut cx = Context::from_waker(waker); let mut interval = interval(Duration::from_millis(500)); interval.set_missed_tick_behavior(MissedTickBehavior::Burst); advance(Duration::from_millis(1501)).await; assert!(matches!(interval.poll_tick(&mut cx), Poll::Ready(_))); assert!(matches!(interval.poll_tick(&mut cx), Poll::Ready(_))); assert!(matches!(interval.poll_tick(&mut cx), Poll::Ready(_))); assert!(matches!(interval.poll_tick(&mut cx), Poll::Ready(_))); assert_eq!(interval.poll_tick(&mut cx), Poll::Pending); } #[wasm_bindgen_test] async fn missed_tick_behavior_skip_test() { initialize(); let waker = noop_waker_ref(); let mut cx = Context::from_waker(waker); let mut interval = interval(Duration::from_millis(500)); interval.set_missed_tick_behavior(MissedTickBehavior::Skip); advance(Duration::from_millis(1601)).await; assert!(matches!(interval.poll_tick(&mut cx), Poll::Ready(_))); assert_eq!(interval.poll_tick(&mut cx), Poll::Pending); advance(Duration::from_millis(401)).await; assert!(matches!(interval.poll_tick(&mut cx), Poll::Ready(_))); assert_eq!(interval.poll_tick(&mut cx), Poll::Pending); } #[wasm_bindgen_test] async fn missed_tick_behavior_delay_test() { initialize(); let waker = noop_waker_ref(); let mut cx = Context::from_waker(waker); let mut interval = interval(Duration::from_millis(500)); interval.set_missed_tick_behavior(MissedTickBehavior::Delay); advance(Duration::from_millis(1601)).await; assert!(matches!(interval.poll_tick(&mut cx), Poll::Ready(_))); assert_eq!(interval.poll_tick(&mut cx), Poll::Pending); advance(Duration::from_millis(401)).await; assert_eq!(interval.poll_tick(&mut cx), Poll::Pending); advance(Duration::from_millis(100)).await; assert!(matches!(interval.poll_tick(&mut cx), Poll::Ready(_))); assert_eq!(interval.poll_tick(&mut cx), Poll::Pending); } } pub mod timeout_tests { use super::*; use wasmtimer::tokio::{sleep, timeout, timeout_at}; #[wasm_bindgen_test] async fn timeout_success_test() { initialize(); let waker = noop_waker_ref(); let mut cx = Context::from_waker(waker); let mut fut = timeout( Duration::from_millis(1500), sleep(Duration::from_millis(1000)), ); assert_eq!(Pin::new(&mut fut).poll(&mut cx), Poll::Pending); advance(Duration::from_millis(1001)).await; assert!(matches!( Pin::new(&mut fut).poll(&mut cx), Poll::Ready(Ok(_)) )); } #[wasm_bindgen_test] async fn timeout_fail_test() { initialize(); let waker = noop_waker_ref(); let mut cx = Context::from_waker(waker); let mut fut = timeout( Duration::from_millis(1000), sleep(Duration::from_millis(1500)), ); assert_eq!(Pin::new(&mut fut).poll(&mut cx), Poll::Pending); advance(Duration::from_millis(1001)).await; assert!(matches!( Pin::new(&mut fut).poll(&mut cx), Poll::Ready(Err(_)) )); } #[wasm_bindgen_test] async fn timeout_at_success_test() { initialize(); let waker = noop_waker_ref(); let mut cx = Context::from_waker(waker); let mut fut = timeout_at( Instant::now() + Duration::from_millis(1500), sleep(Duration::from_millis(1000)), ); assert_eq!(Pin::new(&mut fut).poll(&mut cx), Poll::Pending); advance(Duration::from_millis(1001)).await; assert!(matches!( Pin::new(&mut fut).poll(&mut cx), Poll::Ready(Ok(_)) )); } #[wasm_bindgen_test] async fn timeout_at_fail_test() { initialize(); let waker = noop_waker_ref(); let mut cx = Context::from_waker(waker); let mut fut = timeout_at( Instant::now() + Duration::from_millis(1000), sleep(Duration::from_millis(1500)), ); assert_eq!(Pin::new(&mut fut).poll(&mut cx), Poll::Pending); advance(Duration::from_millis(1001)).await; assert!(matches!( Pin::new(&mut fut).poll(&mut cx), Poll::Ready(Err(_)) )); } } #[cfg(feature = "tokio-util")] pub mod delay_queue_tests { use wasmtimer::tokio_util::DelayQueue; use super::*; #[wasm_bindgen_test] async fn insert_at_test() { initialize(); let waker = noop_waker_ref(); let mut cx = Context::from_waker(waker); let mut delay_queue = DelayQueue::<()>::new(); let key1 = delay_queue.insert_at((), Instant::now() + Duration::from_millis(1000)); let key2 = delay_queue.insert_at((), Instant::now() + Duration::from_millis(1000)); let key3 = delay_queue.insert_at((), Instant::now() + Duration::from_millis(1500)); advance(Duration::from_millis(1000)).await; let expired_1 = delay_queue.poll_expired(&mut cx); assert!(matches!(expired_1, Poll::Ready(Some(_)))); if let Poll::Ready(Some(expired)) = expired_1 { assert_eq!(key1, expired.key()); } let expired_2 = delay_queue.poll_expired(&mut cx); assert!(matches!(expired_2, Poll::Ready(Some(_)))); if let Poll::Ready(Some(expired)) = expired_2 { assert_eq!(key2, expired.key()); } assert!(matches!(delay_queue.poll_expired(&mut cx), Poll::Pending)); advance(Duration::from_millis(500)).await; let expired_3 = delay_queue.poll_expired(&mut cx); assert!(matches!(expired_3, Poll::Ready(Some(_)))); if let Poll::Ready(Some(expired)) = expired_3 { assert_eq!(key3, expired.key()); } assert!(matches!( delay_queue.poll_expired(&mut cx), Poll::Ready(None) )); let key4 = delay_queue.insert_at((), Instant::now() + Duration::from_millis(500)); advance(Duration::from_millis(500)).await; let expired_4 = delay_queue.poll_expired(&mut cx); assert!(matches!(expired_4, Poll::Ready(Some(_)))); if let Poll::Ready(Some(expired)) = expired_4 { assert_eq!(key4, expired.key()); } assert!(matches!( delay_queue.poll_expired(&mut cx), Poll::Ready(None) )); } #[wasm_bindgen_test] async fn insert_test() { initialize(); let waker = noop_waker_ref(); let mut cx = Context::from_waker(waker); let mut delay_queue = DelayQueue::<()>::new(); let key1 = delay_queue.insert((), Duration::from_millis(1000)); let key2 = delay_queue.insert((), Duration::from_millis(1000)); let key3 = delay_queue.insert((), Duration::from_millis(1500)); advance(Duration::from_millis(1000)).await; let expired_1 = delay_queue.poll_expired(&mut cx); assert!(matches!(expired_1, Poll::Ready(Some(_)))); if let Poll::Ready(Some(expired)) = expired_1 { assert_eq!(key1, expired.key()); } let expired_2 = delay_queue.poll_expired(&mut cx); assert!(matches!(expired_2, Poll::Ready(Some(_)))); if let Poll::Ready(Some(expired)) = expired_2 { assert_eq!(key2, expired.key()); } assert!(matches!(delay_queue.poll_expired(&mut cx), Poll::Pending)); advance(Duration::from_millis(500)).await; let expired_3 = delay_queue.poll_expired(&mut cx); assert!(matches!(expired_3, Poll::Ready(Some(_)))); if let Poll::Ready(Some(expired)) = expired_3 { assert_eq!(key3, expired.key()); } assert!(matches!( delay_queue.poll_expired(&mut cx), Poll::Ready(None) )); let key4 = delay_queue.insert((), Duration::from_millis(500)); advance(Duration::from_millis(500)).await; let expired_4 = delay_queue.poll_expired(&mut cx); assert!(matches!(expired_4, Poll::Ready(Some(_)))); if let Poll::Ready(Some(expired)) = expired_4 { assert_eq!(key4, expired.key()); } assert!(matches!( delay_queue.poll_expired(&mut cx), Poll::Ready(None) )); } #[wasm_bindgen_test] async fn immidiately_remove_test() { initialize(); let waker = noop_waker_ref(); let mut cx = Context::from_waker(waker); let mut delay_queue = DelayQueue::<()>::new(); let key1 = delay_queue.insert((), Duration::from_millis(1000)); delay_queue.remove(&key1); assert!(matches!( delay_queue.poll_expired(&mut cx), Poll::Ready(None) )); advance(Duration::from_millis(1000)).await; assert!(matches!( delay_queue.poll_expired(&mut cx), Poll::Ready(None) )); } #[wasm_bindgen_test] async fn remove_after_deadline_test() { initialize(); let waker = noop_waker_ref(); let mut cx = Context::from_waker(waker); let mut delay_queue = DelayQueue::<()>::new(); let key1 = delay_queue.insert((), Duration::from_millis(1000)); assert!(matches!(delay_queue.poll_expired(&mut cx), Poll::Pending)); advance(Duration::from_millis(1000)).await; delay_queue.remove(&key1); assert!(matches!( delay_queue.poll_expired(&mut cx), Poll::Ready(None) )); } #[wasm_bindgen_test] async fn reset_test() { initialize(); let waker = noop_waker_ref(); let mut cx = Context::from_waker(waker); let mut delay_queue = DelayQueue::<()>::new(); let key1 = delay_queue.insert((), Duration::from_millis(1000)); assert!(matches!(delay_queue.poll_expired(&mut cx), Poll::Pending)); delay_queue.reset(&key1, Duration::from_millis(1500)); advance(Duration::from_millis(1000)).await; assert!(matches!(delay_queue.poll_expired(&mut cx), Poll::Pending)); advance(Duration::from_millis(500)).await; assert!(matches!( delay_queue.poll_expired(&mut cx), Poll::Ready(Some(_)) )); assert!(matches!( delay_queue.poll_expired(&mut cx), Poll::Ready(None) )); } } }