Diffstat (limited to 'src/walk/walkers/core/struct.rs')
-rw-r--r--src/walk/walkers/core/struct.rs152
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();
+ }
+}