proptest/strategy/
statics.rs1use crate::std_facade::fmt;
28
29use crate::strategy::traits::*;
30use crate::test_runner::*;
31
32pub trait FilterFn<T> {
38 fn apply(&self, t: &T) -> bool;
40}
41
42#[derive(Clone)]
44#[must_use = "strategies do nothing unless used"]
45pub struct Filter<S, F> {
46 source: S,
47 whence: Reason,
48 fun: F,
49}
50
51impl<S, F> Filter<S, F> {
52 pub fn new(source: S, whence: Reason, filter: F) -> Self {
55 Filter {
58 source,
59 whence,
60 fun: filter,
61 }
62 }
63}
64
65impl<S: fmt::Debug, F> fmt::Debug for Filter<S, F> {
66 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
67 f.debug_struct("Filter")
68 .field("source", &self.source)
69 .field("whence", &self.whence)
70 .field("fun", &"<function>")
71 .finish()
72 }
73}
74
75impl<S: Strategy, F: FilterFn<S::Value> + Clone> Strategy for Filter<S, F> {
76 type Tree = Filter<S::Tree, F>;
77 type Value = S::Value;
78
79 fn new_tree(&self, runner: &mut TestRunner) -> NewTree<Self> {
80 loop {
81 let val = self.source.new_tree(runner)?;
82 if !self.fun.apply(&val.current()) {
83 runner.reject_local(self.whence.clone())?;
84 } else {
85 return Ok(Filter {
86 source: val,
87 whence: "unused".into(),
88 fun: self.fun.clone(),
89 });
90 }
91 }
92 }
93}
94
95impl<S: ValueTree, F: FilterFn<S::Value>> Filter<S, F> {
96 fn ensure_acceptable(&mut self) {
97 while !self.fun.apply(&self.source.current()) {
98 if !self.source.complicate() {
99 panic!(
100 "Unable to complicate filtered strategy \
101 back into acceptable value"
102 );
103 }
104 }
105 }
106}
107
108impl<S: ValueTree, F: FilterFn<S::Value>> ValueTree for Filter<S, F> {
109 type Value = S::Value;
110
111 fn current(&self) -> S::Value {
112 self.source.current()
113 }
114
115 fn simplify(&mut self) -> bool {
116 if self.source.simplify() {
117 self.ensure_acceptable();
118 true
119 } else {
120 false
121 }
122 }
123
124 fn complicate(&mut self) -> bool {
125 if self.source.complicate() {
126 self.ensure_acceptable();
127 true
128 } else {
129 false
130 }
131 }
132}
133
134pub trait MapFn<T> {
140 #[allow(missing_docs)]
141 type Output: fmt::Debug;
142
143 fn apply(&self, t: T) -> Self::Output;
145}
146
147#[derive(Clone)]
149#[must_use = "strategies do nothing unless used"]
150pub struct Map<S, F> {
151 source: S,
152 fun: F,
153}
154
155impl<S, F> Map<S, F> {
156 pub fn new(source: S, fun: F) -> Self {
158 Map { source, fun }
159 }
160}
161
162impl<S: fmt::Debug, F> fmt::Debug for Map<S, F> {
163 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
164 f.debug_struct("Map")
165 .field("source", &self.source)
166 .field("fun", &"<function>")
167 .finish()
168 }
169}
170
171impl<S: Strategy, F: Clone + MapFn<S::Value>> Strategy for Map<S, F> {
172 type Tree = Map<S::Tree, F>;
173 type Value = F::Output;
174
175 fn new_tree(&self, runner: &mut TestRunner) -> NewTree<Self> {
176 self.source.new_tree(runner).map(|v| Map {
177 source: v,
178 fun: self.fun.clone(),
179 })
180 }
181}
182
183impl<S: ValueTree, F: MapFn<S::Value>> ValueTree for Map<S, F> {
184 type Value = F::Output;
185
186 fn current(&self) -> F::Output {
187 self.fun.apply(self.source.current())
188 }
189
190 fn simplify(&mut self) -> bool {
191 self.source.simplify()
192 }
193
194 fn complicate(&mut self) -> bool {
195 self.source.complicate()
196 }
197}
198
199impl<I, O: fmt::Debug> MapFn<I> for fn(I) -> O {
200 type Output = O;
201 fn apply(&self, x: I) -> Self::Output {
202 self(x)
203 }
204}
205
206pub(crate) fn static_map<S: Strategy, O: fmt::Debug>(
207 strat: S,
208 fun: fn(S::Value) -> O,
209) -> Map<S, fn(S::Value) -> O> {
210 Map::new(strat, fun)
211}
212
213#[cfg(test)]
218mod test {
219 use super::*;
220
221 #[test]
222 fn test_static_filter() {
223 #[derive(Clone, Copy, Debug)]
224 struct MyFilter;
225 impl FilterFn<i32> for MyFilter {
226 fn apply(&self, &v: &i32) -> bool {
227 0 == v % 3
228 }
229 }
230
231 let input = Filter::new(0..256, "%3".into(), MyFilter);
232
233 for _ in 0..256 {
234 let mut runner = TestRunner::default();
235 let mut case = input.new_tree(&mut runner).unwrap();
236
237 assert!(0 == case.current() % 3);
238
239 while case.simplify() {
240 assert!(0 == case.current() % 3);
241 }
242 assert!(0 == case.current() % 3);
243 }
244 }
245
246 #[test]
247 fn test_static_map() {
248 #[derive(Clone, Copy, Debug)]
249 struct MyMap;
250 impl MapFn<i32> for MyMap {
251 type Output = i32;
252 fn apply(&self, v: i32) -> i32 {
253 v * 2
254 }
255 }
256
257 let input = Map::new(0..10, MyMap);
258
259 TestRunner::default()
260 .run(&input, |v| {
261 assert!(0 == v % 2);
262 Ok(())
263 })
264 .unwrap();
265 }
266}