#![cfg(feature = "tokio")]
use curfew::{
join_with_deadline_async, DeadlineJoinerAsync, JoinOutcomeAsync,
TaskOutcome,
};
use std::time::{Duration, Instant};
#[tokio::test]
async fn async_joiner_collects_on_time() {
let deadline = Instant::now() + Duration::from_millis(150);
let mut joiner = DeadlineJoinerAsync::new(deadline);
for value in 0..3u32 {
joiner.spawn(async move {
tokio::time::sleep(Duration::from_millis(20)).await;
value * 2
});
}
let summary = joiner.join_ready().await;
assert_eq!(summary.completed_count(), 3);
assert_eq!(summary.timed_out_count(), 0);
}
#[tokio::test]
async fn async_joiner_respects_deadline() {
let deadline = Instant::now() + Duration::from_millis(80);
let mut joiner = DeadlineJoinerAsync::new(deadline);
joiner.spawn(async {
tokio::time::sleep(Duration::from_millis(30)).await;
1
});
joiner.spawn(async {
tokio::time::sleep(Duration::from_millis(150)).await;
2
});
let summary = joiner.join_ready().await;
assert_eq!(summary.completed_count(), 1);
assert_eq!(summary.timed_out_count(), 1);
}
#[tokio::test]
async fn join_with_deadline_async_reports_timeout() {
let future = async {
tokio::time::sleep(Duration::from_millis(120)).await;
42
};
let deadline = Instant::now() + Duration::from_millis(40);
match join_with_deadline_async(future, deadline).await {
JoinOutcomeAsync::Completed(_) => {
panic!("future should not complete before deadline")
}
JoinOutcomeAsync::TimedOut(late) => {
let result = late.wait().await;
match result.outcome {
TaskOutcome::Completed(value) => assert_eq!(value, 42),
TaskOutcome::Panicked(info) => {
panic!("unexpected panic: {info}")
}
}
}
}
}