1use crate::strategy::*;
13use crate::test_runner::*;
14
15use rand::Rng;
16
17#[derive(Clone, Copy, Debug)]
19pub struct Any(());
20
21pub const ANY: Any = Any(());
25
26impl Strategy for Any {
27 type Tree = BoolValueTree;
28 type Value = bool;
29
30 fn new_tree(&self, runner: &mut TestRunner) -> NewTree<Self> {
31 Ok(BoolValueTree::new(runner.rng().gen()))
32 }
33}
34
35pub fn weighted(probability: f64) -> Weighted {
40 Weighted(probability)
41}
42
43#[must_use = "strategies do nothing unless used"]
45#[derive(Clone, Copy, Debug)]
46pub struct Weighted(f64);
47
48impl Strategy for Weighted {
49 type Tree = BoolValueTree;
50 type Value = bool;
51
52 fn new_tree(&self, runner: &mut TestRunner) -> NewTree<Self> {
53 Ok(BoolValueTree::new(runner.rng().gen_bool(self.0)))
54 }
55}
56
57#[derive(Clone, Copy, Debug)]
59pub struct BoolValueTree {
60 current: bool,
61 state: ShrinkState,
62}
63
64#[derive(Clone, Copy, Debug, PartialEq)]
65enum ShrinkState {
66 Untouched,
67 Simplified,
68 Final,
69}
70
71impl BoolValueTree {
72 fn new(current: bool) -> Self {
73 BoolValueTree {
74 current,
75 state: ShrinkState::Untouched,
76 }
77 }
78}
79
80impl ValueTree for BoolValueTree {
81 type Value = bool;
82
83 fn current(&self) -> bool {
84 self.current
85 }
86 fn simplify(&mut self) -> bool {
87 match self.state {
88 ShrinkState::Untouched if self.current => {
89 self.current = false;
90 self.state = ShrinkState::Simplified;
91 true
92 }
93
94 ShrinkState::Untouched
95 | ShrinkState::Simplified
96 | ShrinkState::Final => {
97 self.state = ShrinkState::Final;
98 false
99 }
100 }
101 }
102 fn complicate(&mut self) -> bool {
103 match self.state {
104 ShrinkState::Untouched | ShrinkState::Final => {
105 self.state = ShrinkState::Final;
106 false
107 }
108
109 ShrinkState::Simplified => {
110 self.current = true;
111 self.state = ShrinkState::Final;
112 true
113 }
114 }
115 }
116}
117
118#[cfg(test)]
119mod test {
120 use super::*;
121
122 #[test]
123 fn test_sanity() {
124 check_strategy_sanity(ANY, None);
125 }
126
127 #[test]
128 fn shrinks_properly() {
129 let mut tree = BoolValueTree::new(true);
130 assert!(tree.simplify());
131 assert!(!tree.current());
132 assert!(!tree.clone().simplify());
133 assert!(tree.complicate());
134 assert!(!tree.clone().complicate());
135 assert!(tree.current());
136 assert!(!tree.simplify());
137 assert!(tree.current());
138
139 tree = BoolValueTree::new(false);
140 assert!(!tree.clone().simplify());
141 assert!(!tree.clone().complicate());
142 assert!(!tree.current());
143 }
144}