use std::future::Future;
use std::pin::Pin;
use std::sync::Arc;
use pretty_assertions::assert_eq;
use rstest::rstest;
use tokio::sync::Mutex;
use crate::run_until::run_until;
#[rstest]
#[tokio::test]
async fn test_run_until_condition_met() {
let (inc_value_closure, get_value_closure, condition) = create_test_closures(3);
let result = run_until(100, 5, inc_value_closure, condition, None).await;
assert_eq!(result, Some(3));
assert_eq!(get_value_closure().await, 3); }
#[rstest]
#[tokio::test]
async fn test_run_until_condition_not_met() {
let (inc_value_closure, get_value_closure, condition) = create_test_closures(3);
let failed_result = run_until(100, 2, inc_value_closure, condition, None).await;
assert_eq!(failed_result, None);
assert_eq!(get_value_closure().await, 2); }
type AsyncFn = Box<dyn Fn() -> Pin<Box<dyn Future<Output = u32> + Send>> + Send + Sync>;
type SyncConditionFn = Box<dyn Fn(&u32) -> bool + Send + Sync>;
fn create_test_closures(condition_value: u32) -> (AsyncFn, AsyncFn, SyncConditionFn) {
let counter = Arc::new(Mutex::new(0));
let increment_closure: Box<
dyn Fn() -> Pin<Box<dyn Future<Output = u32> + Send>> + Send + Sync,
> = {
let counter = Arc::clone(&counter);
Box::new(move || {
let counter = Arc::clone(&counter);
Box::pin(async move {
let mut counter_lock = counter.lock().await;
*counter_lock += 1;
*counter_lock
})
})
};
let get_counter_value: Box<
dyn Fn() -> Pin<Box<dyn Future<Output = u32> + Send>> + Send + Sync,
> = {
let counter = Arc::clone(&counter);
Box::new(move || {
let counter = Arc::clone(&counter);
Box::pin(async move {
let counter_lock = counter.lock().await;
*counter_lock
})
})
};
let condition: Box<dyn Fn(&u32) -> bool + Send + Sync> =
Box::new(move |&result: &u32| result >= condition_value);
(increment_closure, get_counter_value, condition)
}