use common::protocol::recoverable::MockRecoverableVisitor;
use treaty::{
any::OwnedStatic,
effect::blocking::Blocking,
protocol::{
visitor::{Recoverable, ValueProto, VisitResult},
DynVisitor,
},
Flow, Status,
};
use crate::common::{
builder::MockBuilder,
protocol::recoverable::{MockRecoverableScopeVisitor, RecoverableScopeFactory},
};
mod common;
/// Tests that the recoverable protocol allows multiple walks by the visitor.
#[test]
fn recoverable_can_be_visited() {
let mut mock = MockRecoverableVisitor::<Blocking>::new();
// Expect a visit using the rescoverable protocol.
mock.expect_visit().once().return_const(
(|(), scope| {
let mut visitor = MockBuilder::<(), (), ()>::new();
// Expect that the visitor gets used.
visitor.expect_traits().times(2).return_const(None);
// Attempt to walk once.
assert_eq!(scope.new_walk(DynVisitor(&mut visitor)).value(), Status::Ok);
// Attempt to walk twice.
assert_eq!(scope.new_walk(DynVisitor(&mut visitor)).value(), Status::Ok);
// We are done.
VisitResult::Control(Flow::Done)
}) as RecoverableScopeFactory<Blocking>,
);
let visitor: &mut dyn Recoverable<Blocking> = &mut mock;
let mut scope = MockRecoverableScopeVisitor::new();
// Expect two walks of the recoverable walker.
scope.expect_new_walk().times(2).returning(|visitor| {
// Attempt to use the visitor.
assert!(visitor
.upcast::<ValueProto<OwnedStatic<i32>, Blocking>>()
.is_none());
Status::Ok
});
// Visit using the recoverable protocol.
assert!(matches!(
visitor.visit(&mut scope).value(),
VisitResult::Control(Flow::Done)
));
}