Diffstat (limited to 'tests/protocol_visitor_recoverable.rs')
-rw-r--r--tests/protocol_visitor_recoverable.rs68
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)
+ ));
+}