use proptest::collection::vec; use proptest::strategy::{Just, SBoxedStrategy}; use proptest::{prelude::*, proptest}; use proptest_recurse::{StrategyExt, StrategySet}; #[derive(Clone, Debug)] enum First { Zero, Second(Vec), } #[derive(Clone, Debug)] enum Second { Zero, First(First), } impl First { fn depth(&self) -> u32 { match self { First::Zero => 0, First::Second(s) => match s.iter().map(Second::depth).max() { Some(depth) => depth + 1, None => 0, }, } } } impl Second { fn depth(&self) -> u32 { match self { Second::Zero => 0, Second::First(f) => f.depth() + 1, } } } fn arb_first(set: &mut StrategySet) -> SBoxedStrategy { Just(First::Zero).prop_mutually_recursive(5, 32, 8, set, |set| { vec(set.get::(arb_second), 0..8) .prop_map(First::Second) .sboxed() }) } fn arb_second(set: &mut StrategySet) -> SBoxedStrategy { Just(Second::Zero) .prop_mutually_recursive(3, 32, 1, set, |set| { set.get::(arb_first) .prop_map(Second::First) .sboxed() }) .sboxed() } proptest! { #[test] fn create_first(x in arb_first(&mut Default::default())) { assert!(x.depth() <= 8); } #[test] fn create_second(x in arb_second(&mut Default::default())) { assert!(x.depth() <= 8); } }