use effect_rs::{Effect, Exit, Runtime, STM, TRef};
use tokio::time::Duration;
#[test]
fn test_stm_commit() {
let rt = Runtime::new();
let tref = TRef::new(0);
let tref_clone = tref.clone();
let transaction = tref_clone.get().flat_map(move |v| tref_clone.set(v + 1));
let program = transaction.commit();
let res = rt.block_on(program, ());
match res {
Exit::Success(_) => {}
Exit::Failure(_) => panic!("STM Commit Failed"),
}
let check = tref.get().commit();
let val = rt.block_on(check, ());
match val {
Exit::Success(v) => assert_eq!(v, 1),
Exit::Failure(_) => panic!("Read failed"),
}
}
#[test]
fn test_stm_isolation() {
}
#[test]
fn test_stm_retry() {
let rt = Runtime::new();
let tref = TRef::new(0);
let wait_program = tref
.get()
.flat_map(|v| if v > 0 { STM::succeed(v) } else { STM::retry() })
.commit();
let tref_clone = tref.clone();
let setter = Effect::<(), (), ()>::sleep(Duration::from_millis(50))
.flat_map(move |_| tref_clone.set(1).commit());
let program = wait_program.zip_par(setter);
let result = rt.block_on(program, ());
match result {
Exit::Success((val, _)) => assert_eq!(val, 1),
Exit::Failure(cause) => panic!("STM Failed: {:?}", cause),
}
}