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());
}