1 //! The purpose of these tests is to cover corner cases of iterators
2 //! and adaptors.
3 //!
4 //! In particular we test the tedious size_hint and exact size correctness.
5 
6 #[macro_use] extern crate itertools;
7 
8 extern crate quickcheck;
9 extern crate rand;
10 
11 use std::default::Default;
12 
13 use quickcheck as qc;
14 use std::ops::Range;
15 use std::cmp::{max, min, Ordering};
16 use std::collections::HashSet;
17 use itertools::Itertools;
18 use itertools::{
19     multizip,
20     EitherOrBoth,
21 };
22 use itertools::free::{
23     cloned,
24     enumerate,
25     multipeek,
26     put_back,
27     put_back_n,
28     rciter,
29     zip,
30     zip_eq,
31 };
32 
33 use rand::Rng;
34 use rand::seq::SliceRandom;
35 use quickcheck::TestResult;
36 
37 /// Trait for size hint modifier types
38 trait HintKind: Copy + Send + qc::Arbitrary {
loosen_bounds(&self, org_hint: (usize, Option<usize>)) -> (usize, Option<usize>)39     fn loosen_bounds(&self, org_hint: (usize, Option<usize>)) -> (usize, Option<usize>);
40 }
41 
42 /// Exact size hint variant that leaves hints unchanged
43 #[derive(Clone, Copy, Debug)]
44 struct Exact {}
45 
46 impl HintKind for Exact {
loosen_bounds(&self, org_hint: (usize, Option<usize>)) -> (usize, Option<usize>)47     fn loosen_bounds(&self, org_hint: (usize, Option<usize>)) -> (usize, Option<usize>) {
48         org_hint
49     }
50 }
51 
52 impl qc::Arbitrary for Exact {
arbitrary<G: qc::Gen>(_: &mut G) -> Self53     fn arbitrary<G: qc::Gen>(_: &mut G) -> Self {
54         Exact {}
55     }
56 }
57 
58 /// Inexact size hint variant to simulate imprecise (but valid) size hints
59 ///
60 /// Will always decrease the lower bound and increase the upper bound
61 /// of the size hint by set amounts.
62 #[derive(Clone, Copy, Debug)]
63 struct Inexact {
64     underestimate: usize,
65     overestimate: usize,
66 }
67 
68 impl HintKind for Inexact {
loosen_bounds(&self, org_hint: (usize, Option<usize>)) -> (usize, Option<usize>)69     fn loosen_bounds(&self, org_hint: (usize, Option<usize>)) -> (usize, Option<usize>) {
70         let (org_lower, org_upper) = org_hint;
71         (org_lower.saturating_sub(self.underestimate),
72          org_upper.and_then(move |x| x.checked_add(self.overestimate)))
73     }
74 }
75 
76 impl qc::Arbitrary for Inexact {
arbitrary<G: qc::Gen>(g: &mut G) -> Self77     fn arbitrary<G: qc::Gen>(g: &mut G) -> Self {
78         let ue_value = usize::arbitrary(g);
79         let oe_value = usize::arbitrary(g);
80         // Compensate for quickcheck using extreme values too rarely
81         let ue_choices = &[0, ue_value, usize::max_value()];
82         let oe_choices = &[0, oe_value, usize::max_value()];
83         Inexact {
84             underestimate: *ue_choices.choose(g).unwrap(),
85             overestimate: *oe_choices.choose(g).unwrap(),
86         }
87     }
88 
shrink(&self) -> Box<Iterator<Item=Self>>89     fn shrink(&self) -> Box<Iterator<Item=Self>> {
90         let underestimate_value = self.underestimate;
91         let overestimate_value = self.overestimate;
92         Box::new(
93             underestimate_value.shrink().flat_map(move |ue_value|
94                 overestimate_value.shrink().map(move |oe_value|
95                     Inexact {
96                         underestimate: ue_value,
97                         overestimate: oe_value,
98                     }
99                 )
100             )
101         )
102     }
103 }
104 
105 /// Our base iterator that we can impl Arbitrary for
106 ///
107 /// By default we'll return inexact bounds estimates for size_hint
108 /// to make tests harder to pass.
109 ///
110 /// NOTE: Iter is tricky and is not fused, to help catch bugs.
111 /// At the end it will return None once, then return Some(0),
112 /// then return None again.
113 #[derive(Clone, Debug)]
114 struct Iter<T, SK: HintKind = Inexact> {
115     iterator: Range<T>,
116     // fuse/done flag
117     fuse_flag: i32,
118     hint_kind: SK,
119 }
120 
121 impl<T, HK> Iter<T, HK> where HK: HintKind
122 {
new(it: Range<T>, hint_kind: HK) -> Self123     fn new(it: Range<T>, hint_kind: HK) -> Self {
124         Iter {
125             iterator: it,
126             fuse_flag: 0,
127             hint_kind: hint_kind
128         }
129     }
130 }
131 
132 impl<T, HK> Iterator for Iter<T, HK>
133     where Range<T>: Iterator,
134           <Range<T> as Iterator>::Item: Default,
135           HK: HintKind,
136 {
137     type Item = <Range<T> as Iterator>::Item;
138 
next(&mut self) -> Option<Self::Item>139     fn next(&mut self) -> Option<Self::Item>
140     {
141         let elt = self.iterator.next();
142         if elt.is_none() {
143             self.fuse_flag += 1;
144             // check fuse flag
145             if self.fuse_flag == 2 {
146                 return Some(Default::default())
147             }
148         }
149         elt
150     }
151 
size_hint(&self) -> (usize, Option<usize>)152     fn size_hint(&self) -> (usize, Option<usize>)
153     {
154         let org_hint = self.iterator.size_hint();
155         self.hint_kind.loosen_bounds(org_hint)
156     }
157 }
158 
159 impl<T, HK> DoubleEndedIterator for Iter<T, HK>
160     where Range<T>: DoubleEndedIterator,
161           <Range<T> as Iterator>::Item: Default,
162           HK: HintKind
163 {
next_back(&mut self) -> Option<Self::Item>164     fn next_back(&mut self) -> Option<Self::Item> { self.iterator.next_back() }
165 }
166 
167 impl<T> ExactSizeIterator for Iter<T, Exact> where Range<T>: ExactSizeIterator,
168     <Range<T> as Iterator>::Item: Default,
169 { }
170 
171 impl<T, HK> qc::Arbitrary for Iter<T, HK>
172     where T: qc::Arbitrary,
173           HK: HintKind,
174 {
arbitrary<G: qc::Gen>(g: &mut G) -> Self175     fn arbitrary<G: qc::Gen>(g: &mut G) -> Self
176     {
177         Iter::new(T::arbitrary(g)..T::arbitrary(g), HK::arbitrary(g))
178     }
179 
shrink(&self) -> Box<Iterator<Item=Iter<T, HK>>>180     fn shrink(&self) -> Box<Iterator<Item=Iter<T, HK>>>
181     {
182         let r = self.iterator.clone();
183         let hint_kind = self.hint_kind;
184         Box::new(
185             r.start.shrink().flat_map(move |a|
186                 r.end.shrink().map(move |b|
187                     Iter::new(a.clone()..b, hint_kind)
188                 )
189             )
190         )
191     }
192 }
193 
194 /// A meta-iterator which yields `Iter<i32>`s whose start/endpoints are
195 /// increased or decreased linearly on each iteration.
196 #[derive(Clone, Debug)]
197 struct ShiftRange<HK = Inexact> {
198     range_start: i32,
199     range_end: i32,
200     start_step: i32,
201     end_step: i32,
202     iter_count: u32,
203     hint_kind: HK,
204 }
205 
206 impl<HK> Iterator for ShiftRange<HK> where HK: HintKind {
207     type Item = Iter<i32, HK>;
208 
next(&mut self) -> Option<Self::Item>209     fn next(&mut self) -> Option<Self::Item> {
210         if self.iter_count == 0 {
211             return None;
212         }
213 
214         let iter = Iter::new(self.range_start..self.range_end, self.hint_kind);
215 
216         self.range_start += self.start_step;
217         self.range_end += self.end_step;
218         self.iter_count -= 1;
219 
220         Some(iter)
221     }
222 }
223 
224 impl ExactSizeIterator for ShiftRange<Exact> { }
225 
226 impl<HK> qc::Arbitrary for ShiftRange<HK>
227     where HK: HintKind
228 {
arbitrary<G: qc::Gen>(g: &mut G) -> Self229     fn arbitrary<G: qc::Gen>(g: &mut G) -> Self {
230         const MAX_STARTING_RANGE_DIFF: i32 = 32;
231         const MAX_STEP_MODULO: i32 = 8;
232         const MAX_ITER_COUNT: u32 = 3;
233 
234         let range_start = qc::Arbitrary::arbitrary(g);
235         let range_end = range_start + g.gen_range(0, MAX_STARTING_RANGE_DIFF + 1);
236         let start_step = g.gen_range(-MAX_STEP_MODULO, MAX_STEP_MODULO + 1);
237         let end_step = g.gen_range(-MAX_STEP_MODULO, MAX_STEP_MODULO + 1);
238         let iter_count = g.gen_range(0, MAX_ITER_COUNT + 1);
239         let hint_kind = qc::Arbitrary::arbitrary(g);
240 
241         ShiftRange {
242             range_start: range_start,
243             range_end: range_end,
244             start_step: start_step,
245             end_step: end_step,
246             iter_count: iter_count,
247             hint_kind: hint_kind
248         }
249     }
250 }
251 
correct_count<I, F>(get_it: F) -> bool where I: Iterator, F: Fn() -> I252 fn correct_count<I, F>(get_it: F) -> bool
253 where
254     I: Iterator,
255     F: Fn() -> I
256 {
257     let mut counts = vec![get_it().count()];
258 
259     'outer: loop {
260         let mut it = get_it();
261 
262         for _ in 0..(counts.len() - 1) {
263             if let None = it.next() {
264                 panic!("Iterator shouldn't be finished, may not be deterministic");
265             }
266         }
267 
268         if let None = it.next() {
269             break 'outer;
270         }
271 
272         counts.push(it.count());
273     }
274 
275     let total_actual_count = counts.len() - 1;
276 
277     for (i, returned_count) in counts.into_iter().enumerate() {
278         let actual_count = total_actual_count - i;
279         if actual_count != returned_count {
280             println!("Total iterations: {} True count: {} returned count: {}", i, actual_count, returned_count);
281 
282             return false;
283         }
284     }
285 
286     true
287 }
288 
correct_size_hint<I: Iterator>(mut it: I) -> bool289 fn correct_size_hint<I: Iterator>(mut it: I) -> bool {
290     // record size hint at each iteration
291     let initial_hint = it.size_hint();
292     let mut hints = Vec::with_capacity(initial_hint.0 + 1);
293     hints.push(initial_hint);
294     while let Some(_) = it.next() {
295         hints.push(it.size_hint())
296     }
297 
298     let mut true_count = hints.len(); // start off +1 too much
299 
300     // check all the size hints
301     for &(low, hi) in &hints {
302         true_count -= 1;
303         if low > true_count ||
304             (hi.is_some() && hi.unwrap() < true_count)
305         {
306             println!("True size: {:?}, size hint: {:?}", true_count, (low, hi));
307             //println!("All hints: {:?}", hints);
308             return false
309         }
310     }
311     true
312 }
313 
exact_size<I: ExactSizeIterator>(mut it: I) -> bool314 fn exact_size<I: ExactSizeIterator>(mut it: I) -> bool {
315     // check every iteration
316     let (mut low, mut hi) = it.size_hint();
317     if Some(low) != hi { return false; }
318     while let Some(_) = it.next() {
319         let (xlow, xhi) = it.size_hint();
320         if low != xlow + 1 { return false; }
321         low = xlow;
322         hi = xhi;
323         if Some(low) != hi { return false; }
324     }
325     let (low, hi) = it.size_hint();
326     low == 0 && hi == Some(0)
327 }
328 
329 // Exact size for this case, without ExactSizeIterator
exact_size_for_this<I: Iterator>(mut it: I) -> bool330 fn exact_size_for_this<I: Iterator>(mut it: I) -> bool {
331     // check every iteration
332     let (mut low, mut hi) = it.size_hint();
333     if Some(low) != hi { return false; }
334     while let Some(_) = it.next() {
335         let (xlow, xhi) = it.size_hint();
336         if low != xlow + 1 { return false; }
337         low = xlow;
338         hi = xhi;
339         if Some(low) != hi { return false; }
340     }
341     let (low, hi) = it.size_hint();
342     low == 0 && hi == Some(0)
343 }
344 
345 /*
346  * NOTE: Range<i8> is broken!
347  * (all signed ranges are)
348 #[quickcheck]
349 fn size_range_i8(a: Iter<i8>) -> bool {
350     exact_size(a)
351 }
352 
353 #[quickcheck]
354 fn size_range_i16(a: Iter<i16>) -> bool {
355     exact_size(a)
356 }
357 
358 #[quickcheck]
359 fn size_range_u8(a: Iter<u8>) -> bool {
360     exact_size(a)
361 }
362  */
363 
364 macro_rules! quickcheck {
365     // accept several property function definitions
366     // The property functions can use pattern matching and `mut` as usual
367     // in the function arguments, but the functions can not be generic.
368     {$($(#$attr:tt)* fn $fn_name:ident($($arg:tt)*) -> $ret:ty { $($code:tt)* })*} => (
369         $(
370             #[test]
371             $(#$attr)*
372             fn $fn_name() {
373                 fn prop($($arg)*) -> $ret {
374                     $($code)*
375                 }
376                 ::quickcheck::quickcheck(quickcheck!(@fn prop [] $($arg)*));
377             }
378         )*
379     );
380     // parse argument list (with patterns allowed) into prop as fn(_, _) -> _
381     (@fn $f:ident [$($t:tt)*]) => {
382         $f as fn($($t),*) -> _
383     };
384     (@fn $f:ident [$($p:tt)*] : $($tail:tt)*) => {
385         quickcheck!(@fn $f [$($p)* _] $($tail)*)
386     };
387     (@fn $f:ident [$($p:tt)*] $t:tt $($tail:tt)*) => {
388         quickcheck!(@fn $f [$($p)*] $($tail)*)
389     };
390 }
391 
392 quickcheck! {
393 
394     fn size_product(a: Iter<u16>, b: Iter<u16>) -> bool {
395         correct_size_hint(a.cartesian_product(b))
396     }
397     fn size_product3(a: Iter<u16>, b: Iter<u16>, c: Iter<u16>) -> bool {
398         correct_size_hint(iproduct!(a, b, c))
399     }
400 
401     fn correct_cartesian_product3(a: Iter<u16>, b: Iter<u16>, c: Iter<u16>,
402                                   take_manual: usize) -> ()
403     {
404         // test correctness of iproduct through regular iteration (take)
405         // and through fold.
406         let ac = a.clone();
407         let br = &b.clone();
408         let cr = &c.clone();
409         let answer: Vec<_> = ac.flat_map(move |ea| br.clone().flat_map(move |eb| cr.clone().map(move |ec| (ea, eb, ec)))).collect();
410         let mut product_iter = iproduct!(a, b, c);
411         let mut actual = Vec::new();
412 
413         actual.extend((&mut product_iter).take(take_manual));
414         if actual.len() == take_manual {
415             product_iter.fold((), |(), elt| actual.push(elt));
416         }
417         assert_eq!(answer, actual);
418     }
419 
420     fn size_multi_product(a: ShiftRange) -> bool {
421         correct_size_hint(a.multi_cartesian_product())
422     }
423     fn correct_multi_product3(a: ShiftRange, take_manual: usize) -> () {
424         // Fix no. of iterators at 3
425         let a = ShiftRange { iter_count: 3, ..a };
426 
427         // test correctness of MultiProduct through regular iteration (take)
428         // and through fold.
429         let mut iters = a.clone();
430         let i0 = iters.next().unwrap();
431         let i1r = &iters.next().unwrap();
432         let i2r = &iters.next().unwrap();
433         let answer: Vec<_> = i0.flat_map(move |ei0| i1r.clone().flat_map(move |ei1| i2r.clone().map(move |ei2| vec![ei0, ei1, ei2]))).collect();
434         let mut multi_product = a.clone().multi_cartesian_product();
435         let mut actual = Vec::new();
436 
437         actual.extend((&mut multi_product).take(take_manual));
438         if actual.len() == take_manual {
439             multi_product.fold((), |(), elt| actual.push(elt));
440         }
441         assert_eq!(answer, actual);
442 
443         assert_eq!(answer.into_iter().last(), a.clone().multi_cartesian_product().last());
444     }
445 
446     #[allow(deprecated)]
447     fn size_step(a: Iter<i16, Exact>, s: usize) -> bool {
448         let mut s = s;
449         if s == 0 {
450             s += 1; // never zero
451         }
452         let filt = a.clone().dedup();
453         correct_size_hint(filt.step(s)) &&
454             exact_size(a.step(s))
455     }
456 
457     #[allow(deprecated)]
458     fn equal_step(a: Iter<i16>, s: usize) -> bool {
459         let mut s = s;
460         if s == 0 {
461             s += 1; // never zero
462         }
463         let mut i = 0;
464         itertools::equal(a.clone().step(s), a.filter(|_| {
465             let keep = i % s == 0;
466             i += 1;
467             keep
468         }))
469     }
470 
471     #[allow(deprecated)]
472     fn equal_step_vec(a: Vec<i16>, s: usize) -> bool {
473         let mut s = s;
474         if s == 0 {
475             s += 1; // never zero
476         }
477         let mut i = 0;
478         itertools::equal(a.iter().step(s), a.iter().filter(|_| {
479             let keep = i % s == 0;
480             i += 1;
481             keep
482         }))
483     }
484 
485     fn size_multipeek(a: Iter<u16, Exact>, s: u8) -> bool {
486         let mut it = multipeek(a);
487         // peek a few times
488         for _ in 0..s {
489             it.peek();
490         }
491         exact_size(it)
492     }
493 
494     fn equal_merge(a: Vec<i16>, b: Vec<i16>) -> bool {
495         let mut sa = a.clone();
496         let mut sb = b.clone();
497         sa.sort();
498         sb.sort();
499         let mut merged = sa.clone();
500         merged.extend(sb.iter().cloned());
501         merged.sort();
502         itertools::equal(&merged, sa.iter().merge(&sb))
503     }
504     fn size_merge(a: Iter<u16>, b: Iter<u16>) -> bool {
505         correct_size_hint(a.merge(b))
506     }
507     fn size_zip(a: Iter<i16, Exact>, b: Iter<i16, Exact>, c: Iter<i16, Exact>) -> bool {
508         let filt = a.clone().dedup();
509         correct_size_hint(multizip((filt, b.clone(), c.clone()))) &&
510             exact_size(multizip((a, b, c)))
511     }
512     fn size_zip_rc(a: Iter<i16>, b: Iter<i16>) -> bool {
513         let rc = rciter(a.clone());
514         correct_size_hint(multizip((&rc, &rc, b)))
515     }
516 
517     fn size_zip_macro(a: Iter<i16, Exact>, b: Iter<i16, Exact>, c: Iter<i16, Exact>) -> bool {
518         let filt = a.clone().dedup();
519         correct_size_hint(izip!(filt, b.clone(), c.clone())) &&
520             exact_size(izip!(a, b, c))
521     }
522     fn equal_kmerge(a: Vec<i16>, b: Vec<i16>, c: Vec<i16>) -> bool {
523         use itertools::free::kmerge;
524         let mut sa = a.clone();
525         let mut sb = b.clone();
526         let mut sc = c.clone();
527         sa.sort();
528         sb.sort();
529         sc.sort();
530         let mut merged = sa.clone();
531         merged.extend(sb.iter().cloned());
532         merged.extend(sc.iter().cloned());
533         merged.sort();
534         itertools::equal(merged.into_iter(), kmerge(vec![sa, sb, sc]))
535     }
536 
537     // Any number of input iterators
538     fn equal_kmerge_2(mut inputs: Vec<Vec<i16>>) -> bool {
539         use itertools::free::kmerge;
540         // sort the inputs
541         for input in &mut inputs {
542             input.sort();
543         }
544         let mut merged = inputs.concat();
545         merged.sort();
546         itertools::equal(merged.into_iter(), kmerge(inputs))
547     }
548 
549     // Any number of input iterators
550     fn equal_kmerge_by_ge(mut inputs: Vec<Vec<i16>>) -> bool {
551         // sort the inputs
552         for input in &mut inputs {
553             input.sort();
554             input.reverse();
555         }
556         let mut merged = inputs.concat();
557         merged.sort();
558         merged.reverse();
559         itertools::equal(merged.into_iter(),
560                          inputs.into_iter().kmerge_by(|x, y| x >= y))
561     }
562 
563     // Any number of input iterators
564     fn equal_kmerge_by_lt(mut inputs: Vec<Vec<i16>>) -> bool {
565         // sort the inputs
566         for input in &mut inputs {
567             input.sort();
568         }
569         let mut merged = inputs.concat();
570         merged.sort();
571         itertools::equal(merged.into_iter(),
572                          inputs.into_iter().kmerge_by(|x, y| x < y))
573     }
574 
575     // Any number of input iterators
576     fn equal_kmerge_by_le(mut inputs: Vec<Vec<i16>>) -> bool {
577         // sort the inputs
578         for input in &mut inputs {
579             input.sort();
580         }
581         let mut merged = inputs.concat();
582         merged.sort();
583         itertools::equal(merged.into_iter(),
584                          inputs.into_iter().kmerge_by(|x, y| x <= y))
585     }
586     fn size_kmerge(a: Iter<i16>, b: Iter<i16>, c: Iter<i16>) -> bool {
587         use itertools::free::kmerge;
588         correct_size_hint(kmerge(vec![a, b, c]))
589     }
590     fn equal_zip_eq(a: Vec<i32>, b: Vec<i32>) -> bool {
591         let len = std::cmp::min(a.len(), b.len());
592         let a = &a[..len];
593         let b = &b[..len];
594         itertools::equal(zip_eq(a, b), zip(a, b))
595     }
596     fn size_zip_longest(a: Iter<i16, Exact>, b: Iter<i16, Exact>) -> bool {
597         let filt = a.clone().dedup();
598         let filt2 = b.clone().dedup();
599         correct_size_hint(filt.zip_longest(b.clone())) &&
600         correct_size_hint(a.clone().zip_longest(filt2)) &&
601             exact_size(a.zip_longest(b))
602     }
603     fn size_2_zip_longest(a: Iter<i16>, b: Iter<i16>) -> bool {
604         let it = a.clone().zip_longest(b.clone());
605         let jt = a.clone().zip_longest(b.clone());
606         itertools::equal(a.clone(),
607                          it.filter_map(|elt| match elt {
608                              EitherOrBoth::Both(x, _) => Some(x),
609                              EitherOrBoth::Left(x) => Some(x),
610                              _ => None,
611                          }
612                          ))
613             &&
614         itertools::equal(b.clone(),
615                          jt.filter_map(|elt| match elt {
616                              EitherOrBoth::Both(_, y) => Some(y),
617                              EitherOrBoth::Right(y) => Some(y),
618                              _ => None,
619                          }
620                          ))
621     }
622     fn size_interleave(a: Iter<i16>, b: Iter<i16>) -> bool {
623         correct_size_hint(a.interleave(b))
624     }
625     fn exact_interleave(a: Iter<i16, Exact>, b: Iter<i16, Exact>) -> bool {
626         exact_size_for_this(a.interleave(b))
627     }
628     fn size_interleave_shortest(a: Iter<i16>, b: Iter<i16>) -> bool {
629         correct_size_hint(a.interleave_shortest(b))
630     }
631     fn exact_interleave_shortest(a: Vec<()>, b: Vec<()>) -> bool {
632         exact_size_for_this(a.iter().interleave_shortest(&b))
633     }
634     fn size_intersperse(a: Iter<i16>, x: i16) -> bool {
635         correct_size_hint(a.intersperse(x))
636     }
637     fn equal_intersperse(a: Vec<i32>, x: i32) -> bool {
638         let mut inter = false;
639         let mut i = 0;
640         for elt in a.iter().cloned().intersperse(x) {
641             if inter {
642                 if elt != x { return false }
643             } else {
644                 if elt != a[i] { return false }
645                 i += 1;
646             }
647             inter = !inter;
648         }
649         true
650     }
651 
652     fn equal_combinations_2(a: Vec<u8>) -> bool {
653         let mut v = Vec::new();
654         for (i, x) in enumerate(&a) {
655             for y in &a[i + 1..] {
656                 v.push((x, y));
657             }
658         }
659         itertools::equal(a.iter().tuple_combinations::<(_, _)>(), v)
660     }
661 
662     fn collect_tuple_matches_size(a: Iter<i16>) -> bool {
663         let size = a.clone().count();
664         a.collect_tuple::<(_, _, _)>().is_some() == (size == 3)
665     }
666 
667     fn correct_permutations(vals: HashSet<i32>, k: usize) -> () {
668         // Test permutations only on iterators of distinct integers, to prevent
669         // false positives.
670 
671         const MAX_N: usize = 5;
672 
673         let n = min(vals.len(), MAX_N);
674         let vals: HashSet<i32> = vals.into_iter().take(n).collect();
675 
676         let perms = vals.iter().permutations(k);
677 
678         let mut actual = HashSet::new();
679 
680         for perm in perms {
681             assert_eq!(perm.len(), k);
682 
683             let all_items_valid = perm.iter().all(|p| vals.contains(p));
684             assert!(all_items_valid, "perm contains value not from input: {:?}", perm);
685 
686             // Check that all perm items are distinct
687             let distinct_len = {
688                 let perm_set: HashSet<_> = perm.iter().collect();
689                 perm_set.len()
690             };
691             assert_eq!(perm.len(), distinct_len);
692 
693             // Check that the perm is new
694             assert!(actual.insert(perm.clone()), "perm already encountered: {:?}", perm);
695         }
696     }
697 
698     fn permutations_lexic_order(a: usize, b: usize) -> () {
699         let a = a % 6;
700         let b = b % 6;
701 
702         let n = max(a, b);
703         let k = min (a, b);
704 
705         let expected_first: Vec<usize> = (0..k).collect();
706         let expected_last: Vec<usize> = ((n - k)..n).rev().collect();
707 
708         let mut perms = (0..n).permutations(k);
709 
710         let mut curr_perm = match perms.next() {
711             Some(p) => p,
712             None => { return; }
713         };
714 
715         assert_eq!(expected_first, curr_perm);
716 
717         while let Some(next_perm) = perms.next() {
718             assert!(
719                 next_perm > curr_perm,
720                 "next perm isn't greater-than current; next_perm={:?} curr_perm={:?} n={}",
721                 next_perm, curr_perm, n
722             );
723 
724             curr_perm = next_perm;
725         }
726 
727         assert_eq!(expected_last, curr_perm);
728 
729     }
730 
731     fn permutations_count(n: usize, k: usize) -> bool {
732         let n = n % 6;
733 
734         correct_count(|| (0..n).permutations(k))
735     }
736 
737     fn permutations_size(a: Iter<i32>, k: usize) -> bool {
738         correct_size_hint(a.take(5).permutations(k))
739     }
740 
741     fn permutations_k0_yields_once(n: usize) -> () {
742         let k = 0;
743         let expected: Vec<Vec<usize>> = vec![vec![]];
744         let actual = (0..n).permutations(k).collect_vec();
745 
746         assert_eq!(expected, actual);
747     }
748 }
749 
750 quickcheck! {
751     fn equal_dedup(a: Vec<i32>) -> bool {
752         let mut b = a.clone();
753         b.dedup();
754         itertools::equal(&b, a.iter().dedup())
755     }
756 }
757 
758 quickcheck! {
759     fn equal_dedup_by(a: Vec<(i32, i32)>) -> bool {
760         let mut b = a.clone();
761         b.dedup_by(|x, y| x.0==y.0);
762         itertools::equal(&b, a.iter().dedup_by(|x, y| x.0==y.0))
763     }
764 }
765 
766 quickcheck! {
767     fn size_dedup(a: Vec<i32>) -> bool {
768         correct_size_hint(a.iter().dedup())
769     }
770 }
771 
772 quickcheck! {
773     fn size_dedup_by(a: Vec<(i32, i32)>) -> bool {
774         correct_size_hint(a.iter().dedup_by(|x, y| x.0==y.0))
775     }
776 }
777 
778 quickcheck! {
779     fn exact_repeatn((n, x): (usize, i32)) -> bool {
780         let it = itertools::repeat_n(x, n);
781         exact_size(it)
782     }
783 }
784 
785 quickcheck! {
786     fn size_put_back(a: Vec<u8>, x: Option<u8>) -> bool {
787         let mut it = put_back(a.into_iter());
788         match x {
789             Some(t) => it.put_back(t),
790             None => {}
791         }
792         correct_size_hint(it)
793     }
794 }
795 
796 quickcheck! {
797     fn size_put_backn(a: Vec<u8>, b: Vec<u8>) -> bool {
798         let mut it = put_back_n(a.into_iter());
799         for elt in b {
800             it.put_back(elt)
801         }
802         correct_size_hint(it)
803     }
804 }
805 
806 quickcheck! {
807     fn size_tee(a: Vec<u8>) -> bool {
808         let (mut t1, mut t2) = a.iter().tee();
809         t1.next();
810         t1.next();
811         t2.next();
812         exact_size(t1) && exact_size(t2)
813     }
814 }
815 
816 quickcheck! {
817     fn size_tee_2(a: Vec<u8>) -> bool {
818         let (mut t1, mut t2) = a.iter().dedup().tee();
819         t1.next();
820         t1.next();
821         t2.next();
822         correct_size_hint(t1) && correct_size_hint(t2)
823     }
824 }
825 
826 quickcheck! {
827     fn size_take_while_ref(a: Vec<u8>, stop: u8) -> bool {
828         correct_size_hint(a.iter().take_while_ref(|x| **x != stop))
829     }
830 }
831 
832 quickcheck! {
833     fn equal_partition(a: Vec<i32>) -> bool {
834         let mut a = a;
835         let mut ap = a.clone();
836         let split_index = itertools::partition(&mut ap, |x| *x >= 0);
837         let parted = (0..split_index).all(|i| ap[i] >= 0) &&
838             (split_index..a.len()).all(|i| ap[i] < 0);
839 
840         a.sort();
841         ap.sort();
842         parted && (a == ap)
843     }
844 }
845 
846 quickcheck! {
847     fn size_combinations(it: Iter<i16>) -> bool {
848         correct_size_hint(it.tuple_combinations::<(_, _)>())
849     }
850 }
851 
852 quickcheck! {
853     fn equal_combinations(it: Iter<i16>) -> bool {
854         let values = it.clone().collect_vec();
855         let mut cmb = it.tuple_combinations();
856         for i in 0..values.len() {
857             for j in i+1..values.len() {
858                 let pair = (values[i], values[j]);
859                 if pair != cmb.next().unwrap() {
860                     return false;
861                 }
862             }
863         }
864         cmb.next() == None
865     }
866 }
867 
868 quickcheck! {
869     fn size_pad_tail(it: Iter<i8>, pad: u8) -> bool {
870         correct_size_hint(it.clone().pad_using(pad as usize, |_| 0)) &&
871             correct_size_hint(it.dropping(1).rev().pad_using(pad as usize, |_| 0))
872     }
873 }
874 
875 quickcheck! {
876     fn size_pad_tail2(it: Iter<i8, Exact>, pad: u8) -> bool {
877         exact_size(it.pad_using(pad as usize, |_| 0))
878     }
879 }
880 
881 quickcheck! {
882     fn size_unique(it: Iter<i8>) -> bool {
883         correct_size_hint(it.unique())
884     }
885 
886     fn count_unique(it: Vec<i8>, take_first: u8) -> () {
887         let answer = {
888             let mut v = it.clone();
889             v.sort(); v.dedup();
890             v.len()
891         };
892         let mut iter = cloned(&it).unique();
893         let first_count = (&mut iter).take(take_first as usize).count();
894         let rest_count = iter.count();
895         assert_eq!(answer, first_count + rest_count);
896     }
897 }
898 
899 quickcheck! {
900     fn fuzz_group_by_lazy_1(it: Iter<u8>) -> bool {
901         let jt = it.clone();
902         let groups = it.group_by(|k| *k);
903         let res = itertools::equal(jt, groups.into_iter().flat_map(|(_, x)| x));
904         res
905     }
906 }
907 
908 quickcheck! {
909     fn fuzz_group_by_lazy_2(data: Vec<u8>) -> bool {
910         let groups = data.iter().group_by(|k| *k / 10);
911         let res = itertools::equal(data.iter(), groups.into_iter().flat_map(|(_, x)| x));
912         res
913     }
914 }
915 
916 quickcheck! {
917     fn fuzz_group_by_lazy_3(data: Vec<u8>) -> bool {
918         let grouper = data.iter().group_by(|k| *k / 10);
919         let groups = grouper.into_iter().collect_vec();
920         let res = itertools::equal(data.iter(), groups.into_iter().flat_map(|(_, x)| x));
921         res
922     }
923 }
924 
925 quickcheck! {
926     fn fuzz_group_by_lazy_duo(data: Vec<u8>, order: Vec<(bool, bool)>) -> bool {
927         let grouper = data.iter().group_by(|k| *k / 3);
928         let mut groups1 = grouper.into_iter();
929         let mut groups2 = grouper.into_iter();
930         let mut elts = Vec::<&u8>::new();
931         let mut old_groups = Vec::new();
932 
933         let tup1 = |(_, b)| b;
934         for &(ord, consume_now) in &order {
935             let iter = &mut [&mut groups1, &mut groups2][ord as usize];
936             match iter.next() {
937                 Some((_, gr)) => if consume_now {
938                     for og in old_groups.drain(..) {
939                         elts.extend(og);
940                     }
941                     elts.extend(gr);
942                 } else {
943                     old_groups.push(gr);
944                 },
945                 None => break,
946             }
947         }
948         for og in old_groups.drain(..) {
949             elts.extend(og);
950         }
951         for gr in groups1.map(&tup1) { elts.extend(gr); }
952         for gr in groups2.map(&tup1) { elts.extend(gr); }
953         itertools::assert_equal(&data, elts);
954         true
955     }
956 }
957 
958 quickcheck! {
959     fn equal_chunks_lazy(a: Vec<u8>, size: u8) -> bool {
960         let mut size = size;
961         if size == 0 {
962             size += 1;
963         }
964         let chunks = a.iter().chunks(size as usize);
965         let it = a.chunks(size as usize);
966         for (a, b) in chunks.into_iter().zip(it) {
967             if !itertools::equal(a, b) {
968                 return false;
969             }
970         }
971         true
972     }
973 }
974 
975 quickcheck! {
976     fn equal_tuple_windows_1(a: Vec<u8>) -> bool {
977         let x = a.windows(1).map(|s| (&s[0], ));
978         let y = a.iter().tuple_windows::<(_,)>();
979         itertools::equal(x, y)
980     }
981 
982     fn equal_tuple_windows_2(a: Vec<u8>) -> bool {
983         let x = a.windows(2).map(|s| (&s[0], &s[1]));
984         let y = a.iter().tuple_windows::<(_, _)>();
985         itertools::equal(x, y)
986     }
987 
988     fn equal_tuple_windows_3(a: Vec<u8>) -> bool {
989         let x = a.windows(3).map(|s| (&s[0], &s[1], &s[2]));
990         let y = a.iter().tuple_windows::<(_, _, _)>();
991         itertools::equal(x, y)
992     }
993 
994     fn equal_tuple_windows_4(a: Vec<u8>) -> bool {
995         let x = a.windows(4).map(|s| (&s[0], &s[1], &s[2], &s[3]));
996         let y = a.iter().tuple_windows::<(_, _, _, _)>();
997         itertools::equal(x, y)
998     }
999 
1000     fn equal_tuples_1(a: Vec<u8>) -> bool {
1001         let x = a.chunks(1).map(|s| (&s[0], ));
1002         let y = a.iter().tuples::<(_,)>();
1003         itertools::equal(x, y)
1004     }
1005 
1006     fn equal_tuples_2(a: Vec<u8>) -> bool {
1007         let x = a.chunks(2).filter(|s| s.len() == 2).map(|s| (&s[0], &s[1]));
1008         let y = a.iter().tuples::<(_, _)>();
1009         itertools::equal(x, y)
1010     }
1011 
1012     fn equal_tuples_3(a: Vec<u8>) -> bool {
1013         let x = a.chunks(3).filter(|s| s.len() == 3).map(|s| (&s[0], &s[1], &s[2]));
1014         let y = a.iter().tuples::<(_, _, _)>();
1015         itertools::equal(x, y)
1016     }
1017 
1018     fn equal_tuples_4(a: Vec<u8>) -> bool {
1019         let x = a.chunks(4).filter(|s| s.len() == 4).map(|s| (&s[0], &s[1], &s[2], &s[3]));
1020         let y = a.iter().tuples::<(_, _, _, _)>();
1021         itertools::equal(x, y)
1022     }
1023 
1024     fn exact_tuple_buffer(a: Vec<u8>) -> bool {
1025         let mut iter = a.iter().tuples::<(_, _, _, _)>();
1026         (&mut iter).last();
1027         let buffer = iter.into_buffer();
1028         assert_eq!(buffer.len(), a.len() % 4);
1029         exact_size(buffer)
1030     }
1031 }
1032 
1033 // with_position
1034 quickcheck! {
1035     fn with_position_exact_size_1(a: Vec<u8>) -> bool {
1036         exact_size_for_this(a.iter().with_position())
1037     }
1038     fn with_position_exact_size_2(a: Iter<u8, Exact>) -> bool {
1039         exact_size_for_this(a.with_position())
1040     }
1041 }
1042 
1043 quickcheck! {
1044     fn correct_group_map_modulo_key(a: Vec<u8>, modulo: u8) -> () {
1045         let modulo = if modulo == 0 { 1 } else { modulo }; // Avoid `% 0`
1046         let count = a.len();
1047         let lookup = a.into_iter().map(|i| (i % modulo, i)).into_group_map();
1048 
1049         assert_eq!(lookup.values().flat_map(|vals| vals.iter()).count(), count);
1050 
1051         for (&key, vals) in lookup.iter() {
1052             assert!(vals.iter().all(|&val| val % modulo == key));
1053         }
1054     }
1055 }
1056 
1057 /// A peculiar type: Equality compares both tuple items, but ordering only the
1058 /// first item.  This is so we can check the stability property easily.
1059 #[derive(Clone, Debug, PartialEq, Eq)]
1060 struct Val(u32, u32);
1061 
1062 impl PartialOrd<Val> for Val {
partial_cmp(&self, other: &Val) -> Option<Ordering>1063     fn partial_cmp(&self, other: &Val) -> Option<Ordering> {
1064         self.0.partial_cmp(&other.0)
1065     }
1066 }
1067 
1068 impl Ord for Val {
cmp(&self, other: &Val) -> Ordering1069     fn cmp(&self, other: &Val) -> Ordering {
1070         self.0.cmp(&other.0)
1071     }
1072 }
1073 
1074 impl qc::Arbitrary for Val {
arbitrary<G: qc::Gen>(g: &mut G) -> Self1075     fn arbitrary<G: qc::Gen>(g: &mut G) -> Self {
1076         let (x, y) = <(u32, u32)>::arbitrary(g);
1077         Val(x, y)
1078     }
shrink(&self) -> Box<Iterator<Item = Self>>1079     fn shrink(&self) -> Box<Iterator<Item = Self>> {
1080         Box::new((self.0, self.1).shrink().map(|(x, y)| Val(x, y)))
1081     }
1082 }
1083 
1084 quickcheck! {
1085     fn minmax(a: Vec<Val>) -> bool {
1086         use itertools::MinMaxResult;
1087 
1088 
1089         let minmax = a.iter().minmax();
1090         let expected = match a.len() {
1091             0 => MinMaxResult::NoElements,
1092             1 => MinMaxResult::OneElement(&a[0]),
1093             _ => MinMaxResult::MinMax(a.iter().min().unwrap(),
1094                                       a.iter().max().unwrap()),
1095         };
1096         minmax == expected
1097     }
1098 }
1099 
1100 quickcheck! {
1101     fn minmax_f64(a: Vec<f64>) -> TestResult {
1102         use itertools::MinMaxResult;
1103 
1104         if a.iter().any(|x| x.is_nan()) {
1105             return TestResult::discard();
1106         }
1107 
1108         let min = cloned(&a).fold1(f64::min);
1109         let max = cloned(&a).fold1(f64::max);
1110 
1111         let minmax = cloned(&a).minmax();
1112         let expected = match a.len() {
1113             0 => MinMaxResult::NoElements,
1114             1 => MinMaxResult::OneElement(min.unwrap()),
1115             _ => MinMaxResult::MinMax(min.unwrap(), max.unwrap()),
1116         };
1117         TestResult::from_bool(minmax == expected)
1118     }
1119 }
1120 
1121 quickcheck! {
1122     #[allow(deprecated)]
1123     fn tree_fold1_f64(mut a: Vec<f64>) -> TestResult {
1124         fn collapse_adjacent<F>(x: Vec<f64>, mut f: F) -> Vec<f64>
1125             where F: FnMut(f64, f64) -> f64
1126         {
1127             let mut out = Vec::new();
1128             for i in (0..x.len()).step(2) {
1129                 if i == x.len()-1 {
1130                     out.push(x[i])
1131                 } else {
1132                     out.push(f(x[i], x[i+1]));
1133                 }
1134             }
1135             out
1136         }
1137 
1138         if a.iter().any(|x| x.is_nan()) {
1139             return TestResult::discard();
1140         }
1141 
1142         let actual = a.iter().cloned().tree_fold1(f64::atan2);
1143 
1144         while a.len() > 1 {
1145             a = collapse_adjacent(a, f64::atan2);
1146         }
1147         let expected = a.pop();
1148 
1149         TestResult::from_bool(actual == expected)
1150     }
1151 }
1152 
1153 quickcheck! {
1154     fn exactly_one_i32(a: Vec<i32>) -> TestResult {
1155         let ret = a.iter().cloned().exactly_one();
1156         match a.len() {
1157             1 => TestResult::from_bool(ret.unwrap() == a[0]),
1158             _ => TestResult::from_bool(ret.unwrap_err().eq(a.iter().cloned())),
1159         }
1160     }
1161 }
1162