quickcheck/
arbitrary.rs

1use std::char;
2use std::collections::{
3    BTreeMap,
4    BTreeSet,
5    BinaryHeap,
6    HashMap,
7    HashSet,
8    LinkedList,
9    VecDeque,
10};
11use std::hash::Hash;
12use std::iter::{empty, once};
13use std::ops::{Range, RangeFrom, RangeTo, RangeFull};
14use std::time::Duration;
15
16use rand::Rng;
17
18/// `Gen` wraps a `rand::Rng` with parameters to control the distribution of
19/// random values.
20///
21/// A value with type satisfying the `Gen` trait can be constructed with the
22/// `gen` function in this crate.
23pub trait Gen : Rng {
24    fn size(&self) -> usize;
25}
26
27/// StdGen is the default implementation of `Gen`.
28///
29/// Values of type `StdGen` can be created with the `gen` function in this
30/// crate.
31pub struct StdGen<R> {
32    rng: R,
33    size: usize,
34}
35
36/// Returns a `StdGen` with the given configuration using any random number
37/// generator.
38///
39/// The `size` parameter controls the size of random values generated.
40/// For example, it specifies the maximum length of a randomly generated vector
41/// and also will specify the maximum magnitude of a randomly generated number.
42impl<R: Rng> StdGen<R> {
43    pub fn new(rng: R, size: usize) -> StdGen<R> {
44        StdGen { rng: rng, size: size }
45    }
46}
47
48impl<R: Rng> Rng for StdGen<R> {
49    fn next_u32(&mut self) -> u32 { self.rng.next_u32() }
50
51    // some RNGs implement these more efficiently than the default, so
52    // we might as well defer to them.
53    fn next_u64(&mut self) -> u64 { self.rng.next_u64() }
54    fn fill_bytes(&mut self, dest: &mut [u8]) { self.rng.fill_bytes(dest) }
55}
56
57impl<R: Rng> Gen for StdGen<R> {
58    fn size(&self) -> usize { self.size }
59}
60
61/// Creates a shrinker with zero elements.
62pub fn empty_shrinker<A: 'static>() -> Box<Iterator<Item=A>> {
63    Box::new(empty())
64}
65
66/// Creates a shrinker with a single element.
67pub fn single_shrinker<A: 'static>(value: A) -> Box<Iterator<Item=A>> {
68    Box::new(once(value))
69}
70
71/// `Arbitrary` describes types whose values can be randomly generated and
72/// shrunk.
73///
74/// Aside from shrinking, `Arbitrary` is different from the `std::Rand` trait
75/// in that it uses a `Gen` to control the distribution of random values.
76///
77/// As of now, all types that implement `Arbitrary` must also implement
78/// `Clone`. (I'm not sure if this is a permanent restriction.)
79///
80/// They must also be sendable and static since every test is run in its own
81/// thread using `thread::Builder::spawn`, which requires the `Send + 'static`
82/// bounds.
83pub trait Arbitrary : Clone + Send + 'static {
84    fn arbitrary<G: Gen>(g: &mut G) -> Self;
85
86    fn shrink(&self) -> Box<Iterator<Item=Self>> {
87        empty_shrinker()
88    }
89}
90
91impl Arbitrary for () {
92    fn arbitrary<G: Gen>(_: &mut G) -> () { () }
93}
94
95impl Arbitrary for bool {
96    fn arbitrary<G: Gen>(g: &mut G) -> bool { g.gen() }
97
98    fn shrink(&self) -> Box<Iterator<Item=bool>> {
99        if *self {
100            single_shrinker(false)
101        }
102        else {
103            empty_shrinker()
104        }
105    }
106}
107
108impl<A: Arbitrary> Arbitrary for Option<A> {
109    fn arbitrary<G: Gen>(g: &mut G) -> Option<A> {
110        if g.gen() {
111            None
112        } else {
113            Some(Arbitrary::arbitrary(g))
114        }
115    }
116
117    fn shrink(&self)  -> Box<Iterator<Item=Option<A>>> {
118        match *self {
119            None => empty_shrinker(),
120            Some(ref x) => {
121                let chain = single_shrinker(None).chain(x.shrink().map(Some));
122                Box::new(chain)
123            }
124        }
125    }
126}
127
128impl<A: Arbitrary, B: Arbitrary> Arbitrary for Result<A, B> {
129    fn arbitrary<G: Gen>(g: &mut G) -> Result<A, B> {
130        if g.gen() {
131            Ok(Arbitrary::arbitrary(g))
132        } else {
133            Err(Arbitrary::arbitrary(g))
134        }
135    }
136
137    fn shrink(&self) -> Box<Iterator<Item=Result<A, B>>> {
138        match *self {
139            Ok(ref x) => {
140                let xs = x.shrink();
141                let tagged = xs.map(Ok);
142                Box::new(tagged)
143            }
144            Err(ref x) => {
145                let xs = x.shrink();
146                let tagged = xs.map(Err);
147                Box::new(tagged)
148            }
149        }
150    }
151}
152
153macro_rules! impl_arb_for_tuple {
154    (($var_a:ident, $type_a:ident) $(, ($var_n:ident, $type_n:ident))*) => (
155        impl<$type_a: Arbitrary, $($type_n: Arbitrary),*> Arbitrary
156                for ($type_a, $($type_n),*) {
157            fn arbitrary<GEN: Gen>(g: &mut GEN) -> ($type_a, $($type_n),*) {
158                (
159                    Arbitrary::arbitrary(g),
160                    $({
161                        $type_n::arbitrary(g)
162                    },
163                    )*
164                )
165            }
166
167            fn shrink(&self)
168                     -> Box<Iterator<Item=($type_a, $($type_n),*)>> {
169                let (ref $var_a, $(ref $var_n),*) = *self;
170                let sa = $var_a.shrink().scan(
171                    ($($var_n.clone(),)*),
172                    |&mut ($(ref $var_n,)*), $var_a|
173                        Some(($var_a, $($var_n.clone(),)*))
174                );
175                let srest = ($($var_n.clone(),)*).shrink()
176                    .scan($var_a.clone(), |$var_a, ($($var_n,)*)|
177                        Some(($var_a.clone(), $($var_n,)*))
178                    );
179                Box::new(sa.chain(srest))
180            }
181        }
182    );
183}
184
185impl_arb_for_tuple!((a, A));
186impl_arb_for_tuple!((a, A), (b, B));
187impl_arb_for_tuple!((a, A), (b, B), (c, C));
188impl_arb_for_tuple!((a, A), (b, B), (c, C), (d, D));
189impl_arb_for_tuple!((a, A), (b, B), (c, C), (d, D), (e, E));
190impl_arb_for_tuple!((a, A), (b, B), (c, C), (d, D), (e, E), (f, F));
191impl_arb_for_tuple!((a, A), (b, B), (c, C), (d, D), (e, E), (f, F),
192                    (g, G));
193impl_arb_for_tuple!((a, A), (b, B), (c, C), (d, D), (e, E), (f, F),
194                    (g, G), (h, H));
195impl_arb_for_tuple!((a, A), (b, B), (c, C), (d, D), (e, E), (f, F),
196                    (g, G), (h, H), (i, I));
197impl_arb_for_tuple!((a, A), (b, B), (c, C), (d, D), (e, E), (f, F),
198                    (g, G), (h, H), (i, I), (j, J));
199impl_arb_for_tuple!((a, A), (b, B), (c, C), (d, D), (e, E), (f, F),
200                    (g, G), (h, H), (i, I), (j, J), (k, K));
201impl_arb_for_tuple!((a, A), (b, B), (c, C), (d, D), (e, E), (f, F),
202                    (g, G), (h, H), (i, I), (j, J), (k, K), (l, L));
203
204impl<A: Arbitrary> Arbitrary for Vec<A> {
205    fn arbitrary<G: Gen>(g: &mut G) -> Vec<A> {
206        let size = { let s = g.size(); g.gen_range(0, s) };
207        (0..size).map(|_| Arbitrary::arbitrary(g)).collect()
208    }
209
210    fn shrink(&self) -> Box<Iterator<Item=Vec<A>>> {
211        VecShrinker::new(self.clone())
212    }
213}
214
215///Iterator which returns successive attempts to shrink the vector `seed`
216struct VecShrinker<A> {
217    seed: Vec<A>,
218    /// How much which is removed when trying with smaller vectors
219    size: usize,
220    /// The end of the removed elements
221    offset: usize,
222    /// The shrinker for the element at `offset` once shrinking of individual
223    /// elements are attempted
224    element_shrinker: Box<Iterator<Item=A>>
225}
226
227impl <A: Arbitrary> VecShrinker<A> {
228
229    fn new(seed: Vec<A>) -> Box<Iterator<Item=Vec<A>>> {
230        let es = match seed.get(0) {
231            Some(e) => e.shrink(),
232            None => return empty_shrinker()
233        };
234        let size = seed.len();
235        Box::new(VecShrinker {
236            seed: seed,
237            size: size,
238            offset: size,
239            element_shrinker: es,
240        })
241    }
242
243    /// Returns the next shrunk element if any, `offset` points to the index
244    /// after the returned element after the function returns
245    fn next_element(&mut self) -> Option<A> {
246        loop {
247            match self.element_shrinker.next() {
248                Some(e) => return Some(e),
249                None => {
250                    match self.seed.get(self.offset) {
251                        Some(e) => {
252                            self.element_shrinker = e.shrink();
253                            self.offset += 1;
254                        }
255                        None => return None
256                    }
257                }
258            }
259        }
260    }
261}
262
263impl <A> Iterator for VecShrinker<A>
264    where A: Arbitrary {
265    type Item = Vec<A>;
266    fn next(&mut self) -> Option<Vec<A>> {
267        // Try with an empty vector first
268        if self.size == self.seed.len() {
269            self.size /= 2;
270            self.offset = self.size;
271            return Some(vec![])
272        }
273        if self.size != 0 {
274            // Generate a smaller vector by removing the elements between
275            // (offset - size) and offset
276            let xs1 = self.seed[..(self.offset - self.size)].iter()
277                .chain(&self.seed[self.offset..])
278                .cloned()
279                .collect();
280            self.offset += self.size;
281            // Try to reduce the amount removed from the vector once all
282            // previous sizes tried
283            if self.offset > self.seed.len() {
284                self.size /= 2;
285                self.offset = self.size;
286            }
287            Some(xs1)
288        }
289        else {
290            // A smaller vector did not work so try to shrink each element of
291            // the vector instead Reuse `offset` as the index determining which
292            // element to shrink
293
294            // The first element shrinker is already created so skip the first
295            // offset (self.offset == 0 only on first entry to this part of the
296            // iterator)
297            if self.offset == 0 { self.offset = 1 }
298
299            match self.next_element() {
300                Some(e) => Some(self.seed[..self.offset-1].iter().cloned()
301                    .chain(Some(e).into_iter())
302                    .chain(self.seed[self.offset..].iter().cloned())
303                    .collect()),
304                None => None
305            }
306        }
307    }
308}
309
310impl<K: Arbitrary + Ord, V: Arbitrary> Arbitrary for BTreeMap<K, V> {
311    fn arbitrary<G: Gen>(g: &mut G) -> BTreeMap<K, V> {
312        let vec: Vec<(K, V)> = Arbitrary::arbitrary(g);
313        vec.into_iter().collect()
314    }
315
316    fn shrink(&self) -> Box<Iterator<Item=BTreeMap<K, V>>> {
317        let vec: Vec<(K, V)> = self.clone().into_iter().collect();
318        Box::new(vec.shrink()
319                    .map(|v| v.into_iter().collect::<BTreeMap<K, V>>()))
320    }
321}
322
323impl<K: Arbitrary + Eq + Hash, V: Arbitrary> Arbitrary for HashMap<K, V> {
324    fn arbitrary<G: Gen>(g: &mut G) -> HashMap<K, V> {
325        let vec: Vec<(K, V)> = Arbitrary::arbitrary(g);
326        vec.into_iter().collect()
327    }
328
329    fn shrink(&self) -> Box<Iterator<Item=HashMap<K, V>>> {
330        let vec: Vec<(K, V)> = self.clone().into_iter().collect();
331        Box::new(vec.shrink()
332                    .map(|v| v.into_iter().collect::<HashMap<K, V>>()))
333    }
334}
335
336impl<T: Arbitrary + Ord> Arbitrary for BTreeSet<T> {
337    fn arbitrary<G: Gen>(g: &mut G) -> BTreeSet<T> {
338        let vec: Vec<T> = Arbitrary::arbitrary(g);
339        vec.into_iter().collect()
340    }
341
342    fn shrink(&self) -> Box<Iterator<Item=BTreeSet<T>>> {
343        let vec: Vec<T> = self.clone().into_iter().collect();
344        Box::new(vec.shrink().map(|v| v.into_iter().collect::<BTreeSet<T>>()))
345    }
346}
347
348impl<T: Arbitrary + Ord> Arbitrary for BinaryHeap<T> {
349    fn arbitrary<G: Gen>(g: &mut G) -> BinaryHeap<T> {
350        let vec: Vec<T> = Arbitrary::arbitrary(g);
351        vec.into_iter().collect()
352    }
353
354    fn shrink(&self) -> Box<Iterator<Item=BinaryHeap<T>>> {
355        let vec: Vec<T> = self.clone().into_iter().collect();
356        Box::new(vec.shrink()
357                    .map(|v| v.into_iter().collect::<BinaryHeap<T>>()))
358    }
359}
360
361impl<T: Arbitrary + Eq + Hash> Arbitrary for HashSet<T> {
362    fn arbitrary<G: Gen>(g: &mut G) -> HashSet<T> {
363        let vec: Vec<T> = Arbitrary::arbitrary(g);
364        vec.into_iter().collect()
365    }
366
367    fn shrink(&self) -> Box<Iterator<Item=HashSet<T>>> {
368        let vec: Vec<T> = self.clone().into_iter().collect();
369        Box::new(vec.shrink().map(|v| v.into_iter().collect::<HashSet<T>>()))
370    }
371}
372
373impl<T: Arbitrary> Arbitrary for LinkedList<T> {
374    fn arbitrary<G: Gen>(g: &mut G) -> LinkedList<T> {
375        let vec: Vec<T> = Arbitrary::arbitrary(g);
376        vec.into_iter().collect()
377    }
378
379    fn shrink(&self) -> Box<Iterator<Item=LinkedList<T>>> {
380        let vec: Vec<T> = self.clone().into_iter().collect();
381        Box::new(vec.shrink()
382                    .map(|v| v.into_iter().collect::<LinkedList<T>>()))
383    }
384}
385
386impl<T: Arbitrary> Arbitrary for VecDeque<T> {
387    fn arbitrary<G: Gen>(g: &mut G) -> VecDeque<T> {
388        let vec: Vec<T> = Arbitrary::arbitrary(g);
389        vec.into_iter().collect()
390    }
391
392    fn shrink(&self) -> Box<Iterator<Item=VecDeque<T>>> {
393        let vec: Vec<T> = self.clone().into_iter().collect();
394        Box::new(vec.shrink()
395                    .map(|v| v.into_iter().collect::<VecDeque<T>>()))
396    }
397}
398
399impl Arbitrary for String {
400    fn arbitrary<G: Gen>(g: &mut G) -> String {
401        let size = { let s = g.size(); g.gen_range(0, s) };
402        let mut s = String::with_capacity(size);
403        for _ in 0..size {
404            s.push(char::arbitrary(g));
405        }
406        s
407    }
408
409    fn shrink(&self) -> Box<Iterator<Item=String>> {
410        // Shrink a string by shrinking a vector of its characters.
411        let chars: Vec<char> = self.chars().collect();
412        Box::new(chars.shrink().map(|x| x.into_iter().collect::<String>()))
413    }
414}
415
416impl Arbitrary for char {
417    fn arbitrary<G: Gen>(g: &mut G) -> char {
418        let mode = g.gen_range(0, 100);
419        match mode {
420            0...49 => {
421                // ASCII + some control characters
422                g.gen_range(0,0xB0) as u8 as char
423            }
424            50...59 => {
425                // Unicode BMP characters
426                loop {
427                    if let Some(x) = char::from_u32(g.gen_range(0, 0x10000)) {
428                        return x
429                    }
430                    // ignore surrogate pairs
431                }
432            }
433            60...84 => {
434                // Characters often used in programming languages
435                *g.choose(&[
436                    ' ', ' ', ' ',
437                    '\t',
438                    '\n',
439                    '~', '`', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')',
440                    '_', '-', '=', '+','[', ']', '{', '}',':',';','\'','"','\\',
441                    '|',',','<','>','.','/','?',
442                    '0', '1','2','3','4','5','6','7','8','9',
443                ]).unwrap()
444            }
445            85...89 => {
446                // Tricky Unicode, part 1
447                *g.choose(&[
448                    '\u{0149}', // a deprecated character
449                    '\u{fff0}', // some of "Other, format" category:
450                    '\u{fff1}','\u{fff2}','\u{fff3}','\u{fff4}','\u{fff5}',
451                    '\u{fff6}','\u{fff7}','\u{fff8}','\u{fff9}','\u{fffA}',
452                    '\u{fffB}','\u{fffC}','\u{fffD}','\u{fffE}','\u{fffF}',
453                    '\u{0600}','\u{0601}','\u{0602}','\u{0603}',
454                    '\u{0604}','\u{0605}','\u{061C}',
455                    '\u{06DD}','\u{070F}','\u{180E}',
456                    '\u{110BD}', '\u{1D173}',
457                    '\u{e0001}', // tag
458                    '\u{e0020}',//  tag space
459                    '\u{e000}', '\u{e001}', '\u{ef8ff}', // private use
460                    '\u{f0000}', '\u{ffffd}','\u{ffffe}', '\u{fffff}',
461                    '\u{100000}','\u{10FFFD}','\u{10FFFE}','\u{10FFFF}',
462                    // "Other, surrogate" characters are so that very special
463                    // that they are not even allowed in safe Rust,
464                    //so omitted here
465                    '\u{3000}', // ideographic space
466                    '\u{1680}',
467                    // other space characters are already covered by two next
468                    // branches
469                ]).unwrap()
470            }
471            90...94 => {
472                // Tricky unicode, part 2
473                char::from_u32(g.gen_range(0x2000, 0x2070)).unwrap()
474            }
475            95...99 => {
476                // Completely arbitrary characters
477                g.gen()
478            }
479            _ => unreachable!()
480        }
481    }
482
483    fn shrink(&self) -> Box<Iterator<Item=char>> {
484        Box::new((*self as u32).shrink().filter_map(char::from_u32))
485    }
486}
487
488macro_rules! unsigned_shrinker {
489    ($ty:ty) => {
490        mod shrinker {
491            pub struct UnsignedShrinker {
492                x: $ty,
493                i: $ty,
494            }
495
496            impl UnsignedShrinker {
497                pub fn new(x: $ty) -> Box<Iterator<Item=$ty>> {
498                    if x == 0 {
499                        super::empty_shrinker()
500                    } else {
501                        Box::new(vec![0].into_iter().chain(
502                            UnsignedShrinker {
503                                x: x,
504                                i: x / 2,
505                            }
506                        ))
507                    }
508                }
509            }
510
511            impl Iterator for UnsignedShrinker {
512                type Item = $ty;
513                fn next(&mut self) -> Option<$ty> {
514                    if self.x - self.i < self.x {
515                        let result = Some(self.x - self.i);
516                        self.i = self.i / 2;
517                        result
518                    } else {
519                        None
520                    }
521                }
522            }
523        }
524    }
525}
526
527macro_rules! unsigned_arbitrary {
528    ($($ty:ty),*) => {
529        $(
530            impl Arbitrary for $ty {
531                fn arbitrary<G: Gen>(g: &mut G) -> $ty {
532                    #![allow(trivial_numeric_casts)]
533                    let mut s = g.size() as $ty;
534                    if s == 0 {
535                        s = s + 1;
536                    }
537                    g.gen_range(0, s)
538                }
539                fn shrink(&self) -> Box<Iterator<Item=$ty>> {
540                    unsigned_shrinker!($ty);
541                    shrinker::UnsignedShrinker::new(*self)
542                }
543            }
544        )*
545    }
546}
547
548unsigned_arbitrary! {
549    usize, u8, u16, u32, u64
550}
551
552macro_rules! signed_shrinker {
553    ($ty:ty) => {
554        mod shrinker {
555            pub struct SignedShrinker {
556                x: $ty,
557                i: $ty,
558            }
559
560            impl SignedShrinker {
561                pub fn new(x: $ty) -> Box<Iterator<Item=$ty>> {
562                    if x == 0 {
563                        super::empty_shrinker()
564                    } else {
565                        let shrinker = SignedShrinker {
566                            x: x,
567                            i: x / 2,
568                        };
569                        let mut items = vec![0];
570                        if shrinker.i < 0 {
571                            items.push(shrinker.x.abs());
572                        }
573                        Box::new(items.into_iter().chain(shrinker))
574                    }
575                }
576            }
577
578            impl Iterator for SignedShrinker {
579                type Item = $ty;
580                fn next(&mut self) -> Option<$ty> {
581                    if (self.x - self.i).abs() < self.x.abs() {
582                        let result = Some(self.x - self.i);
583                        self.i = self.i / 2;
584                        result
585                    } else {
586                        None
587                    }
588                }
589            }
590        }
591    }
592}
593
594macro_rules! signed_arbitrary {
595    ($($ty:ty),*) => {
596        $(
597            impl Arbitrary for $ty {
598                fn arbitrary<G: Gen>(g: &mut G) -> $ty {
599                    let s = g.size() as $ty;
600                    g.gen_range(-s, if s == 0 { 1 } else { s })
601                }
602                fn shrink(&self) -> Box<Iterator<Item=$ty>> {
603                    signed_shrinker!($ty);
604                    shrinker::SignedShrinker::new(*self)
605                }
606            }
607        )*
608    }
609}
610
611signed_arbitrary! {
612    isize, i8, i16, i32, i64
613}
614
615impl Arbitrary for f32 {
616    fn arbitrary<G: Gen>(g: &mut G) -> f32 {
617        let s = g.size(); g.gen_range(-(s as f32), s as f32)
618    }
619    fn shrink(&self) -> Box<Iterator<Item=f32>> {
620        signed_shrinker!(i32);
621        let it = shrinker::SignedShrinker::new(*self as i32);
622        Box::new(it.map(|x| x as f32))
623    }
624}
625
626impl Arbitrary for f64 {
627    fn arbitrary<G: Gen>(g: &mut G) -> f64 {
628        let s = g.size(); g.gen_range(-(s as f64), s as f64)
629    }
630    fn shrink(&self) -> Box<Iterator<Item=f64>> {
631        signed_shrinker!(i64);
632        let it = shrinker::SignedShrinker::new(*self as i64);
633        Box::new(it.map(|x| x as f64))
634    }
635}
636
637impl<T: Arbitrary + Clone + PartialOrd> Arbitrary for Range<T> {
638    fn arbitrary<G: Gen>(g: &mut G) -> Range<T> {
639        Arbitrary::arbitrary(g) .. Arbitrary::arbitrary(g)
640    }
641    fn shrink(&self) -> Box<Iterator<Item=Range<T>>> {
642        Box::new(
643            (self.start.clone(), self.end.clone())
644            .shrink().map(|(s, e)| s .. e))
645    }
646}
647
648impl<T: Arbitrary + Clone + PartialOrd> Arbitrary for RangeFrom<T> {
649    fn arbitrary<G: Gen>(g: &mut G) -> RangeFrom<T> {
650        Arbitrary::arbitrary(g) ..
651    }
652    fn shrink(&self) -> Box<Iterator<Item=RangeFrom<T>>> {
653        Box::new(self.start.clone().shrink().map(|start| start ..))
654    }
655}
656
657impl<T: Arbitrary + Clone + PartialOrd> Arbitrary for RangeTo<T> {
658    fn arbitrary<G: Gen>(g: &mut G) -> RangeTo<T> {
659        .. Arbitrary::arbitrary(g)
660    }
661    fn shrink(&self) -> Box<Iterator<Item=RangeTo<T>>> {
662        Box::new(self.end.clone().shrink().map(|end| ..end))
663    }
664}
665
666impl Arbitrary for RangeFull {
667    fn arbitrary<G: Gen>(_: &mut G) -> RangeFull { .. }
668}
669
670impl Arbitrary for Duration {
671    fn arbitrary<G: Gen>(gen: &mut G) -> Self {
672        let seconds = u64::arbitrary(gen);
673        let nanoseconds = u32::arbitrary(gen) % 1_000_000;
674        Duration::new(seconds, nanoseconds)
675    }
676
677    fn shrink(&self) -> Box<Iterator<Item=Self>> {
678        Box::new((self.as_secs(), self.subsec_nanos()).shrink()
679            .map(|(secs, nanos)| {
680                Duration::new(secs, nanos % 1_000_000)
681            }))
682    }
683}
684
685
686#[cfg(feature = "unstable")]
687mod unstable_impls {
688    use {Arbitrary, Gen};
689    use std::time::{Duration, SystemTime, UNIX_EPOCH};
690
691    impl Arbitrary for SystemTime {
692        fn arbitrary<G: Gen>(gen: &mut G) -> Self {
693            let after_epoch = bool::arbitrary(gen);
694            let duration = Duration::arbitrary(gen);
695            if after_epoch {
696                UNIX_EPOCH + duration
697            } else {
698                UNIX_EPOCH - duration
699            }
700        }
701
702        fn shrink(&self) -> Box<Iterator<Item=Self>> {
703            let duration = match self.duration_since(UNIX_EPOCH) {
704                Ok(duration) => duration,
705                Err(e) => e.duration(),
706            };
707            Box::new(duration.shrink().flat_map(|d| {
708                vec![UNIX_EPOCH + d, UNIX_EPOCH - d]
709            }))
710        }
711    }
712}
713
714#[cfg(test)]
715mod test {
716    use rand;
717    use std::collections::{
718        BTreeMap,
719        BTreeSet,
720        BinaryHeap,
721        HashMap,
722        HashSet,
723        LinkedList,
724        VecDeque,
725    };
726    use std::fmt::Debug;
727    use std::hash::Hash;
728    use super::Arbitrary;
729
730    #[test]
731    fn arby_unit() {
732        assert_eq!(arby::<()>(), ());
733    }
734
735    #[test]
736    fn arby_int() {
737        rep(&mut || { let n: isize = arby(); assert!(n >= -5 && n <= 5); } );
738    }
739
740    #[test]
741    fn arby_uint() {
742        rep(&mut || { let n: usize = arby(); assert!(n <= 5); } );
743    }
744
745    fn arby<A: super::Arbitrary>() -> A {
746        super::Arbitrary::arbitrary(&mut gen())
747    }
748
749    fn gen() -> super::StdGen<rand::ThreadRng> {
750        super::StdGen::new(rand::thread_rng(), 5)
751    }
752
753    fn rep<F>(f: &mut F) where F : FnMut() -> () {
754        for _ in 0..100 {
755            f()
756        }
757    }
758
759    // Shrink testing.
760    #[test]
761    fn unit() {
762        eq((), vec![]);
763    }
764
765    #[test]
766    fn bools() {
767        eq(false, vec![]);
768        eq(true, vec![false]);
769    }
770
771    #[test]
772    fn options() {
773        eq(None::<()>, vec![]);
774        eq(Some(false), vec![None]);
775        eq(Some(true), vec![None, Some(false)]);
776    }
777
778    #[test]
779    fn results() {
780        // Result<A, B> doesn't implement the Hash trait, so these tests
781        // depends on the order of shrunk results. Ug.
782        // TODO: Fix this.
783        ordered_eq(Ok::<bool, ()>(true), vec![Ok(false)]);
784        ordered_eq(Err::<(), bool>(true), vec![Err(false)]);
785    }
786
787    #[test]
788    fn tuples() {
789        eq((false, false), vec![]);
790        eq((true, false), vec![(false, false)]);
791        eq((true, true), vec![(false, true), (true, false)]);
792    }
793
794    #[test]
795    fn triples() {
796        eq((false, false, false), vec![]);
797        eq((true, false, false), vec![(false, false, false)]);
798        eq((true, true, false),
799           vec![(false, true, false), (true, false, false)]);
800    }
801
802    #[test]
803    fn quads() {
804        eq((false, false, false, false), vec![]);
805        eq((true, false, false, false), vec![(false, false, false, false)]);
806        eq((true, true, false, false),
807            vec![(false, true, false, false), (true, false, false, false)]);
808    }
809
810    #[test]
811    fn ints() {
812        // TODO: Test overflow?
813        eq(5isize, vec![0, 3, 4]);
814        eq(-5isize, vec![5, 0, -3, -4]);
815        eq(0isize, vec![]);
816    }
817
818    #[test]
819    fn ints8() {
820        eq(5i8, vec![0, 3, 4]);
821        eq(-5i8, vec![5, 0, -3, -4]);
822        eq(0i8, vec![]);
823    }
824
825    #[test]
826    fn ints16() {
827        eq(5i16, vec![0, 3, 4]);
828        eq(-5i16, vec![5, 0, -3, -4]);
829        eq(0i16, vec![]);
830    }
831
832    #[test]
833    fn ints32() {
834        eq(5i32, vec![0, 3, 4]);
835        eq(-5i32, vec![5, 0, -3, -4]);
836        eq(0i32, vec![]);
837    }
838
839    #[test]
840    fn ints64() {
841        eq(5i64, vec![0, 3, 4]);
842        eq(-5i64, vec![5, 0, -3, -4]);
843        eq(0i64, vec![]);
844    }
845
846    #[test]
847    fn uints() {
848        eq(5usize, vec![0, 3, 4]);
849        eq(0usize, vec![]);
850    }
851
852    #[test]
853    fn uints8() {
854        eq(5u8, vec![0, 3, 4]);
855        eq(0u8, vec![]);
856    }
857
858    #[test]
859    fn uints16() {
860        eq(5u16, vec![0, 3, 4]);
861        eq(0u16, vec![]);
862    }
863
864    #[test]
865    fn uints32() {
866        eq(5u32, vec![0, 3, 4]);
867        eq(0u32, vec![]);
868    }
869
870    #[test]
871    fn uints64() {
872        eq(5u64, vec![0, 3, 4]);
873        eq(0u64, vec![]);
874    }
875
876    #[test]
877    fn vecs() {
878        eq({let it: Vec<isize> = vec![]; it}, vec![]);
879        eq({let it: Vec<Vec<isize>> = vec![vec![]]; it}, vec![vec![]]);
880        eq(vec![1isize], vec![vec![], vec![0]]);
881        eq(vec![11isize], vec![vec![], vec![0], vec![6], vec![9], vec![10]]);
882        eq(
883            vec![3isize, 5],
884            vec![vec![], vec![5], vec![3], vec![0,5], vec![2,5],
885                 vec![3,0], vec![3,3], vec![3,4]]
886        );
887    }
888
889    macro_rules! map_tests {
890        ($name:ident, $ctor:expr) => {
891            #[test]
892            fn $name() {
893                ordered_eq($ctor, vec![]);
894
895                {
896                    let mut map = $ctor;
897                    map.insert(1usize, 1isize);
898
899                    let shrinks = vec![
900                        $ctor,
901                        {let mut m = $ctor; m.insert(0, 1); m},
902                        {let mut m = $ctor; m.insert(1, 0); m},
903                    ];
904
905                    ordered_eq(map, shrinks);
906                }
907            }
908        }
909    }
910
911    map_tests!(btreemap, BTreeMap::<usize, isize>::new());
912    map_tests!(hashmap, HashMap::<usize, isize>::new());
913
914    macro_rules! list_tests {
915        ($name:ident, $ctor:expr, $push:ident) => {
916            #[test]
917            fn $name() {
918                ordered_eq($ctor, vec![]);
919
920                {
921                    let mut list = $ctor;
922                    list.$push(2usize);
923
924                    let shrinks = vec![
925                        $ctor,
926                        {let mut m = $ctor; m.$push(0); m},
927                        {let mut m = $ctor; m.$push(1); m},
928                    ];
929
930                    ordered_eq(list, shrinks);
931                }
932            }
933        }
934    }
935
936    list_tests!(btreesets, BTreeSet::<usize>::new(), insert);
937    list_tests!(hashsets, HashSet::<usize>::new(), insert);
938    list_tests!(linkedlists, LinkedList::<usize>::new(), push_back);
939    list_tests!(vecdeques, VecDeque::<usize>::new(), push_back);
940
941    #[test]
942    fn binaryheaps() {
943        ordered_eq(
944            BinaryHeap::<usize>::new().into_iter().collect::<Vec<_>>(),
945            vec![]);
946
947        {
948            let mut heap = BinaryHeap::<usize>::new();
949            heap.push(2usize);
950
951            let shrinks = vec![
952                vec![],
953                vec![0],
954                vec![1],
955            ];
956
957            ordered_eq(heap.into_iter().collect::<Vec<_>>(), shrinks);
958        }
959    }
960
961    #[test]
962    fn chars() {
963        eq('\x00', vec![]);
964    }
965
966    // All this jazz is for testing set equality on the results of a shrinker.
967    fn eq<A: Arbitrary + Eq + Debug + Hash>(s: A, v: Vec<A>) {
968        let (left, right) = (shrunk(s), set(v));
969        assert_eq!(left, right);
970    }
971    fn shrunk<A: Arbitrary + Eq + Hash>(s: A) -> HashSet<A> {
972        set(s.shrink().collect())
973    }
974    fn set<A: Eq + Hash>(xs: Vec<A>) -> HashSet<A> {
975        xs.into_iter().collect()
976    }
977
978    fn ordered_eq<A: Arbitrary + Eq + Debug>(s: A, v: Vec<A>) {
979        let (left, right) = (s.shrink().collect::<Vec<A>>(), v);
980        assert_eq!(left, right);
981    }
982
983    #[test]
984    fn ranges() {
985        ordered_eq(0..0, vec![]);
986        ordered_eq(1..1, vec![0..1, 1..0]);
987        ordered_eq(3..5, vec![0..5, 2..5, 3..0, 3..3, 3..4]);
988        ordered_eq(5..3, vec![0..3, 3..3, 4..3, 5..0, 5..2]);
989        ordered_eq(3.., vec![0.., 2..]);
990        ordered_eq(..3, vec![..0, ..2]);
991        ordered_eq(.., vec![]);
992    }
993}