use effect_rs::{Effect, Exit, Ref, Runtime, Schedule};
use std::time::Duration;
#[test]
fn test_schedule_exponential() {
let rt = Runtime::new();
let counter = Ref::new(0);
let program = counter
.update(|x| x + 1)
.map_error(|_| "err")
.flat_map(|val| {
if val < 4 {
Effect::fail("error")
} else {
Effect::succeed(val)
}
})
.retry(Schedule::<&str, Duration>::exponential(
Duration::from_millis(10),
2.0,
));
let result = rt.block_on(program, ());
match result {
Exit::Success(val) => assert_eq!(val, 4),
Exit::Failure(_) => panic!("Expected success"),
}
}
#[test]
fn test_schedule_jitter() {
let rt = Runtime::new();
let counter = Ref::new(0);
let program = counter
.update(|x| x + 1)
.map_error(|_| "err")
.flat_map(|val| {
if val < 4 {
Effect::fail("error")
} else {
Effect::succeed(val)
}
})
.retry(Schedule::<&str, ()>::spaced(Duration::from_millis(50)).jittered(0.0, 0.1));
let result = rt.block_on(program, ());
match result {
Exit::Success(val) => assert_eq!(val, 4),
Exit::Failure(_) => panic!("Expected success"),
}
}
#[test]
fn test_schedule_intersect() {
let rt = Runtime::new();
let counter = Ref::new(0);
let program = counter
.update(|x| x + 1)
.map_error(|_| "err")
.flat_map(|val| {
if val <= 10 {
Effect::fail("error")
} else {
Effect::succeed(val)
}
})
.retry(
Schedule::<&str, usize>::recurs(3)
.intersect(Schedule::<&str, ()>::spaced(Duration::from_millis(1))),
);
let result = rt.block_on(program, ());
match result {
Exit::Failure(_) => {
let c = rt.block_on(counter.get(), ());
match c {
Exit::Success(val) => assert_eq!(val, 4),
_ => panic!("Failed to get counter"),
}
}
Exit::Success(_) => panic!("Expected failure after 3 retries"),
}
}
#[test]
fn test_schedule_union() {
let rt = Runtime::new();
let counter = Ref::new(0);
let program = counter
.update(|x| x + 1)
.map_error(|_| "err")
.flat_map(|val| {
if val <= 10 {
Effect::fail("error")
} else {
Effect::succeed(val)
}
})
.retry(Schedule::<&str, usize>::recurs(2).union(Schedule::<&str, usize>::recurs(4)));
let result = rt.block_on(program, ());
match result {
Exit::Failure(_) => {
let c = rt.block_on(counter.get(), ());
match c {
Exit::Success(val) => assert_eq!(val, 5),
_ => panic!("Failed to get counter"),
}
}
Exit::Success(_) => panic!("Expected failure"),
}
}