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 use quickcheck as qc;
7 use std::default::Default;
8 use std::num::Wrapping;
9 use std::ops::Range;
10 use std::cmp::{max, min, Ordering};
11 use std::collections::{HashMap, HashSet};
12 use itertools::Itertools;
13 use itertools::{
14     multizip,
15     EitherOrBoth,
16     iproduct,
17     izip,
18 };
19 use itertools::free::{
20     cloned,
21     enumerate,
22     multipeek,
23     peek_nth,
24     put_back,
25     put_back_n,
26     rciter,
27     zip,
28     zip_eq,
29 };
30 
31 use rand::Rng;
32 use rand::seq::SliceRandom;
33 use quickcheck::TestResult;
34 
35 /// Trait for size hint modifier types
36 trait HintKind: Copy + Send + qc::Arbitrary {
loosen_bounds(&self, org_hint: (usize, Option<usize>)) -> (usize, Option<usize>)37     fn loosen_bounds(&self, org_hint: (usize, Option<usize>)) -> (usize, Option<usize>);
38 }
39 
40 /// Exact size hint variant that leaves hints unchanged
41 #[derive(Clone, Copy, Debug)]
42 struct Exact {}
43 
44 impl HintKind for Exact {
loosen_bounds(&self, org_hint: (usize, Option<usize>)) -> (usize, Option<usize>)45     fn loosen_bounds(&self, org_hint: (usize, Option<usize>)) -> (usize, Option<usize>) {
46         org_hint
47     }
48 }
49 
50 impl qc::Arbitrary for Exact {
arbitrary<G: qc::Gen>(_: &mut G) -> Self51     fn arbitrary<G: qc::Gen>(_: &mut G) -> Self {
52         Exact {}
53     }
54 }
55 
56 /// Inexact size hint variant to simulate imprecise (but valid) size hints
57 ///
58 /// Will always decrease the lower bound and increase the upper bound
59 /// of the size hint by set amounts.
60 #[derive(Clone, Copy, Debug)]
61 struct Inexact {
62     underestimate: usize,
63     overestimate: usize,
64 }
65 
66 impl HintKind for Inexact {
loosen_bounds(&self, org_hint: (usize, Option<usize>)) -> (usize, Option<usize>)67     fn loosen_bounds(&self, org_hint: (usize, Option<usize>)) -> (usize, Option<usize>) {
68         let (org_lower, org_upper) = org_hint;
69         (org_lower.saturating_sub(self.underestimate),
70          org_upper.and_then(move |x| x.checked_add(self.overestimate)))
71     }
72 }
73 
74 impl qc::Arbitrary for Inexact {
arbitrary<G: qc::Gen>(g: &mut G) -> Self75     fn arbitrary<G: qc::Gen>(g: &mut G) -> Self {
76         let ue_value = usize::arbitrary(g);
77         let oe_value = usize::arbitrary(g);
78         // Compensate for quickcheck using extreme values too rarely
79         let ue_choices = &[0, ue_value, usize::max_value()];
80         let oe_choices = &[0, oe_value, usize::max_value()];
81         Inexact {
82             underestimate: *ue_choices.choose(g).unwrap(),
83             overestimate: *oe_choices.choose(g).unwrap(),
84         }
85     }
86 
shrink(&self) -> Box<dyn Iterator<Item=Self>>87     fn shrink(&self) -> Box<dyn Iterator<Item=Self>> {
88         let underestimate_value = self.underestimate;
89         let overestimate_value = self.overestimate;
90         Box::new(
91             underestimate_value.shrink().flat_map(move |ue_value|
92                 overestimate_value.shrink().map(move |oe_value|
93                     Inexact {
94                         underestimate: ue_value,
95                         overestimate: oe_value,
96                     }
97                 )
98             )
99         )
100     }
101 }
102 
103 /// Our base iterator that we can impl Arbitrary for
104 ///
105 /// By default we'll return inexact bounds estimates for size_hint
106 /// to make tests harder to pass.
107 ///
108 /// NOTE: Iter is tricky and is not fused, to help catch bugs.
109 /// At the end it will return None once, then return Some(0),
110 /// then return None again.
111 #[derive(Clone, Debug)]
112 struct Iter<T, SK: HintKind = Inexact> {
113     iterator: Range<T>,
114     // fuse/done flag
115     fuse_flag: i32,
116     hint_kind: SK,
117 }
118 
119 impl<T, HK> Iter<T, HK> where HK: HintKind
120 {
new(it: Range<T>, hint_kind: HK) -> Self121     fn new(it: Range<T>, hint_kind: HK) -> Self {
122         Iter {
123             iterator: it,
124             fuse_flag: 0,
125             hint_kind,
126         }
127     }
128 }
129 
130 impl<T, HK> Iterator for Iter<T, HK>
131     where Range<T>: Iterator,
132           <Range<T> as Iterator>::Item: Default,
133           HK: HintKind,
134 {
135     type Item = <Range<T> as Iterator>::Item;
136 
next(&mut self) -> Option<Self::Item>137     fn next(&mut self) -> Option<Self::Item>
138     {
139         let elt = self.iterator.next();
140         if elt.is_none() {
141             self.fuse_flag += 1;
142             // check fuse flag
143             if self.fuse_flag == 2 {
144                 return Some(Default::default())
145             }
146         }
147         elt
148     }
149 
size_hint(&self) -> (usize, Option<usize>)150     fn size_hint(&self) -> (usize, Option<usize>)
151     {
152         let org_hint = self.iterator.size_hint();
153         self.hint_kind.loosen_bounds(org_hint)
154     }
155 }
156 
157 impl<T, HK> DoubleEndedIterator for Iter<T, HK>
158     where Range<T>: DoubleEndedIterator,
159           <Range<T> as Iterator>::Item: Default,
160           HK: HintKind
161 {
next_back(&mut self) -> Option<Self::Item>162     fn next_back(&mut self) -> Option<Self::Item> { self.iterator.next_back() }
163 }
164 
165 impl<T> ExactSizeIterator for Iter<T, Exact> where Range<T>: ExactSizeIterator,
166     <Range<T> as Iterator>::Item: Default,
167 { }
168 
169 impl<T, HK> qc::Arbitrary for Iter<T, HK>
170     where T: qc::Arbitrary,
171           HK: HintKind,
172 {
arbitrary<G: qc::Gen>(g: &mut G) -> Self173     fn arbitrary<G: qc::Gen>(g: &mut G) -> Self
174     {
175         Iter::new(T::arbitrary(g)..T::arbitrary(g), HK::arbitrary(g))
176     }
177 
shrink(&self) -> Box<dyn Iterator<Item=Iter<T, HK>>>178     fn shrink(&self) -> Box<dyn Iterator<Item=Iter<T, HK>>>
179     {
180         let r = self.iterator.clone();
181         let hint_kind = self.hint_kind;
182         Box::new(
183             r.start.shrink().flat_map(move |a|
184                 r.end.shrink().map(move |b|
185                     Iter::new(a.clone()..b, hint_kind)
186                 )
187             )
188         )
189     }
190 }
191 
192 /// A meta-iterator which yields `Iter<i32>`s whose start/endpoints are
193 /// increased or decreased linearly on each iteration.
194 #[derive(Clone, Debug)]
195 struct ShiftRange<HK = Inexact> {
196     range_start: i32,
197     range_end: i32,
198     start_step: i32,
199     end_step: i32,
200     iter_count: u32,
201     hint_kind: HK,
202 }
203 
204 impl<HK> Iterator for ShiftRange<HK> where HK: HintKind {
205     type Item = Iter<i32, HK>;
206 
next(&mut self) -> Option<Self::Item>207     fn next(&mut self) -> Option<Self::Item> {
208         if self.iter_count == 0 {
209             return None;
210         }
211 
212         let iter = Iter::new(self.range_start..self.range_end, self.hint_kind);
213 
214         self.range_start += self.start_step;
215         self.range_end += self.end_step;
216         self.iter_count -= 1;
217 
218         Some(iter)
219     }
220 }
221 
222 impl ExactSizeIterator for ShiftRange<Exact> { }
223 
224 impl<HK> qc::Arbitrary for ShiftRange<HK>
225     where HK: HintKind
226 {
arbitrary<G: qc::Gen>(g: &mut G) -> Self227     fn arbitrary<G: qc::Gen>(g: &mut G) -> Self {
228         const MAX_STARTING_RANGE_DIFF: i32 = 32;
229         const MAX_STEP_MODULO: i32 = 8;
230         const MAX_ITER_COUNT: u32 = 3;
231 
232         let range_start = qc::Arbitrary::arbitrary(g);
233         let range_end = range_start + g.gen_range(0, MAX_STARTING_RANGE_DIFF + 1);
234         let start_step = g.gen_range(-MAX_STEP_MODULO, MAX_STEP_MODULO + 1);
235         let end_step = g.gen_range(-MAX_STEP_MODULO, MAX_STEP_MODULO + 1);
236         let iter_count = g.gen_range(0, MAX_ITER_COUNT + 1);
237         let hint_kind = qc::Arbitrary::arbitrary(g);
238 
239         ShiftRange {
240             range_start,
241             range_end,
242             start_step,
243             end_step,
244             iter_count,
245             hint_kind,
246         }
247     }
248 }
249 
correct_count<I, F>(get_it: F) -> bool where I: Iterator, F: Fn() -> I250 fn correct_count<I, F>(get_it: F) -> bool
251 where
252     I: Iterator,
253     F: Fn() -> I
254 {
255     let mut counts = vec![get_it().count()];
256 
257     'outer: loop {
258         let mut it = get_it();
259 
260         for _ in 0..(counts.len() - 1) {
261             if let None = it.next() {
262                 panic!("Iterator shouldn't be finished, may not be deterministic");
263             }
264         }
265 
266         if let None = it.next() {
267             break 'outer;
268         }
269 
270         counts.push(it.count());
271     }
272 
273     let total_actual_count = counts.len() - 1;
274 
275     for (i, returned_count) in counts.into_iter().enumerate() {
276         let actual_count = total_actual_count - i;
277         if actual_count != returned_count {
278             println!("Total iterations: {} True count: {} returned count: {}", i, actual_count, returned_count);
279 
280             return false;
281         }
282     }
283 
284     true
285 }
286 
correct_size_hint<I: Iterator>(mut it: I) -> bool287 fn correct_size_hint<I: Iterator>(mut it: I) -> bool {
288     // record size hint at each iteration
289     let initial_hint = it.size_hint();
290     let mut hints = Vec::with_capacity(initial_hint.0 + 1);
291     hints.push(initial_hint);
292     while let Some(_) = it.next() {
293         hints.push(it.size_hint())
294     }
295 
296     let mut true_count = hints.len(); // start off +1 too much
297 
298     // check all the size hints
299     for &(low, hi) in &hints {
300         true_count -= 1;
301         if low > true_count ||
302             (hi.is_some() && hi.unwrap() < true_count)
303         {
304             println!("True size: {:?}, size hint: {:?}", true_count, (low, hi));
305             //println!("All hints: {:?}", hints);
306             return false
307         }
308     }
309     true
310 }
311 
exact_size<I: ExactSizeIterator>(mut it: I) -> bool312 fn exact_size<I: ExactSizeIterator>(mut it: I) -> bool {
313     // check every iteration
314     let (mut low, mut hi) = it.size_hint();
315     if Some(low) != hi { return false; }
316     while let Some(_) = it.next() {
317         let (xlow, xhi) = it.size_hint();
318         if low != xlow + 1 { return false; }
319         low = xlow;
320         hi = xhi;
321         if Some(low) != hi { return false; }
322     }
323     let (low, hi) = it.size_hint();
324     low == 0 && hi == Some(0)
325 }
326 
327 // Exact size for this case, without ExactSizeIterator
exact_size_for_this<I: Iterator>(mut it: I) -> bool328 fn exact_size_for_this<I: Iterator>(mut it: I) -> bool {
329     // check every iteration
330     let (mut low, mut hi) = it.size_hint();
331     if Some(low) != hi { return false; }
332     while let Some(_) = it.next() {
333         let (xlow, xhi) = it.size_hint();
334         if low != xlow + 1 { return false; }
335         low = xlow;
336         hi = xhi;
337         if Some(low) != hi { return false; }
338     }
339     let (low, hi) = it.size_hint();
340     low == 0 && hi == Some(0)
341 }
342 
343 /*
344  * NOTE: Range<i8> is broken!
345  * (all signed ranges are)
346 #[quickcheck]
347 fn size_range_i8(a: Iter<i8>) -> bool {
348     exact_size(a)
349 }
350 
351 #[quickcheck]
352 fn size_range_i16(a: Iter<i16>) -> bool {
353     exact_size(a)
354 }
355 
356 #[quickcheck]
357 fn size_range_u8(a: Iter<u8>) -> bool {
358     exact_size(a)
359 }
360  */
361 
362 macro_rules! quickcheck {
363     // accept several property function definitions
364     // The property functions can use pattern matching and `mut` as usual
365     // in the function arguments, but the functions can not be generic.
366     {$($(#$attr:tt)* fn $fn_name:ident($($arg:tt)*) -> $ret:ty { $($code:tt)* })*} => (
367         $(
368             #[test]
369             $(#$attr)*
370             fn $fn_name() {
371                 fn prop($($arg)*) -> $ret {
372                     $($code)*
373                 }
374                 ::quickcheck::quickcheck(quickcheck!(@fn prop [] $($arg)*));
375             }
376         )*
377     );
378     // parse argument list (with patterns allowed) into prop as fn(_, _) -> _
379     (@fn $f:ident [$($t:tt)*]) => {
380         $f as fn($($t),*) -> _
381     };
382     (@fn $f:ident [$($p:tt)*] : $($tail:tt)*) => {
383         quickcheck!(@fn $f [$($p)* _] $($tail)*)
384     };
385     (@fn $f:ident [$($p:tt)*] $t:tt $($tail:tt)*) => {
386         quickcheck!(@fn $f [$($p)*] $($tail)*)
387     };
388 }
389 
390 quickcheck! {
391 
392     fn size_product(a: Iter<u16>, b: Iter<u16>) -> bool {
393         correct_size_hint(a.cartesian_product(b))
394     }
395     fn size_product3(a: Iter<u16>, b: Iter<u16>, c: Iter<u16>) -> bool {
396         correct_size_hint(iproduct!(a, b, c))
397     }
398 
399     fn correct_cartesian_product3(a: Iter<u16>, b: Iter<u16>, c: Iter<u16>,
400                                   take_manual: usize) -> ()
401     {
402         // test correctness of iproduct through regular iteration (take)
403         // and through fold.
404         let ac = a.clone();
405         let br = &b.clone();
406         let cr = &c.clone();
407         let answer: Vec<_> = ac.flat_map(move |ea| br.clone().flat_map(move |eb| cr.clone().map(move |ec| (ea, eb, ec)))).collect();
408         let mut product_iter = iproduct!(a, b, c);
409         let mut actual = Vec::new();
410 
411         actual.extend((&mut product_iter).take(take_manual));
412         if actual.len() == take_manual {
413             product_iter.fold((), |(), elt| actual.push(elt));
414         }
415         assert_eq!(answer, actual);
416     }
417 
418     fn size_multi_product(a: ShiftRange) -> bool {
419         correct_size_hint(a.multi_cartesian_product())
420     }
421     fn correct_multi_product3(a: ShiftRange, take_manual: usize) -> () {
422         // Fix no. of iterators at 3
423         let a = ShiftRange { iter_count: 3, ..a };
424 
425         // test correctness of MultiProduct through regular iteration (take)
426         // and through fold.
427         let mut iters = a.clone();
428         let i0 = iters.next().unwrap();
429         let i1r = &iters.next().unwrap();
430         let i2r = &iters.next().unwrap();
431         let answer: Vec<_> = i0.flat_map(move |ei0| i1r.clone().flat_map(move |ei1| i2r.clone().map(move |ei2| vec![ei0, ei1, ei2]))).collect();
432         let mut multi_product = a.clone().multi_cartesian_product();
433         let mut actual = Vec::new();
434 
435         actual.extend((&mut multi_product).take(take_manual));
436         if actual.len() == take_manual {
437             multi_product.fold((), |(), elt| actual.push(elt));
438         }
439         assert_eq!(answer, actual);
440 
441         assert_eq!(answer.into_iter().last(), a.clone().multi_cartesian_product().last());
442     }
443 
444     #[allow(deprecated)]
445     fn size_step(a: Iter<i16, Exact>, s: usize) -> bool {
446         let mut s = s;
447         if s == 0 {
448             s += 1; // never zero
449         }
450         let filt = a.clone().dedup();
451         correct_size_hint(filt.step(s)) &&
452             exact_size(a.step(s))
453     }
454 
455     #[allow(deprecated)]
456     fn equal_step(a: Iter<i16>, s: usize) -> bool {
457         let mut s = s;
458         if s == 0 {
459             s += 1; // never zero
460         }
461         let mut i = 0;
462         itertools::equal(a.clone().step(s), a.filter(|_| {
463             let keep = i % s == 0;
464             i += 1;
465             keep
466         }))
467     }
468 
469     #[allow(deprecated)]
470     fn equal_step_vec(a: Vec<i16>, s: usize) -> bool {
471         let mut s = s;
472         if s == 0 {
473             s += 1; // never zero
474         }
475         let mut i = 0;
476         itertools::equal(a.iter().step(s), a.iter().filter(|_| {
477             let keep = i % s == 0;
478             i += 1;
479             keep
480         }))
481     }
482 
483     fn size_multipeek(a: Iter<u16, Exact>, s: u8) -> bool {
484         let mut it = multipeek(a);
485         // peek a few times
486         for _ in 0..s {
487             it.peek();
488         }
489         exact_size(it)
490     }
491 
492     fn size_peek_nth(a: Iter<u16, Exact>, s: u8) -> bool {
493         let mut it = peek_nth(a);
494         // peek a few times
495         for n in 0..s {
496             it.peek_nth(n as usize);
497         }
498         exact_size(it)
499     }
500 
501     fn equal_merge(a: Vec<i16>, b: Vec<i16>) -> bool {
502         let mut sa = a.clone();
503         let mut sb = b.clone();
504         sa.sort();
505         sb.sort();
506         let mut merged = sa.clone();
507         merged.extend(sb.iter().cloned());
508         merged.sort();
509         itertools::equal(&merged, sa.iter().merge(&sb))
510     }
511     fn size_merge(a: Iter<u16>, b: Iter<u16>) -> bool {
512         correct_size_hint(a.merge(b))
513     }
514     fn size_zip(a: Iter<i16, Exact>, b: Iter<i16, Exact>, c: Iter<i16, Exact>) -> bool {
515         let filt = a.clone().dedup();
516         correct_size_hint(multizip((filt, b.clone(), c.clone()))) &&
517             exact_size(multizip((a, b, c)))
518     }
519     fn size_zip_rc(a: Iter<i16>, b: Iter<i16>) -> bool {
520         let rc = rciter(a.clone());
521         correct_size_hint(multizip((&rc, &rc, b)))
522     }
523 
524     fn size_zip_macro(a: Iter<i16, Exact>, b: Iter<i16, Exact>, c: Iter<i16, Exact>) -> bool {
525         let filt = a.clone().dedup();
526         correct_size_hint(izip!(filt, b.clone(), c.clone())) &&
527             exact_size(izip!(a, b, c))
528     }
529     fn equal_kmerge(a: Vec<i16>, b: Vec<i16>, c: Vec<i16>) -> bool {
530         use itertools::free::kmerge;
531         let mut sa = a.clone();
532         let mut sb = b.clone();
533         let mut sc = c.clone();
534         sa.sort();
535         sb.sort();
536         sc.sort();
537         let mut merged = sa.clone();
538         merged.extend(sb.iter().cloned());
539         merged.extend(sc.iter().cloned());
540         merged.sort();
541         itertools::equal(merged.into_iter(), kmerge(vec![sa, sb, sc]))
542     }
543 
544     // Any number of input iterators
545     fn equal_kmerge_2(mut inputs: Vec<Vec<i16>>) -> bool {
546         use itertools::free::kmerge;
547         // sort the inputs
548         for input in &mut inputs {
549             input.sort();
550         }
551         let mut merged = inputs.concat();
552         merged.sort();
553         itertools::equal(merged.into_iter(), kmerge(inputs))
554     }
555 
556     // Any number of input iterators
557     fn equal_kmerge_by_ge(mut inputs: Vec<Vec<i16>>) -> bool {
558         // sort the inputs
559         for input in &mut inputs {
560             input.sort();
561             input.reverse();
562         }
563         let mut merged = inputs.concat();
564         merged.sort();
565         merged.reverse();
566         itertools::equal(merged.into_iter(),
567                          inputs.into_iter().kmerge_by(|x, y| x >= y))
568     }
569 
570     // Any number of input iterators
571     fn equal_kmerge_by_lt(mut inputs: Vec<Vec<i16>>) -> bool {
572         // sort the inputs
573         for input in &mut inputs {
574             input.sort();
575         }
576         let mut merged = inputs.concat();
577         merged.sort();
578         itertools::equal(merged.into_iter(),
579                          inputs.into_iter().kmerge_by(|x, y| x < y))
580     }
581 
582     // Any number of input iterators
583     fn equal_kmerge_by_le(mut inputs: Vec<Vec<i16>>) -> bool {
584         // sort the inputs
585         for input in &mut inputs {
586             input.sort();
587         }
588         let mut merged = inputs.concat();
589         merged.sort();
590         itertools::equal(merged.into_iter(),
591                          inputs.into_iter().kmerge_by(|x, y| x <= y))
592     }
593     fn size_kmerge(a: Iter<i16>, b: Iter<i16>, c: Iter<i16>) -> bool {
594         use itertools::free::kmerge;
595         correct_size_hint(kmerge(vec![a, b, c]))
596     }
597     fn equal_zip_eq(a: Vec<i32>, b: Vec<i32>) -> bool {
598         let len = std::cmp::min(a.len(), b.len());
599         let a = &a[..len];
600         let b = &b[..len];
601         itertools::equal(zip_eq(a, b), zip(a, b))
602     }
603     fn size_zip_longest(a: Iter<i16, Exact>, b: Iter<i16, Exact>) -> bool {
604         let filt = a.clone().dedup();
605         let filt2 = b.clone().dedup();
606         correct_size_hint(filt.zip_longest(b.clone())) &&
607         correct_size_hint(a.clone().zip_longest(filt2)) &&
608             exact_size(a.zip_longest(b))
609     }
610     fn size_2_zip_longest(a: Iter<i16>, b: Iter<i16>) -> bool {
611         let it = a.clone().zip_longest(b.clone());
612         let jt = a.clone().zip_longest(b.clone());
613         itertools::equal(a.clone(),
614                          it.filter_map(|elt| match elt {
615                              EitherOrBoth::Both(x, _) => Some(x),
616                              EitherOrBoth::Left(x) => Some(x),
617                              _ => None,
618                          }
619                          ))
620             &&
621         itertools::equal(b.clone(),
622                          jt.filter_map(|elt| match elt {
623                              EitherOrBoth::Both(_, y) => Some(y),
624                              EitherOrBoth::Right(y) => Some(y),
625                              _ => None,
626                          }
627                          ))
628     }
629     fn size_interleave(a: Iter<i16>, b: Iter<i16>) -> bool {
630         correct_size_hint(a.interleave(b))
631     }
632     fn exact_interleave(a: Iter<i16, Exact>, b: Iter<i16, Exact>) -> bool {
633         exact_size_for_this(a.interleave(b))
634     }
635     fn size_interleave_shortest(a: Iter<i16>, b: Iter<i16>) -> bool {
636         correct_size_hint(a.interleave_shortest(b))
637     }
638     fn exact_interleave_shortest(a: Vec<()>, b: Vec<()>) -> bool {
639         exact_size_for_this(a.iter().interleave_shortest(&b))
640     }
641     fn size_intersperse(a: Iter<i16>, x: i16) -> bool {
642         correct_size_hint(a.intersperse(x))
643     }
644     fn equal_intersperse(a: Vec<i32>, x: i32) -> bool {
645         let mut inter = false;
646         let mut i = 0;
647         for elt in a.iter().cloned().intersperse(x) {
648             if inter {
649                 if elt != x { return false }
650             } else {
651                 if elt != a[i] { return false }
652                 i += 1;
653             }
654             inter = !inter;
655         }
656         true
657     }
658 
659     fn equal_combinations_2(a: Vec<u8>) -> bool {
660         let mut v = Vec::new();
661         for (i, x) in enumerate(&a) {
662             for y in &a[i + 1..] {
663                 v.push((x, y));
664             }
665         }
666         itertools::equal(a.iter().tuple_combinations::<(_, _)>(), v)
667     }
668 
669     fn collect_tuple_matches_size(a: Iter<i16>) -> bool {
670         let size = a.clone().count();
671         a.collect_tuple::<(_, _, _)>().is_some() == (size == 3)
672     }
673 
674     fn correct_permutations(vals: HashSet<i32>, k: usize) -> () {
675         // Test permutations only on iterators of distinct integers, to prevent
676         // false positives.
677 
678         const MAX_N: usize = 5;
679 
680         let n = min(vals.len(), MAX_N);
681         let vals: HashSet<i32> = vals.into_iter().take(n).collect();
682 
683         let perms = vals.iter().permutations(k);
684 
685         let mut actual = HashSet::new();
686 
687         for perm in perms {
688             assert_eq!(perm.len(), k);
689 
690             let all_items_valid = perm.iter().all(|p| vals.contains(p));
691             assert!(all_items_valid, "perm contains value not from input: {:?}", perm);
692 
693             // Check that all perm items are distinct
694             let distinct_len = {
695                 let perm_set: HashSet<_> = perm.iter().collect();
696                 perm_set.len()
697             };
698             assert_eq!(perm.len(), distinct_len);
699 
700             // Check that the perm is new
701             assert!(actual.insert(perm.clone()), "perm already encountered: {:?}", perm);
702         }
703     }
704 
705     fn permutations_lexic_order(a: usize, b: usize) -> () {
706         let a = a % 6;
707         let b = b % 6;
708 
709         let n = max(a, b);
710         let k = min (a, b);
711 
712         let expected_first: Vec<usize> = (0..k).collect();
713         let expected_last: Vec<usize> = ((n - k)..n).rev().collect();
714 
715         let mut perms = (0..n).permutations(k);
716 
717         let mut curr_perm = match perms.next() {
718             Some(p) => p,
719             None => { return; }
720         };
721 
722         assert_eq!(expected_first, curr_perm);
723 
724         while let Some(next_perm) = perms.next() {
725             assert!(
726                 next_perm > curr_perm,
727                 "next perm isn't greater-than current; next_perm={:?} curr_perm={:?} n={}",
728                 next_perm, curr_perm, n
729             );
730 
731             curr_perm = next_perm;
732         }
733 
734         assert_eq!(expected_last, curr_perm);
735 
736     }
737 
738     fn permutations_count(n: usize, k: usize) -> bool {
739         let n = n % 6;
740 
741         correct_count(|| (0..n).permutations(k))
742     }
743 
744     fn permutations_size(a: Iter<i32>, k: usize) -> bool {
745         correct_size_hint(a.take(5).permutations(k))
746     }
747 
748     fn permutations_k0_yields_once(n: usize) -> () {
749         let k = 0;
750         let expected: Vec<Vec<usize>> = vec![vec![]];
751         let actual = (0..n).permutations(k).collect_vec();
752 
753         assert_eq!(expected, actual);
754     }
755 }
756 
757 quickcheck! {
758     fn dedup_via_coalesce(a: Vec<i32>) -> bool {
759         let mut b = a.clone();
760         b.dedup();
761         itertools::equal(
762             &b,
763             a
764                 .iter()
765                 .coalesce(|x, y| {
766                     if x==y {
767                         Ok(x)
768                     } else {
769                         Err((x, y))
770                     }
771                 })
772                 .fold(vec![], |mut v, n| {
773                     v.push(n);
774                     v
775                 })
776         )
777     }
778 }
779 
780 quickcheck! {
781     fn equal_dedup(a: Vec<i32>) -> bool {
782         let mut b = a.clone();
783         b.dedup();
784         itertools::equal(&b, a.iter().dedup())
785     }
786 }
787 
788 quickcheck! {
789     fn equal_dedup_by(a: Vec<(i32, i32)>) -> bool {
790         let mut b = a.clone();
791         b.dedup_by(|x, y| x.0==y.0);
792         itertools::equal(&b, a.iter().dedup_by(|x, y| x.0==y.0))
793     }
794 }
795 
796 quickcheck! {
797     fn size_dedup(a: Vec<i32>) -> bool {
798         correct_size_hint(a.iter().dedup())
799     }
800 }
801 
802 quickcheck! {
803     fn size_dedup_by(a: Vec<(i32, i32)>) -> bool {
804         correct_size_hint(a.iter().dedup_by(|x, y| x.0==y.0))
805     }
806 }
807 
808 quickcheck! {
809     fn exact_repeatn((n, x): (usize, i32)) -> bool {
810         let it = itertools::repeat_n(x, n);
811         exact_size(it)
812     }
813 }
814 
815 quickcheck! {
816     fn size_put_back(a: Vec<u8>, x: Option<u8>) -> bool {
817         let mut it = put_back(a.into_iter());
818         match x {
819             Some(t) => it.put_back(t),
820             None => {}
821         }
822         correct_size_hint(it)
823     }
824 }
825 
826 quickcheck! {
827     fn size_put_backn(a: Vec<u8>, b: Vec<u8>) -> bool {
828         let mut it = put_back_n(a.into_iter());
829         for elt in b {
830             it.put_back(elt)
831         }
832         correct_size_hint(it)
833     }
834 }
835 
836 quickcheck! {
837     fn size_tee(a: Vec<u8>) -> bool {
838         let (mut t1, mut t2) = a.iter().tee();
839         t1.next();
840         t1.next();
841         t2.next();
842         exact_size(t1) && exact_size(t2)
843     }
844 }
845 
846 quickcheck! {
847     fn size_tee_2(a: Vec<u8>) -> bool {
848         let (mut t1, mut t2) = a.iter().dedup().tee();
849         t1.next();
850         t1.next();
851         t2.next();
852         correct_size_hint(t1) && correct_size_hint(t2)
853     }
854 }
855 
856 quickcheck! {
857     fn size_take_while_ref(a: Vec<u8>, stop: u8) -> bool {
858         correct_size_hint(a.iter().take_while_ref(|x| **x != stop))
859     }
860 }
861 
862 quickcheck! {
863     fn equal_partition(a: Vec<i32>) -> bool {
864         let mut a = a;
865         let mut ap = a.clone();
866         let split_index = itertools::partition(&mut ap, |x| *x >= 0);
867         let parted = (0..split_index).all(|i| ap[i] >= 0) &&
868             (split_index..a.len()).all(|i| ap[i] < 0);
869 
870         a.sort();
871         ap.sort();
872         parted && (a == ap)
873     }
874 }
875 
876 quickcheck! {
877     fn size_combinations(it: Iter<i16>) -> bool {
878         correct_size_hint(it.tuple_combinations::<(_, _)>())
879     }
880 }
881 
882 quickcheck! {
883     fn equal_combinations(it: Iter<i16>) -> bool {
884         let values = it.clone().collect_vec();
885         let mut cmb = it.tuple_combinations();
886         for i in 0..values.len() {
887             for j in i+1..values.len() {
888                 let pair = (values[i], values[j]);
889                 if pair != cmb.next().unwrap() {
890                     return false;
891                 }
892             }
893         }
894         cmb.next() == None
895     }
896 }
897 
898 quickcheck! {
899     fn size_pad_tail(it: Iter<i8>, pad: u8) -> bool {
900         correct_size_hint(it.clone().pad_using(pad as usize, |_| 0)) &&
901             correct_size_hint(it.dropping(1).rev().pad_using(pad as usize, |_| 0))
902     }
903 }
904 
905 quickcheck! {
906     fn size_pad_tail2(it: Iter<i8, Exact>, pad: u8) -> bool {
907         exact_size(it.pad_using(pad as usize, |_| 0))
908     }
909 }
910 
911 quickcheck! {
912     fn size_powerset(it: Iter<u8, Exact>) -> bool {
913         // Powerset cardinality gets large very quickly, limit input to keep test fast.
914         correct_size_hint(it.take(12).powerset())
915     }
916 }
917 
918 quickcheck! {
919     fn size_duplicates(it: Iter<i8>) -> bool {
920         correct_size_hint(it.duplicates())
921     }
922 }
923 
924 quickcheck! {
925     fn size_unique(it: Iter<i8>) -> bool {
926         correct_size_hint(it.unique())
927     }
928 
929     fn count_unique(it: Vec<i8>, take_first: u8) -> () {
930         let answer = {
931             let mut v = it.clone();
932             v.sort(); v.dedup();
933             v.len()
934         };
935         let mut iter = cloned(&it).unique();
936         let first_count = (&mut iter).take(take_first as usize).count();
937         let rest_count = iter.count();
938         assert_eq!(answer, first_count + rest_count);
939     }
940 }
941 
942 quickcheck! {
943     fn fuzz_group_by_lazy_1(it: Iter<u8>) -> bool {
944         let jt = it.clone();
945         let groups = it.group_by(|k| *k);
946         let res = itertools::equal(jt, groups.into_iter().flat_map(|(_, x)| x));
947         res
948     }
949 }
950 
951 quickcheck! {
952     fn fuzz_group_by_lazy_2(data: Vec<u8>) -> bool {
953         let groups = data.iter().group_by(|k| *k / 10);
954         let res = itertools::equal(data.iter(), groups.into_iter().flat_map(|(_, x)| x));
955         res
956     }
957 }
958 
959 quickcheck! {
960     fn fuzz_group_by_lazy_3(data: Vec<u8>) -> bool {
961         let grouper = data.iter().group_by(|k| *k / 10);
962         let groups = grouper.into_iter().collect_vec();
963         let res = itertools::equal(data.iter(), groups.into_iter().flat_map(|(_, x)| x));
964         res
965     }
966 }
967 
968 quickcheck! {
969     fn fuzz_group_by_lazy_duo(data: Vec<u8>, order: Vec<(bool, bool)>) -> bool {
970         let grouper = data.iter().group_by(|k| *k / 3);
971         let mut groups1 = grouper.into_iter();
972         let mut groups2 = grouper.into_iter();
973         let mut elts = Vec::<&u8>::new();
974         let mut old_groups = Vec::new();
975 
976         let tup1 = |(_, b)| b;
977         for &(ord, consume_now) in &order {
978             let iter = &mut [&mut groups1, &mut groups2][ord as usize];
979             match iter.next() {
980                 Some((_, gr)) => if consume_now {
981                     for og in old_groups.drain(..) {
982                         elts.extend(og);
983                     }
984                     elts.extend(gr);
985                 } else {
986                     old_groups.push(gr);
987                 },
988                 None => break,
989             }
990         }
991         for og in old_groups.drain(..) {
992             elts.extend(og);
993         }
994         for gr in groups1.map(&tup1) { elts.extend(gr); }
995         for gr in groups2.map(&tup1) { elts.extend(gr); }
996         itertools::assert_equal(&data, elts);
997         true
998     }
999 }
1000 
1001 quickcheck! {
1002     fn equal_chunks_lazy(a: Vec<u8>, size: u8) -> bool {
1003         let mut size = size;
1004         if size == 0 {
1005             size += 1;
1006         }
1007         let chunks = a.iter().chunks(size as usize);
1008         let it = a.chunks(size as usize);
1009         for (a, b) in chunks.into_iter().zip(it) {
1010             if !itertools::equal(a, b) {
1011                 return false;
1012             }
1013         }
1014         true
1015     }
1016 }
1017 
1018 quickcheck! {
1019     fn equal_tuple_windows_1(a: Vec<u8>) -> bool {
1020         let x = a.windows(1).map(|s| (&s[0], ));
1021         let y = a.iter().tuple_windows::<(_,)>();
1022         itertools::equal(x, y)
1023     }
1024 
1025     fn equal_tuple_windows_2(a: Vec<u8>) -> bool {
1026         let x = a.windows(2).map(|s| (&s[0], &s[1]));
1027         let y = a.iter().tuple_windows::<(_, _)>();
1028         itertools::equal(x, y)
1029     }
1030 
1031     fn equal_tuple_windows_3(a: Vec<u8>) -> bool {
1032         let x = a.windows(3).map(|s| (&s[0], &s[1], &s[2]));
1033         let y = a.iter().tuple_windows::<(_, _, _)>();
1034         itertools::equal(x, y)
1035     }
1036 
1037     fn equal_tuple_windows_4(a: Vec<u8>) -> bool {
1038         let x = a.windows(4).map(|s| (&s[0], &s[1], &s[2], &s[3]));
1039         let y = a.iter().tuple_windows::<(_, _, _, _)>();
1040         itertools::equal(x, y)
1041     }
1042 
1043     fn equal_tuples_1(a: Vec<u8>) -> bool {
1044         let x = a.chunks(1).map(|s| (&s[0], ));
1045         let y = a.iter().tuples::<(_,)>();
1046         itertools::equal(x, y)
1047     }
1048 
1049     fn equal_tuples_2(a: Vec<u8>) -> bool {
1050         let x = a.chunks(2).filter(|s| s.len() == 2).map(|s| (&s[0], &s[1]));
1051         let y = a.iter().tuples::<(_, _)>();
1052         itertools::equal(x, y)
1053     }
1054 
1055     fn equal_tuples_3(a: Vec<u8>) -> bool {
1056         let x = a.chunks(3).filter(|s| s.len() == 3).map(|s| (&s[0], &s[1], &s[2]));
1057         let y = a.iter().tuples::<(_, _, _)>();
1058         itertools::equal(x, y)
1059     }
1060 
1061     fn equal_tuples_4(a: Vec<u8>) -> bool {
1062         let x = a.chunks(4).filter(|s| s.len() == 4).map(|s| (&s[0], &s[1], &s[2], &s[3]));
1063         let y = a.iter().tuples::<(_, _, _, _)>();
1064         itertools::equal(x, y)
1065     }
1066 
1067     fn exact_tuple_buffer(a: Vec<u8>) -> bool {
1068         let mut iter = a.iter().tuples::<(_, _, _, _)>();
1069         (&mut iter).last();
1070         let buffer = iter.into_buffer();
1071         assert_eq!(buffer.len(), a.len() % 4);
1072         exact_size(buffer)
1073     }
1074 }
1075 
1076 // with_position
1077 quickcheck! {
1078     fn with_position_exact_size_1(a: Vec<u8>) -> bool {
1079         exact_size_for_this(a.iter().with_position())
1080     }
1081     fn with_position_exact_size_2(a: Iter<u8, Exact>) -> bool {
1082         exact_size_for_this(a.with_position())
1083     }
1084 }
1085 
1086 quickcheck! {
1087     fn correct_group_map_modulo_key(a: Vec<u8>, modulo: u8) -> () {
1088         let modulo = if modulo == 0 { 1 } else { modulo }; // Avoid `% 0`
1089         let count = a.len();
1090         let lookup = a.into_iter().map(|i| (i % modulo, i)).into_group_map();
1091 
1092         assert_eq!(lookup.values().flat_map(|vals| vals.iter()).count(), count);
1093 
1094         for (&key, vals) in lookup.iter() {
1095             assert!(vals.iter().all(|&val| val % modulo == key));
1096         }
1097     }
1098 }
1099 
1100 /// A peculiar type: Equality compares both tuple items, but ordering only the
1101 /// first item.  This is so we can check the stability property easily.
1102 #[derive(Clone, Debug, PartialEq, Eq)]
1103 struct Val(u32, u32);
1104 
1105 impl PartialOrd<Val> for Val {
partial_cmp(&self, other: &Val) -> Option<Ordering>1106     fn partial_cmp(&self, other: &Val) -> Option<Ordering> {
1107         self.0.partial_cmp(&other.0)
1108     }
1109 }
1110 
1111 impl Ord for Val {
cmp(&self, other: &Val) -> Ordering1112     fn cmp(&self, other: &Val) -> Ordering {
1113         self.0.cmp(&other.0)
1114     }
1115 }
1116 
1117 impl qc::Arbitrary for Val {
arbitrary<G: qc::Gen>(g: &mut G) -> Self1118     fn arbitrary<G: qc::Gen>(g: &mut G) -> Self {
1119         let (x, y) = <(u32, u32)>::arbitrary(g);
1120         Val(x, y)
1121     }
shrink(&self) -> Box<dyn Iterator<Item = Self>>1122     fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
1123         Box::new((self.0, self.1).shrink().map(|(x, y)| Val(x, y)))
1124     }
1125 }
1126 
1127 quickcheck! {
1128     fn minmax(a: Vec<Val>) -> bool {
1129         use itertools::MinMaxResult;
1130 
1131 
1132         let minmax = a.iter().minmax();
1133         let expected = match a.len() {
1134             0 => MinMaxResult::NoElements,
1135             1 => MinMaxResult::OneElement(&a[0]),
1136             _ => MinMaxResult::MinMax(a.iter().min().unwrap(),
1137                                       a.iter().max().unwrap()),
1138         };
1139         minmax == expected
1140     }
1141 }
1142 
1143 quickcheck! {
1144     fn minmax_f64(a: Vec<f64>) -> TestResult {
1145         use itertools::MinMaxResult;
1146 
1147         if a.iter().any(|x| x.is_nan()) {
1148             return TestResult::discard();
1149         }
1150 
1151         let min = cloned(&a).fold1(f64::min);
1152         let max = cloned(&a).fold1(f64::max);
1153 
1154         let minmax = cloned(&a).minmax();
1155         let expected = match a.len() {
1156             0 => MinMaxResult::NoElements,
1157             1 => MinMaxResult::OneElement(min.unwrap()),
1158             _ => MinMaxResult::MinMax(min.unwrap(), max.unwrap()),
1159         };
1160         TestResult::from_bool(minmax == expected)
1161     }
1162 }
1163 
1164 quickcheck! {
1165     #[allow(deprecated)]
1166     fn tree_fold1_f64(mut a: Vec<f64>) -> TestResult {
1167         fn collapse_adjacent<F>(x: Vec<f64>, mut f: F) -> Vec<f64>
1168             where F: FnMut(f64, f64) -> f64
1169         {
1170             let mut out = Vec::new();
1171             for i in (0..x.len()).step(2) {
1172                 if i == x.len()-1 {
1173                     out.push(x[i])
1174                 } else {
1175                     out.push(f(x[i], x[i+1]));
1176                 }
1177             }
1178             out
1179         }
1180 
1181         if a.iter().any(|x| x.is_nan()) {
1182             return TestResult::discard();
1183         }
1184 
1185         let actual = a.iter().cloned().tree_fold1(f64::atan2);
1186 
1187         while a.len() > 1 {
1188             a = collapse_adjacent(a, f64::atan2);
1189         }
1190         let expected = a.pop();
1191 
1192         TestResult::from_bool(actual == expected)
1193     }
1194 }
1195 
1196 quickcheck! {
1197     fn exactly_one_i32(a: Vec<i32>) -> TestResult {
1198         let ret = a.iter().cloned().exactly_one();
1199         match a.len() {
1200             1 => TestResult::from_bool(ret.unwrap() == a[0]),
1201             _ => TestResult::from_bool(ret.unwrap_err().eq(a.iter().cloned())),
1202         }
1203     }
1204 }
1205 
1206 quickcheck! {
1207     fn at_most_one_i32(a: Vec<i32>) -> TestResult {
1208         let ret = a.iter().cloned().at_most_one();
1209         match a.len() {
1210             0 => TestResult::from_bool(ret.unwrap() == None),
1211             1 => TestResult::from_bool(ret.unwrap() == Some(a[0])),
1212             _ => TestResult::from_bool(ret.unwrap_err().eq(a.iter().cloned())),
1213         }
1214     }
1215 }
1216 
1217 quickcheck! {
1218     fn consistent_grouping_map_with_by(a: Vec<u8>, modulo: u8) -> () {
1219         let modulo = if modulo == 0 { 1 } else { modulo }; // Avoid `% 0`
1220 
1221         let lookup_grouping_map = a.iter().copied().map(|i| (i % modulo, i)).into_grouping_map().collect::<Vec<_>>();
1222         let lookup_grouping_map_by = a.iter().copied().into_grouping_map_by(|i| i % modulo).collect::<Vec<_>>();
1223 
1224         assert_eq!(lookup_grouping_map, lookup_grouping_map_by);
1225     }
1226 
1227     fn correct_grouping_map_by_aggregate_modulo_key(a: Vec<u8>, modulo: u8) -> () {
1228         let modulo = if modulo < 2 { 2 } else { modulo } as u64; // Avoid `% 0`
1229         let lookup = a.iter()
1230             .map(|&b| b as u64) // Avoid overflows
1231             .into_grouping_map_by(|i| i % modulo)
1232             .aggregate(|acc, &key, val| {
1233                 assert!(val % modulo == key);
1234                 if val % (modulo - 1) == 0 {
1235                     None
1236                 } else {
1237                     Some(acc.unwrap_or(0) + val)
1238                 }
1239             });
1240 
1241         let group_map_lookup = a.iter()
1242             .map(|&b| b as u64)
1243             .map(|i| (i % modulo, i))
1244             .into_group_map()
1245             .into_iter()
1246             .filter_map(|(key, vals)| {
1247                 vals.into_iter().fold(None, |acc, val| {
1248                     if val % (modulo - 1) == 0 {
1249                         None
1250                     } else {
1251                         Some(acc.unwrap_or(0) + val)
1252                     }
1253                 }).map(|new_val| (key, new_val))
1254             })
1255             .collect::<HashMap<_,_>>();
1256         assert_eq!(lookup, group_map_lookup);
1257 
1258         for m in 0..modulo {
1259             assert_eq!(
1260                 lookup.get(&m).copied(),
1261                 a.iter()
1262                     .map(|&b| b as u64)
1263                     .filter(|&val| val % modulo == m)
1264                     .fold(None, |acc, val| {
1265                         if val % (modulo - 1) == 0 {
1266                             None
1267                         } else {
1268                             Some(acc.unwrap_or(0) + val)
1269                         }
1270                     })
1271             );
1272         }
1273     }
1274 
1275     fn correct_grouping_map_by_fold_modulo_key(a: Vec<u8>, modulo: u8) -> () {
1276         let modulo = if modulo == 0 { 1 } else { modulo } as u64; // Avoid `% 0`
1277         let lookup = a.iter().map(|&b| b as u64) // Avoid overflows
1278             .into_grouping_map_by(|i| i % modulo)
1279             .fold(0u64, |acc, &key, val| {
1280                 assert!(val % modulo == key);
1281                 acc + val
1282             });
1283 
1284         let group_map_lookup = a.iter()
1285             .map(|&b| b as u64)
1286             .map(|i| (i % modulo, i))
1287             .into_group_map()
1288             .into_iter()
1289             .map(|(key, vals)| (key, vals.into_iter().fold(0u64, |acc, val| acc + val)))
1290             .collect::<HashMap<_,_>>();
1291         assert_eq!(lookup, group_map_lookup);
1292 
1293         for (&key, &sum) in lookup.iter() {
1294             assert_eq!(sum, a.iter().map(|&b| b as u64).filter(|&val| val % modulo == key).sum::<u64>());
1295         }
1296     }
1297 
1298     fn correct_grouping_map_by_fold_first_modulo_key(a: Vec<u8>, modulo: u8) -> () {
1299         let modulo = if modulo == 0 { 1 } else { modulo } as u64; // Avoid `% 0`
1300         let lookup = a.iter().map(|&b| b as u64) // Avoid overflows
1301             .into_grouping_map_by(|i| i % modulo)
1302             .fold_first(|acc, &key, val| {
1303                 assert!(val % modulo == key);
1304                 acc + val
1305             });
1306 
1307         // TODO: Swap `fold1` with stdlib's `fold_first` when it's stabilized
1308         let group_map_lookup = a.iter()
1309             .map(|&b| b as u64)
1310             .map(|i| (i % modulo, i))
1311             .into_group_map()
1312             .into_iter()
1313             .map(|(key, vals)| (key, vals.into_iter().fold1(|acc, val| acc + val).unwrap()))
1314             .collect::<HashMap<_,_>>();
1315         assert_eq!(lookup, group_map_lookup);
1316 
1317         for (&key, &sum) in lookup.iter() {
1318             assert_eq!(sum, a.iter().map(|&b| b as u64).filter(|&val| val % modulo == key).sum::<u64>());
1319         }
1320     }
1321 
1322     fn correct_grouping_map_by_collect_modulo_key(a: Vec<u8>, modulo: u8) -> () {
1323         let modulo = if modulo == 0 { 1 } else { modulo }; // Avoid `% 0`
1324         let lookup_grouping_map = a.iter().copied().into_grouping_map_by(|i| i % modulo).collect::<Vec<_>>();
1325         let lookup_group_map = a.iter().copied().map(|i| (i % modulo, i)).into_group_map();
1326 
1327         assert_eq!(lookup_grouping_map, lookup_group_map);
1328     }
1329 
1330     fn correct_grouping_map_by_max_modulo_key(a: Vec<u8>, modulo: u8) -> () {
1331         let modulo = if modulo == 0 { 1 } else { modulo }; // Avoid `% 0`
1332         let lookup = a.iter().copied().into_grouping_map_by(|i| i % modulo).max();
1333 
1334         let group_map_lookup = a.iter().copied()
1335             .map(|i| (i % modulo, i))
1336             .into_group_map()
1337             .into_iter()
1338             .map(|(key, vals)| (key, vals.into_iter().max().unwrap()))
1339             .collect::<HashMap<_,_>>();
1340         assert_eq!(lookup, group_map_lookup);
1341 
1342         for (&key, &max) in lookup.iter() {
1343             assert_eq!(Some(max), a.iter().copied().filter(|&val| val % modulo == key).max());
1344         }
1345     }
1346 
1347     fn correct_grouping_map_by_max_by_modulo_key(a: Vec<u8>, modulo: u8) -> () {
1348         let modulo = if modulo == 0 { 1 } else { modulo }; // Avoid `% 0`
1349         let lookup = a.iter().copied().into_grouping_map_by(|i| i % modulo).max_by(|_, v1, v2| v1.cmp(v2));
1350 
1351         let group_map_lookup = a.iter().copied()
1352             .map(|i| (i % modulo, i))
1353             .into_group_map()
1354             .into_iter()
1355             .map(|(key, vals)| (key, vals.into_iter().max_by(|v1, v2| v1.cmp(v2)).unwrap()))
1356             .collect::<HashMap<_,_>>();
1357         assert_eq!(lookup, group_map_lookup);
1358 
1359         for (&key, &max) in lookup.iter() {
1360             assert_eq!(Some(max), a.iter().copied().filter(|&val| val % modulo == key).max_by(|v1, v2| v1.cmp(v2)));
1361         }
1362     }
1363 
1364     fn correct_grouping_map_by_max_by_key_modulo_key(a: Vec<u8>, modulo: u8) -> () {
1365         let modulo = if modulo == 0 { 1 } else { modulo }; // Avoid `% 0`
1366         let lookup = a.iter().copied().into_grouping_map_by(|i| i % modulo).max_by_key(|_, &val| val);
1367 
1368         let group_map_lookup = a.iter().copied()
1369             .map(|i| (i % modulo, i))
1370             .into_group_map()
1371             .into_iter()
1372             .map(|(key, vals)| (key, vals.into_iter().max_by_key(|&val| val).unwrap()))
1373             .collect::<HashMap<_,_>>();
1374         assert_eq!(lookup, group_map_lookup);
1375 
1376         for (&key, &max) in lookup.iter() {
1377             assert_eq!(Some(max), a.iter().copied().filter(|&val| val % modulo == key).max_by_key(|&val| val));
1378         }
1379     }
1380 
1381     fn correct_grouping_map_by_min_modulo_key(a: Vec<u8>, modulo: u8) -> () {
1382         let modulo = if modulo == 0 { 1 } else { modulo }; // Avoid `% 0`
1383         let lookup = a.iter().copied().into_grouping_map_by(|i| i % modulo).min();
1384 
1385         let group_map_lookup = a.iter().copied()
1386             .map(|i| (i % modulo, i))
1387             .into_group_map()
1388             .into_iter()
1389             .map(|(key, vals)| (key, vals.into_iter().min().unwrap()))
1390             .collect::<HashMap<_,_>>();
1391         assert_eq!(lookup, group_map_lookup);
1392 
1393         for (&key, &min) in lookup.iter() {
1394             assert_eq!(Some(min), a.iter().copied().filter(|&val| val % modulo == key).min());
1395         }
1396     }
1397 
1398     fn correct_grouping_map_by_min_by_modulo_key(a: Vec<u8>, modulo: u8) -> () {
1399         let modulo = if modulo == 0 { 1 } else { modulo }; // Avoid `% 0`
1400         let lookup = a.iter().copied().into_grouping_map_by(|i| i % modulo).min_by(|_, v1, v2| v1.cmp(v2));
1401 
1402         let group_map_lookup = a.iter().copied()
1403             .map(|i| (i % modulo, i))
1404             .into_group_map()
1405             .into_iter()
1406             .map(|(key, vals)| (key, vals.into_iter().min_by(|v1, v2| v1.cmp(v2)).unwrap()))
1407             .collect::<HashMap<_,_>>();
1408         assert_eq!(lookup, group_map_lookup);
1409 
1410         for (&key, &min) in lookup.iter() {
1411             assert_eq!(Some(min), a.iter().copied().filter(|&val| val % modulo == key).min_by(|v1, v2| v1.cmp(v2)));
1412         }
1413     }
1414 
1415     fn correct_grouping_map_by_min_by_key_modulo_key(a: Vec<u8>, modulo: u8) -> () {
1416         let modulo = if modulo == 0 { 1 } else { modulo }; // Avoid `% 0`
1417         let lookup = a.iter().copied().into_grouping_map_by(|i| i % modulo).min_by_key(|_, &val| val);
1418 
1419         let group_map_lookup = a.iter().copied()
1420             .map(|i| (i % modulo, i))
1421             .into_group_map()
1422             .into_iter()
1423             .map(|(key, vals)| (key, vals.into_iter().min_by_key(|&val| val).unwrap()))
1424             .collect::<HashMap<_,_>>();
1425         assert_eq!(lookup, group_map_lookup);
1426 
1427         for (&key, &min) in lookup.iter() {
1428             assert_eq!(Some(min), a.iter().copied().filter(|&val| val % modulo == key).min_by_key(|&val| val));
1429         }
1430     }
1431 
1432     fn correct_grouping_map_by_minmax_modulo_key(a: Vec<u8>, modulo: u8) -> () {
1433         let modulo = if modulo == 0 { 1 } else { modulo }; // Avoid `% 0`
1434         let lookup = a.iter().copied().into_grouping_map_by(|i| i % modulo).minmax();
1435 
1436         let group_map_lookup = a.iter().copied()
1437             .map(|i| (i % modulo, i))
1438             .into_group_map()
1439             .into_iter()
1440             .map(|(key, vals)| (key, vals.into_iter().minmax()))
1441             .collect::<HashMap<_,_>>();
1442         assert_eq!(lookup, group_map_lookup);
1443 
1444         for (&key, &minmax) in lookup.iter() {
1445             assert_eq!(minmax, a.iter().copied().filter(|&val| val % modulo == key).minmax());
1446         }
1447     }
1448 
1449     fn correct_grouping_map_by_minmax_by_modulo_key(a: Vec<u8>, modulo: u8) -> () {
1450         let modulo = if modulo == 0 { 1 } else { modulo }; // Avoid `% 0`
1451         let lookup = a.iter().copied().into_grouping_map_by(|i| i % modulo).minmax_by(|_, v1, v2| v1.cmp(v2));
1452 
1453         let group_map_lookup = a.iter().copied()
1454             .map(|i| (i % modulo, i))
1455             .into_group_map()
1456             .into_iter()
1457             .map(|(key, vals)| (key, vals.into_iter().minmax_by(|v1, v2| v1.cmp(v2))))
1458             .collect::<HashMap<_,_>>();
1459         assert_eq!(lookup, group_map_lookup);
1460 
1461         for (&key, &minmax) in lookup.iter() {
1462             assert_eq!(minmax, a.iter().copied().filter(|&val| val % modulo == key).minmax_by(|v1, v2| v1.cmp(v2)));
1463         }
1464     }
1465 
1466     fn correct_grouping_map_by_minmax_by_key_modulo_key(a: Vec<u8>, modulo: u8) -> () {
1467         let modulo = if modulo == 0 { 1 } else { modulo }; // Avoid `% 0`
1468         let lookup = a.iter().copied().into_grouping_map_by(|i| i % modulo).minmax_by_key(|_, &val| val);
1469 
1470         let group_map_lookup = a.iter().copied()
1471             .map(|i| (i % modulo, i))
1472             .into_group_map()
1473             .into_iter()
1474             .map(|(key, vals)| (key, vals.into_iter().minmax_by_key(|&val| val)))
1475             .collect::<HashMap<_,_>>();
1476         assert_eq!(lookup, group_map_lookup);
1477 
1478         for (&key, &minmax) in lookup.iter() {
1479             assert_eq!(minmax, a.iter().copied().filter(|&val| val % modulo == key).minmax_by_key(|&val| val));
1480         }
1481     }
1482 
1483     fn correct_grouping_map_by_sum_modulo_key(a: Vec<u8>, modulo: u8) -> () {
1484         let modulo = if modulo == 0 { 1 } else { modulo } as u64; // Avoid `% 0`
1485         let lookup = a.iter().map(|&b| b as u64) // Avoid overflows
1486             .into_grouping_map_by(|i| i % modulo)
1487             .sum();
1488 
1489         let group_map_lookup = a.iter().map(|&b| b as u64)
1490             .map(|i| (i % modulo, i))
1491             .into_group_map()
1492             .into_iter()
1493             .map(|(key, vals)| (key, vals.into_iter().sum()))
1494             .collect::<HashMap<_,_>>();
1495         assert_eq!(lookup, group_map_lookup);
1496 
1497         for (&key, &sum) in lookup.iter() {
1498             assert_eq!(sum, a.iter().map(|&b| b as u64).filter(|&val| val % modulo == key).sum::<u64>());
1499         }
1500     }
1501 
1502     fn correct_grouping_map_by_product_modulo_key(a: Vec<u8>, modulo: u8) -> () {
1503         let modulo = Wrapping(if modulo == 0 { 1 } else { modulo } as u64); // Avoid `% 0`
1504         let lookup = a.iter().map(|&b| Wrapping(b as u64)) // Avoid overflows
1505             .into_grouping_map_by(|i| i % modulo)
1506             .product();
1507 
1508         let group_map_lookup = a.iter().map(|&b| Wrapping(b as u64))
1509             .map(|i| (i % modulo, i))
1510             .into_group_map()
1511             .into_iter()
1512             .map(|(key, vals)| (key, vals.into_iter().product::<Wrapping<u64>>()))
1513             .collect::<HashMap<_,_>>();
1514         assert_eq!(lookup, group_map_lookup);
1515 
1516         for (&key, &prod) in lookup.iter() {
1517             assert_eq!(
1518                 prod,
1519                 a.iter()
1520                     .map(|&b| Wrapping(b as u64))
1521                     .filter(|&val| val % modulo == key)
1522                     .product::<Wrapping<u64>>()
1523             );
1524         }
1525     }
1526 
1527     // This should check that if multiple elements are equally minimum or maximum
1528     // then `max`, `min` and `minmax` pick the first minimum and the last maximum.
1529     // This is to be consistent with `std::iter::max` and `std::iter::min`.
1530     fn correct_grouping_map_by_min_max_minmax_order_modulo_key() -> () {
1531         use itertools::MinMaxResult;
1532 
1533         let lookup = (0..=10)
1534             .into_grouping_map_by(|_| 0)
1535             .max_by(|_, _, _| Ordering::Equal);
1536 
1537         assert_eq!(lookup[&0], 10);
1538 
1539         let lookup = (0..=10)
1540             .into_grouping_map_by(|_| 0)
1541             .min_by(|_, _, _| Ordering::Equal);
1542 
1543         assert_eq!(lookup[&0], 0);
1544 
1545         let lookup = (0..=10)
1546             .into_grouping_map_by(|_| 0)
1547             .minmax_by(|_, _, _| Ordering::Equal);
1548 
1549         assert_eq!(lookup[&0], MinMaxResult::MinMax(0, 10));
1550     }
1551 }
1552 
1553 quickcheck! {
1554     #[test]
1555     fn counts(nums: Vec<isize>) -> TestResult {
1556         let counts = nums.iter().counts();
1557         for (&item, &count) in counts.iter() {
1558             if count <= 0 {
1559                 return TestResult::failed();
1560             }
1561             if count != nums.iter().filter(|&x| x == item).count() {
1562                 return TestResult::failed();
1563             }
1564         }
1565         for item in nums.iter() {
1566             if !counts.contains_key(item) {
1567                 return TestResult::failed();
1568             }
1569         }
1570         TestResult::passed()
1571     }
1572 }
1573 
1574 quickcheck! {
1575     fn test_double_ended_zip_2(a: Vec<u8>, b: Vec<u8>) -> TestResult {
1576         let mut x =
1577           multizip((a.clone().into_iter(), b.clone().into_iter()))
1578             .collect_vec();
1579         x.reverse();
1580 
1581         let y =
1582           multizip((a.into_iter(), b.into_iter()))
1583           .rfold(Vec::new(), |mut vec, e| { vec.push(e); vec });
1584 
1585         TestResult::from_bool(itertools::equal(x, y))
1586     }
1587 
1588     fn test_double_ended_zip_3(a: Vec<u8>, b: Vec<u8>, c: Vec<u8>) -> TestResult {
1589         let mut x =
1590           multizip((a.clone().into_iter(), b.clone().into_iter(), c.clone().into_iter()))
1591             .collect_vec();
1592         x.reverse();
1593 
1594         let y =
1595           multizip((a.into_iter(), b.into_iter(), c.into_iter()))
1596           .rfold(Vec::new(), |mut vec, e| { vec.push(e); vec });
1597 
1598         TestResult::from_bool(itertools::equal(x, y))
1599     }
1600 }
1601 
1602 
is_fused<I: Iterator>(mut it: I) -> bool1603 fn is_fused<I: Iterator>(mut it: I) -> bool
1604 {
1605     while let Some(_) = it.next() {}
1606     for _ in 0..10{
1607         if it.next().is_some(){
1608             return false;
1609         }
1610     }
1611     true
1612 }
1613 
1614 quickcheck! {
1615     fn fused_combination(a: Iter<i16>) -> bool
1616     {
1617         is_fused(a.clone().combinations(1)) &&
1618         is_fused(a.combinations(3))
1619     }
1620 
1621     fn fused_combination_with_replacement(a: Iter<i16>) -> bool
1622     {
1623         is_fused(a.clone().combinations_with_replacement(1)) &&
1624         is_fused(a.combinations_with_replacement(3))
1625     }
1626 
1627     fn fused_tuple_combination(a: Iter<i16>) -> bool
1628     {
1629         is_fused(a.clone().fuse().tuple_combinations::<(_,)>()) &&
1630         is_fused(a.fuse().tuple_combinations::<(_,_,_)>())
1631     }
1632 
1633     fn fused_unique(a: Iter<i16>) -> bool
1634     {
1635         is_fused(a.fuse().unique())
1636     }
1637 
1638     fn fused_unique_by(a: Iter<i16>) -> bool
1639     {
1640         is_fused(a.fuse().unique_by(|x| x % 100))
1641     }
1642 
1643     fn fused_interleave_shortest(a: Iter<i16>, b: Iter<i16>) -> bool
1644     {
1645         !is_fused(a.clone().interleave_shortest(b.clone())) &&
1646         is_fused(a.fuse().interleave_shortest(b.fuse()))
1647     }
1648 
1649     fn fused_product(a: Iter<i16>, b: Iter<i16>) -> bool
1650     {
1651         is_fused(a.fuse().cartesian_product(b.fuse()))
1652     }
1653 
1654     fn fused_merge(a: Iter<i16>, b: Iter<i16>) -> bool
1655     {
1656         is_fused(a.fuse().merge(b.fuse()))
1657     }
1658 
1659     fn fused_filter_ok(a: Iter<i16>) -> bool
1660     {
1661         is_fused(a.map(|x| if x % 2 == 0 {Ok(x)} else {Err(x)} )
1662                  .filter_ok(|x| x % 3 == 0)
1663                  .fuse())
1664     }
1665 
1666     fn fused_filter_map_ok(a: Iter<i16>) -> bool
1667     {
1668         is_fused(a.map(|x| if x % 2 == 0 {Ok(x)} else {Err(x)} )
1669                  .filter_map_ok(|x| if x % 3 == 0 {Some(x / 3)} else {None})
1670                  .fuse())
1671     }
1672 
1673     fn fused_positions(a: Iter<i16>) -> bool
1674     {
1675         !is_fused(a.clone().positions(|x|x%2==0)) &&
1676         is_fused(a.fuse().positions(|x|x%2==0))
1677     }
1678 
1679     fn fused_update(a: Iter<i16>) -> bool
1680     {
1681         !is_fused(a.clone().update(|x|*x+=1)) &&
1682         is_fused(a.fuse().update(|x|*x+=1))
1683     }
1684 
1685     fn fused_tuple_windows(a: Iter<i16>) -> bool
1686     {
1687         is_fused(a.fuse().tuple_windows::<(_,_)>())
1688     }
1689 
1690     fn fused_pad_using(a: Iter<i16>) -> bool
1691     {
1692         is_fused(a.fuse().pad_using(100,|_|0))
1693     }
1694 }
1695 
1696