Diffstat (limited to 'tests/protocol_visitor_sequence.rs')
-rw-r--r--tests/protocol_visitor_sequence.rs76
1 files changed, 76 insertions, 0 deletions
diff --git a/tests/protocol_visitor_sequence.rs b/tests/protocol_visitor_sequence.rs
new file mode 100644
index 0000000..52433dc
--- /dev/null
+++ b/tests/protocol_visitor_sequence.rs
@@ -0,0 +1,76 @@
+use std::any::TypeId;
+
+use common::protocol::sequence::{
+ MockSequenceScopeVisitor, MockSequenceVisitor, SequenceScopeFactory,
+};
+use treaty::{
+ any::{OwnedStatic, TypeNameId},
+ effect::Blocking,
+ protocol::{visitor::{Sequence, SequenceProto, ValueProto, VisitResult}, DynVisitor},
+ Flow,
+};
+
+use crate::common::builder::MockBuilder;
+
+mod common;
+
+#[test]
+fn sequence_has_scope_with_size_hint_and_next() {
+ let mut mock = MockSequenceVisitor::<Blocking>::new();
+
+ // Expect a visit with the sequence protocol.
+ mock.expect_visit().once().return_const(
+ (|(), scope| {
+ // Get the size hint from the sequence scope.
+ assert_eq!(scope.size_hint().into_inner(), (1, Some(1)));
+
+ let mut visitor = MockBuilder::<(), (), ()>::new();
+
+ // Expect the walker to lookup a trait.
+ visitor.expect_traits().once().return_const(None);
+
+ // Get the next item in the sequence from the walker.
+ scope.next(DynVisitor(&mut visitor));
+
+ // We are done.
+ VisitResult::Control(Flow::Done)
+ }) as SequenceScopeFactory<Blocking>,
+ );
+
+ // Everything goes throw the sequence protocol trait.
+ let visitor: &mut dyn Sequence<Blocking> = &mut mock;
+
+ let mut scope = MockSequenceScopeVisitor::<Blocking>::new();
+
+ // Expect a size hint to be asked for.
+ scope.expect_size_hint().once().return_const((1, Some(1)));
+
+ // Expect that one element is gotten from the sequence.
+ scope.expect_next().once().returning(|visitor| {
+ // Attempt to lookup a trait on the visitor.
+ assert!(visitor
+ .upcast::<ValueProto<OwnedStatic<i32>, Blocking>>()
+ .is_none());
+
+ // We are done.
+ Flow::Done
+ });
+
+ // Visit a sequence.
+ assert!(matches!(
+ visitor.visit(&mut scope).into_inner(),
+ VisitResult::Control(Flow::Done)
+ ));
+}
+
+#[test]
+fn sequence_proto() {
+ // The type id of the higher ranked type.
+ let id = TypeId::of::<SequenceProto<Blocking>>();
+
+ // The type id for the lifetime containing value protocol trait object.
+ let name_id = TypeNameId::of_lower::<dyn Sequence<Blocking> + Send + Sync>();
+
+ // They should be the same.
+ assert_eq!(id, name_id.into_type_id());
+}