Diffstat (limited to 'src/walk/walkers/core/struct.rs')
| -rw-r--r-- | src/walk/walkers/core/struct.rs | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/src/walk/walkers/core/struct.rs b/src/walk/walkers/core/struct.rs index 5ffb224..cbcb5c0 100644 --- a/src/walk/walkers/core/struct.rs +++ b/src/walk/walkers/core/struct.rs @@ -659,3 +659,155 @@ where }) } } + +#[cfg(test)] +mod test { + use mockall::{predicate::eq, Sequence}; + + use crate::{ + any::{ + static_wrapper::{DynOwnedStatic, OwnedStatic}, + LtTypeId, + }, + effect::{BlockOn as _, Blocking, Spin}, + mock::{ + builder::MockBuilder, + protocol::{tag::MockTagVisitor, value::MockValueVisitor}, + }, + symbol::Symbol, + Builder, DefaultMode, Walker, + }; + + use super::*; + + struct Demo { + a: bool, + b: bool, + } + + impl<'ctx, M> StructTypeInfo<'ctx, M> for Demo { + const NAME: &'static str = "Demo"; + + const FIELDS: &'static [&'static str] = &["a", "b"]; + + type FieldError = (); + + type T = Demo; + + fn walk_field<'a, E: Effect<'ctx>>( + index: usize, + value: &'ctx Self::T, + visitor: Visitor<'a, 'ctx>, + ) -> Future<'a, 'ctx, Result<Flow, Self::FieldError>, E> { + E::wrap(async move { + match index { + 0 => { + let walker = ValueWalker::<bool>::new(value.a); + Walker::<E>::walk(walker, visitor).await.unwrap(); + Ok(Flow::Continue) + } + 1 => { + let walker = ValueWalker::<bool>::new(value.b); + Walker::<E>::walk(walker, visitor).await.unwrap(); + Ok(Flow::Continue) + } + _ => Ok(Flow::Done), + } + }) + } + } + + #[test] + fn demo2() { + let mut builder = MockBuilder::<(), (), ()>::new(); + + let mut seq = Sequence::new(); + + builder + .expect_traits_mut() + .times(4) + .in_sequence(&mut seq) + .return_var(None); + + builder + .expect_traits_mut() + .once() + .with(eq(LtTypeId::of::< + DynTag<'static, TagConst<{ TAG_STRUCT.to_int() }>, Blocking>, + >() + .as_type_id())) + .in_sequence(&mut seq) + .return_var(Some(Box::new({ + let mut mock = MockTagVisitor::<TagConst<{ TAG_STRUCT.to_int() }>, Blocking>::new(); + + mock.expect_visit().once().returning(|_, walker| { + let mut builder = MockBuilder::<(), (), ()>::new(); + assert_eq!( + Spin::block_on(walker.walk(Builder::<Blocking>::as_visitor(&mut builder))), + Flow::Done + ); + + Flow::Continue + }); + + mock + }))); + + builder + .expect_traits_mut() + .once() + .with(eq(LtTypeId::of::< + DynTag<'static, TagConst<{ TAG_TYPE_NAME.to_int() }>, Blocking>, + >() + .as_type_id())) + .in_sequence(&mut seq) + .return_var(Some(Box::new({ + let mut mock = + MockTagVisitor::<TagConst<{ TAG_TYPE_NAME.to_int() }>, Blocking>::new(); + + mock.expect_visit().return_once(|_, walker| { + let mut builder = MockBuilder::<(), (), ()>::new(); + + builder + .expect_traits_mut() + .once() + .with(eq(LtTypeId::of::< + DynValue<'static, DynOwnedStatic<&'static str>, Blocking>, + >() + .as_type_id())) + .return_var(Some(Box::new({ + let mut mock = + MockValueVisitor::<DynOwnedStatic<&'static str>, Blocking>::new(); + + mock.expect_visit() + .once() + .with(eq(OwnedStatic("Demo"))) + .return_const(Flow::Done); + + mock + }))); + + assert_eq!( + Spin::block_on(walker.walk(Builder::<Blocking>::as_visitor(&mut builder))), + Flow::Done + ); + + Flow::Continue + }); + + mock + }))); + + builder + .expect_traits_mut() + .times(3) + .in_sequence(&mut seq) + .return_var(None); + + let value = Demo { a: true, b: false }; + + let walker = StructWalker::<Demo, Demo, DefaultMode, Blocking>::new(&value); + + Spin::block_on(walker.walk(Builder::<Blocking>::as_visitor(&mut builder))).unwrap(); + } +} |