Diffstat (limited to 'tests/protocol_visitor_recoverable.rs')
| -rw-r--r-- | tests/protocol_visitor_recoverable.rs | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/tests/protocol_visitor_recoverable.rs b/tests/protocol_visitor_recoverable.rs new file mode 100644 index 0000000..07ec092 --- /dev/null +++ b/tests/protocol_visitor_recoverable.rs @@ -0,0 +1,68 @@ +use common::protocol::recoverable::MockRecoverableVisitor; +use treaty::{ + any::OwnedStatic, + effect::Blocking, + protocol::{ + visitor::{Recoverable, ValueProto, VisitResult}, + DynVisitor, + }, + Flow, +}; + +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)).into_inner(), + Ok(()) + ); + + // Attempt to walk twice. + assert_eq!( + scope.new_walk(DynVisitor(&mut visitor)).into_inner(), + 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()); + + Ok(()) + }); + + // Visit using the recoverable protocol. + assert!(matches!( + visitor.visit(&mut scope).into_inner(), + VisitResult::Control(Flow::Done) + )); +} |