1use crate::std_facade::Arc;
11use core::fmt;
12use core::marker::PhantomData;
13
14use crate::strategy::traits::*;
15use crate::test_runner::*;
16
17#[must_use = "strategies do nothing unless used"]
25pub struct Map<S, F> {
26 pub(super) source: S,
27 pub(super) fun: Arc<F>,
28}
29
30impl<S: fmt::Debug, F> fmt::Debug for Map<S, F> {
31 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
32 f.debug_struct("Map")
33 .field("source", &self.source)
34 .field("fun", &"<function>")
35 .finish()
36 }
37}
38
39impl<S: Clone, F> Clone for Map<S, F> {
40 fn clone(&self) -> Self {
41 Map {
42 source: self.source.clone(),
43 fun: Arc::clone(&self.fun),
44 }
45 }
46}
47
48impl<S: Strategy, O: fmt::Debug, F: Fn(S::Value) -> O> Strategy for Map<S, F> {
49 type Tree = Map<S::Tree, F>;
50 type Value = O;
51
52 fn new_tree(&self, runner: &mut TestRunner) -> NewTree<Self> {
53 self.source.new_tree(runner).map(|v| Map {
54 source: v,
55 fun: Arc::clone(&self.fun),
56 })
57 }
58}
59
60impl<S: ValueTree, O: fmt::Debug, F: Fn(S::Value) -> O> ValueTree
61 for Map<S, F>
62{
63 type Value = O;
64
65 fn current(&self) -> O {
66 (self.fun)(self.source.current())
67 }
68
69 fn simplify(&mut self) -> bool {
70 self.source.simplify()
71 }
72
73 fn complicate(&mut self) -> bool {
74 self.source.complicate()
75 }
76}
77
78#[must_use = "strategies do nothing unless used"]
89pub struct MapInto<S, O> {
90 pub(super) source: S,
91 pub(super) output: PhantomData<O>,
92}
93
94impl<S, O> MapInto<S, O> {
95 pub(super) fn new(source: S) -> Self {
98 Self {
99 source,
100 output: PhantomData,
101 }
102 }
103}
104
105impl<S: fmt::Debug, O> fmt::Debug for MapInto<S, O> {
106 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
107 f.debug_struct("MapInto")
108 .field("source", &self.source)
109 .finish()
110 }
111}
112
113impl<S: Clone, O> Clone for MapInto<S, O> {
114 fn clone(&self) -> Self {
115 Self::new(self.source.clone())
116 }
117}
118
119impl<S: Strategy, O: fmt::Debug> Strategy for MapInto<S, O>
120where
121 S::Value: Into<O>,
122{
123 type Tree = MapInto<S::Tree, O>;
124 type Value = O;
125
126 fn new_tree(&self, runner: &mut TestRunner) -> NewTree<Self> {
127 self.source.new_tree(runner).map(MapInto::new)
128 }
129}
130
131impl<S: ValueTree, O: fmt::Debug> ValueTree for MapInto<S, O>
132where
133 S::Value: Into<O>,
134{
135 type Value = O;
136
137 fn current(&self) -> O {
138 self.source.current().into()
139 }
140
141 fn simplify(&mut self) -> bool {
142 self.source.simplify()
143 }
144
145 fn complicate(&mut self) -> bool {
146 self.source.complicate()
147 }
148}
149
150#[must_use = "strategies do nothing unless used"]
158pub struct Perturb<S, F> {
159 pub(super) source: S,
160 pub(super) fun: Arc<F>,
161}
162
163impl<S: fmt::Debug, F> fmt::Debug for Perturb<S, F> {
164 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
165 f.debug_struct("Perturb")
166 .field("source", &self.source)
167 .field("fun", &"<function>")
168 .finish()
169 }
170}
171
172impl<S: Clone, F> Clone for Perturb<S, F> {
173 fn clone(&self) -> Self {
174 Perturb {
175 source: self.source.clone(),
176 fun: Arc::clone(&self.fun),
177 }
178 }
179}
180
181impl<S: Strategy, O: fmt::Debug, F: Fn(S::Value, TestRng) -> O> Strategy
182 for Perturb<S, F>
183{
184 type Tree = PerturbValueTree<S::Tree, F>;
185 type Value = O;
186
187 fn new_tree(&self, runner: &mut TestRunner) -> NewTree<Self> {
188 let rng = runner.new_rng();
189
190 self.source.new_tree(runner).map(|source| PerturbValueTree {
191 source,
192 rng,
193 fun: Arc::clone(&self.fun),
194 })
195 }
196}
197
198pub struct PerturbValueTree<S, F> {
202 source: S,
203 fun: Arc<F>,
204 rng: TestRng,
205}
206
207impl<S: fmt::Debug, F> fmt::Debug for PerturbValueTree<S, F> {
208 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
209 f.debug_struct("PerturbValueTree")
210 .field("source", &self.source)
211 .field("fun", &"<function>")
212 .field("rng", &self.rng)
213 .finish()
214 }
215}
216
217impl<S: Clone, F> Clone for PerturbValueTree<S, F> {
218 fn clone(&self) -> Self {
219 PerturbValueTree {
220 source: self.source.clone(),
221 fun: Arc::clone(&self.fun),
222 rng: self.rng.clone(),
223 }
224 }
225}
226
227impl<S: ValueTree, O: fmt::Debug, F: Fn(S::Value, TestRng) -> O> ValueTree
228 for PerturbValueTree<S, F>
229{
230 type Value = O;
231
232 fn current(&self) -> O {
233 (self.fun)(self.source.current(), self.rng.clone())
234 }
235
236 fn simplify(&mut self) -> bool {
237 self.source.simplify()
238 }
239
240 fn complicate(&mut self) -> bool {
241 self.source.complicate()
242 }
243}
244
245#[cfg(test)]
250mod test {
251 use std::collections::HashSet;
252
253 use rand::RngCore;
254
255 use super::*;
256 use crate::strategy::just::Just;
257
258 #[test]
259 fn test_map() {
260 TestRunner::default()
261 .run(&(0..10).prop_map(|v| v * 2), |v| {
262 assert!(0 == v % 2);
263 Ok(())
264 })
265 .unwrap();
266 }
267
268 #[test]
269 fn test_map_into() {
270 TestRunner::default()
271 .run(&(0..10u8).prop_map_into::<usize>(), |v| {
272 assert!(v < 10);
273 Ok(())
274 })
275 .unwrap();
276 }
277
278 #[test]
279 fn perturb_uses_same_rng_every_time() {
280 let mut runner = TestRunner::default();
281 let input = Just(1).prop_perturb(|v, mut rng| v + rng.next_u32());
282
283 for _ in 0..16 {
284 let value = input.new_tree(&mut runner).unwrap();
285 assert_eq!(value.current(), value.current());
286 }
287 }
288
289 #[test]
290 fn perturb_uses_varying_random_seeds() {
291 let mut runner = TestRunner::default();
292 let input = Just(1).prop_perturb(|v, mut rng| v + rng.next_u32());
293
294 let mut seen = HashSet::new();
295 for _ in 0..64 {
296 seen.insert(input.new_tree(&mut runner).unwrap().current());
297 }
298
299 assert_eq!(64, seen.len());
300 }
301}