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