use std::{sync::atomic::{AtomicBool, Ordering}, time::Duration};
use futures::{FutureExt, future};
use smol::{Timer, block_on, future::{race, yield_now}};
use floop::floop;
#[test]
fn counter() {
let mut counter = 0;
let run = AtomicBool::new(true);
let future = race(
floop!{biased
_ in Timer::after(Duration::from_millis(20)) => {
if counter % 2 == 1 {
counter += 1;
}
}
_ in Timer::after(Duration::from_millis(14)) => {
if counter % 2 == 0 {
counter += 1;
}
if counter >= 21 {
run.store(false, Ordering::Relaxed);
}
}
}.map(drop),
async {
while run.load(Ordering::Relaxed) {
yield_now().await;
}
}
);
block_on(future);
assert_eq!(counter, 21);
}
#[test]
fn break_() {
let future = floop!{biased
val in future::ready(2) => {
break val;
}
val in future::ready(5) => {
break val;
}
};
let result = block_on(future);
assert_eq!(result, (2, 5));
}
#[test]
fn break_complex() {
let mut counter = 10;
let mut collatz = 77031;
let future = floop!{
biased
_ in Timer::after(Duration::from_millis(counter))=> {
if collatz == 1 {
break;
} else if collatz % 2 == 0 {
collatz /= 2;
} else {
collatz = collatz * 3 + 1;
}
}
_ in Timer::after(Duration::from_micros(collatz / 5)) => {
if counter == 0 {
break;
}
counter -= 1;
}
};
block_on(future);
assert_eq!(counter, 0);
assert_eq!(collatz, 1);
}