summaryrefslogtreecommitdiffstats
path: root/vendor/itertools/tests/quick.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/itertools/tests/quick.rs')
-rw-r--r--vendor/itertools/tests/quick.rs314
1 files changed, 223 insertions, 91 deletions
diff --git a/vendor/itertools/tests/quick.rs b/vendor/itertools/tests/quick.rs
index c19af6c1e..6f45a63d0 100644
--- a/vendor/itertools/tests/quick.rs
+++ b/vendor/itertools/tests/quick.rs
@@ -3,34 +3,23 @@
//!
//! In particular we test the tedious size_hint and exact size correctness.
+#![allow(deprecated, unstable_name_collisions)]
+
+use itertools::free::{
+ cloned, enumerate, multipeek, peek_nth, put_back, put_back_n, rciter, zip, zip_eq,
+};
+use itertools::Itertools;
+use itertools::{iproduct, izip, multizip, EitherOrBoth};
use quickcheck as qc;
+use std::cmp::{max, min, Ordering};
+use std::collections::{HashMap, HashSet};
use std::default::Default;
use std::num::Wrapping;
use std::ops::Range;
-use std::cmp::{max, min, Ordering};
-use std::collections::{HashMap, HashSet};
-use itertools::Itertools;
-use itertools::{
- multizip,
- EitherOrBoth,
- iproduct,
- izip,
-};
-use itertools::free::{
- cloned,
- enumerate,
- multipeek,
- peek_nth,
- put_back,
- put_back_n,
- rciter,
- zip,
- zip_eq,
-};
-use rand::Rng;
-use rand::seq::SliceRandom;
use quickcheck::TestResult;
+use rand::seq::SliceRandom;
+use rand::Rng;
/// Trait for size hint modifier types
trait HintKind: Copy + Send + qc::Arbitrary {
@@ -66,8 +55,10 @@ struct Inexact {
impl HintKind for Inexact {
fn loosen_bounds(&self, org_hint: (usize, Option<usize>)) -> (usize, Option<usize>) {
let (org_lower, org_upper) = org_hint;
- (org_lower.saturating_sub(self.underestimate),
- org_upper.and_then(move |x| x.checked_add(self.overestimate)))
+ (
+ org_lower.saturating_sub(self.underestimate),
+ org_upper.and_then(move |x| x.checked_add(self.overestimate)),
+ )
}
}
@@ -84,19 +75,15 @@ impl qc::Arbitrary for Inexact {
}
}
- fn shrink(&self) -> Box<dyn Iterator<Item=Self>> {
+ fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
let underestimate_value = self.underestimate;
let overestimate_value = self.overestimate;
- Box::new(
- underestimate_value.shrink().flat_map(move |ue_value|
- overestimate_value.shrink().map(move |oe_value|
- Inexact {
- underestimate: ue_value,
- overestimate: oe_value,
- }
- )
- )
- )
+ Box::new(underestimate_value.shrink().flat_map(move |ue_value| {
+ overestimate_value.shrink().map(move |oe_value| Inexact {
+ underestimate: ue_value,
+ overestimate: oe_value,
+ })
+ }))
}
}
@@ -116,7 +103,9 @@ struct Iter<T, SK: HintKind = Inexact> {
hint_kind: SK,
}
-impl<T, HK> Iter<T, HK> where HK: HintKind
+impl<T, HK> Iter<T, HK>
+where
+ HK: HintKind,
{
fn new(it: Range<T>, hint_kind: HK) -> Self {
Iter {
@@ -128,64 +117,66 @@ impl<T, HK> Iter<T, HK> where HK: HintKind
}
impl<T, HK> Iterator for Iter<T, HK>
- where Range<T>: Iterator,
- <Range<T> as Iterator>::Item: Default,
- HK: HintKind,
+where
+ Range<T>: Iterator,
+ <Range<T> as Iterator>::Item: Default,
+ HK: HintKind,
{
type Item = <Range<T> as Iterator>::Item;
- fn next(&mut self) -> Option<Self::Item>
- {
+ fn next(&mut self) -> Option<Self::Item> {
let elt = self.iterator.next();
if elt.is_none() {
self.fuse_flag += 1;
// check fuse flag
if self.fuse_flag == 2 {
- return Some(Default::default())
+ return Some(Default::default());
}
}
elt
}
- fn size_hint(&self) -> (usize, Option<usize>)
- {
+ fn size_hint(&self) -> (usize, Option<usize>) {
let org_hint = self.iterator.size_hint();
self.hint_kind.loosen_bounds(org_hint)
}
}
impl<T, HK> DoubleEndedIterator for Iter<T, HK>
- where Range<T>: DoubleEndedIterator,
- <Range<T> as Iterator>::Item: Default,
- HK: HintKind
+where
+ Range<T>: DoubleEndedIterator,
+ <Range<T> as Iterator>::Item: Default,
+ HK: HintKind,
{
- fn next_back(&mut self) -> Option<Self::Item> { self.iterator.next_back() }
+ fn next_back(&mut self) -> Option<Self::Item> {
+ self.iterator.next_back()
+ }
}
-impl<T> ExactSizeIterator for Iter<T, Exact> where Range<T>: ExactSizeIterator,
+impl<T> ExactSizeIterator for Iter<T, Exact>
+where
+ Range<T>: ExactSizeIterator,
<Range<T> as Iterator>::Item: Default,
-{ }
+{
+}
impl<T, HK> qc::Arbitrary for Iter<T, HK>
- where T: qc::Arbitrary,
- HK: HintKind,
+where
+ T: qc::Arbitrary,
+ HK: HintKind,
{
- fn arbitrary<G: qc::Gen>(g: &mut G) -> Self
- {
+ fn arbitrary<G: qc::Gen>(g: &mut G) -> Self {
Iter::new(T::arbitrary(g)..T::arbitrary(g), HK::arbitrary(g))
}
- fn shrink(&self) -> Box<dyn Iterator<Item=Iter<T, HK>>>
- {
+ fn shrink(&self) -> Box<dyn Iterator<Item = Iter<T, HK>>> {
let r = self.iterator.clone();
let hint_kind = self.hint_kind;
- Box::new(
- r.start.shrink().flat_map(move |a|
- r.end.shrink().map(move |b|
- Iter::new(a.clone()..b, hint_kind)
- )
- )
- )
+ Box::new(r.start.shrink().flat_map(move |a| {
+ r.end
+ .shrink()
+ .map(move |b| Iter::new(a.clone()..b, hint_kind))
+ }))
}
}
@@ -201,7 +192,10 @@ struct ShiftRange<HK = Inexact> {
hint_kind: HK,
}
-impl<HK> Iterator for ShiftRange<HK> where HK: HintKind {
+impl<HK> Iterator for ShiftRange<HK>
+where
+ HK: HintKind,
+{
type Item = Iter<i32, HK>;
fn next(&mut self) -> Option<Self::Item> {
@@ -219,10 +213,11 @@ impl<HK> Iterator for ShiftRange<HK> where HK: HintKind {
}
}
-impl ExactSizeIterator for ShiftRange<Exact> { }
+impl ExactSizeIterator for ShiftRange<Exact> {}
impl<HK> qc::Arbitrary for ShiftRange<HK>
- where HK: HintKind
+where
+ HK: HintKind,
{
fn arbitrary<G: qc::Gen>(g: &mut G) -> Self {
const MAX_STARTING_RANGE_DIFF: i32 = 32;
@@ -250,7 +245,7 @@ impl<HK> qc::Arbitrary for ShiftRange<HK>
fn correct_count<I, F>(get_it: F) -> bool
where
I: Iterator,
- F: Fn() -> I
+ F: Fn() -> I,
{
let mut counts = vec![get_it().count()];
@@ -276,7 +271,10 @@ where
for (i, returned_count) in counts.into_iter().enumerate() {
let actual_count = total_actual_count - i;
if actual_count != returned_count {
- println!("Total iterations: {} True count: {} returned count: {}", i, actual_count, returned_count);
+ println!(
+ "Total iterations: {} True count: {} returned count: {}",
+ i, actual_count, returned_count
+ );
return false;
}
@@ -299,12 +297,10 @@ fn correct_size_hint<I: Iterator>(mut it: I) -> bool {
// check all the size hints
for &(low, hi) in &hints {
true_count -= 1;
- if low > true_count ||
- (hi.is_some() && hi.unwrap() < true_count)
- {
+ if low > true_count || (hi.is_some() && hi.unwrap() < true_count) {
println!("True size: {:?}, size hint: {:?}", true_count, (low, hi));
//println!("All hints: {:?}", hints);
- return false
+ return false;
}
}
true
@@ -313,13 +309,19 @@ fn correct_size_hint<I: Iterator>(mut it: I) -> bool {
fn exact_size<I: ExactSizeIterator>(mut it: I) -> bool {
// check every iteration
let (mut low, mut hi) = it.size_hint();
- if Some(low) != hi { return false; }
+ if Some(low) != hi {
+ return false;
+ }
while let Some(_) = it.next() {
let (xlow, xhi) = it.size_hint();
- if low != xlow + 1 { return false; }
+ if low != xlow + 1 {
+ return false;
+ }
low = xlow;
hi = xhi;
- if Some(low) != hi { return false; }
+ if Some(low) != hi {
+ return false;
+ }
}
let (low, hi) = it.size_hint();
low == 0 && hi == Some(0)
@@ -329,13 +331,19 @@ fn exact_size<I: ExactSizeIterator>(mut it: I) -> bool {
fn exact_size_for_this<I: Iterator>(mut it: I) -> bool {
// check every iteration
let (mut low, mut hi) = it.size_hint();
- if Some(low) != hi { return false; }
+ if Some(low) != hi {
+ return false;
+ }
while let Some(_) = it.next() {
let (xlow, xhi) = it.size_hint();
- if low != xlow + 1 { return false; }
+ if low != xlow + 1 {
+ return false;
+ }
low = xlow;
hi = xhi;
- if Some(low) != hi { return false; }
+ if Some(low) != hi {
+ return false;
+ }
}
let (low, hi) = it.size_hint();
low == 0 && hi == Some(0)
@@ -751,6 +759,56 @@ quickcheck! {
}
quickcheck! {
+ fn correct_peek_nth(mut a: Vec<u16>) -> () {
+ let mut it = peek_nth(a.clone());
+ for start_pos in 0..a.len() + 2 {
+ for real_idx in start_pos..a.len() + 2 {
+ let peek_idx = real_idx - start_pos;
+ assert_eq!(it.peek_nth(peek_idx), a.get(real_idx));
+ assert_eq!(it.peek_nth_mut(peek_idx), a.get_mut(real_idx));
+ }
+ assert_eq!(it.next(), a.get(start_pos).copied());
+ }
+ }
+
+ fn peek_nth_mut_replace(a: Vec<u16>, b: Vec<u16>) -> () {
+ let mut it = peek_nth(a.iter());
+ for i in 0..a.len().min(b.len()) {
+ *it.peek_nth_mut(i).unwrap() = &b[i];
+ }
+ for i in 0..a.len() {
+ assert_eq!(it.next().unwrap(), b.get(i).unwrap_or(&a[i]));
+ }
+ assert_eq!(it.next(), None);
+ assert_eq!(it.next(), None);
+ }
+
+ fn peek_nth_next_if(a: Vec<u8>) -> () {
+ let mut it = peek_nth(a.clone());
+ for (idx, mut value) in a.iter().copied().enumerate() {
+ let should_be_none = it.next_if(|x| x != &value);
+ assert_eq!(should_be_none, None);
+ if value % 5 == 0 {
+ // Sometimes, peek up to 3 further.
+ let n = value as usize % 3;
+ let nth = it.peek_nth(n);
+ assert_eq!(nth, a.get(idx + n));
+ } else if value % 5 == 1 {
+ // Sometimes, peek next element mutably.
+ if let Some(v) = it.peek_mut() {
+ *v = v.wrapping_sub(1);
+ let should_be_none = it.next_if_eq(&value);
+ assert_eq!(should_be_none, None);
+ value = value.wrapping_sub(1);
+ }
+ }
+ let eq = it.next_if_eq(&value);
+ assert_eq!(eq, Some(value));
+ }
+ }
+}
+
+quickcheck! {
fn dedup_via_coalesce(a: Vec<i32>) -> bool {
let mut b = a.clone();
b.dedup();
@@ -895,8 +953,31 @@ quickcheck! {
}
quickcheck! {
- fn size_combinations(it: Iter<i16>) -> bool {
- correct_size_hint(it.tuple_combinations::<(_, _)>())
+ fn size_combinations(a: Iter<i16>) -> bool {
+ let it = a.clone().tuple_combinations::<(_, _)>();
+ correct_size_hint(it.clone()) && it.count() == binomial(a.count(), 2)
+ }
+
+ fn exact_size_combinations_1(a: Vec<u8>) -> bool {
+ let it = a.iter().tuple_combinations::<(_,)>();
+ exact_size_for_this(it.clone()) && it.count() == binomial(a.len(), 1)
+ }
+ fn exact_size_combinations_2(a: Vec<u8>) -> bool {
+ let it = a.iter().tuple_combinations::<(_, _)>();
+ exact_size_for_this(it.clone()) && it.count() == binomial(a.len(), 2)
+ }
+ fn exact_size_combinations_3(mut a: Vec<u8>) -> bool {
+ a.truncate(15);
+ let it = a.iter().tuple_combinations::<(_, _, _)>();
+ exact_size_for_this(it.clone()) && it.count() == binomial(a.len(), 3)
+ }
+}
+
+fn binomial(n: usize, k: usize) -> usize {
+ if k > n {
+ 0
+ } else {
+ (n - k + 1..=n).product::<usize>() / (1..=k).product::<usize>()
}
}
@@ -1111,6 +1192,10 @@ quickcheck! {
true
}
+ fn circular_tuple_windows_exact_size(a: Vec<u8>) -> bool {
+ exact_size(a.iter().circular_tuple_windows::<(_, _, _, _)>())
+ }
+
fn equal_tuple_windows_1(a: Vec<u8>) -> bool {
let x = a.windows(1).map(|s| (&s[0], ));
let y = a.iter().tuple_windows::<(_,)>();
@@ -1135,6 +1220,14 @@ quickcheck! {
itertools::equal(x, y)
}
+ fn tuple_windows_exact_size_1(a: Vec<u8>) -> bool {
+ exact_size(a.iter().tuple_windows::<(_,)>())
+ }
+
+ fn tuple_windows_exact_size_4(a: Vec<u8>) -> bool {
+ exact_size(a.iter().tuple_windows::<(_, _, _, _)>())
+ }
+
fn equal_tuples_1(a: Vec<u8>) -> bool {
let x = a.chunks(1).map(|s| (&s[0], ));
let y = a.iter().tuples::<(_,)>();
@@ -1166,6 +1259,18 @@ quickcheck! {
assert_eq!(buffer.len(), a.len() % 4);
exact_size(buffer)
}
+
+ fn tuples_size_hint_inexact(a: Iter<u8>) -> bool {
+ correct_size_hint(a.clone().tuples::<(_,)>())
+ && correct_size_hint(a.clone().tuples::<(_, _)>())
+ && correct_size_hint(a.tuples::<(_, _, _, _)>())
+ }
+
+ fn tuples_size_hint_exact(a: Iter<u8, Exact>) -> bool {
+ exact_size(a.clone().tuples::<(_,)>())
+ && exact_size(a.clone().tuples::<(_, _)>())
+ && exact_size(a.tuples::<(_, _, _, _)>())
+ }
}
// with_position
@@ -1332,7 +1437,7 @@ quickcheck! {
Some(acc.unwrap_or(0) + val)
}
});
-
+
let group_map_lookup = a.iter()
.map(|&b| b as u64)
.map(|i| (i % modulo, i))
@@ -1352,7 +1457,7 @@ quickcheck! {
for m in 0..modulo {
assert_eq!(
- lookup.get(&m).copied(),
+ lookup.get(&m).copied(),
a.iter()
.map(|&b| b as u64)
.filter(|&val| val % modulo == m)
@@ -1367,6 +1472,35 @@ quickcheck! {
}
}
+ fn correct_grouping_map_by_fold_with_modulo_key(a: Vec<u8>, modulo: u8) -> () {
+ #[derive(Debug, Default, PartialEq)]
+ struct Accumulator {
+ acc: u64,
+ }
+
+ let modulo = if modulo == 0 { 1 } else { modulo } as u64; // Avoid `% 0`
+ let lookup = a.iter().map(|&b| b as u64) // Avoid overflows
+ .into_grouping_map_by(|i| i % modulo)
+ .fold_with(|_key, _val| Default::default(), |Accumulator { acc }, &key, val| {
+ assert!(val % modulo == key);
+ let acc = acc + val;
+ Accumulator { acc }
+ });
+
+ let group_map_lookup = a.iter()
+ .map(|&b| b as u64)
+ .map(|i| (i % modulo, i))
+ .into_group_map()
+ .into_iter()
+ .map(|(key, vals)| (key, vals.into_iter().sum())).map(|(key, acc)| (key,Accumulator { acc }))
+ .collect::<HashMap<_,_>>();
+ assert_eq!(lookup, group_map_lookup);
+
+ for (&key, &Accumulator { acc: sum }) in lookup.iter() {
+ assert_eq!(sum, a.iter().map(|&b| b as u64).filter(|&val| val % modulo == key).sum::<u64>());
+ }
+ }
+
fn correct_grouping_map_by_fold_modulo_key(a: Vec<u8>, modulo: u8) -> () {
let modulo = if modulo == 0 { 1 } else { modulo } as u64; // Avoid `% 0`
let lookup = a.iter().map(|&b| b as u64) // Avoid overflows
@@ -1472,7 +1606,7 @@ quickcheck! {
assert_eq!(Some(max), a.iter().copied().filter(|&val| val % modulo == key).max_by_key(|&val| val));
}
}
-
+
fn correct_grouping_map_by_min_modulo_key(a: Vec<u8>, modulo: u8) -> () {
let modulo = if modulo == 0 { 1 } else { modulo }; // Avoid `% 0`
let lookup = a.iter().copied().into_grouping_map_by(|i| i % modulo).min();
@@ -1523,7 +1657,7 @@ quickcheck! {
assert_eq!(Some(min), a.iter().copied().filter(|&val| val % modulo == key).min_by_key(|&val| val));
}
}
-
+
fn correct_grouping_map_by_minmax_modulo_key(a: Vec<u8>, modulo: u8) -> () {
let modulo = if modulo == 0 { 1 } else { modulo }; // Avoid `% 0`
let lookup = a.iter().copied().into_grouping_map_by(|i| i % modulo).minmax();
@@ -1636,7 +1770,7 @@ quickcheck! {
.min_by(|_, _, _| Ordering::Equal);
assert_eq!(lookup[&0], 0);
-
+
let lookup = (0..=10)
.into_grouping_map_by(|_| 0)
.minmax_by(|_, _, _| Ordering::Equal);
@@ -1694,12 +1828,10 @@ quickcheck! {
}
}
-
-fn is_fused<I: Iterator>(mut it: I) -> bool
-{
+fn is_fused<I: Iterator>(mut it: I) -> bool {
for _ in it.by_ref() {}
- for _ in 0..10{
- if it.next().is_some(){
+ for _ in 0..10 {
+ if it.next().is_some() {
return false;
}
}
@@ -1740,7 +1872,7 @@ quickcheck! {
!is_fused(a.clone().interleave_shortest(b.clone())) &&
is_fused(a.fuse().interleave_shortest(b.fuse()))
}
-
+
fn fused_product(a: Iter<i16>, b: Iter<i16>) -> bool
{
is_fused(a.fuse().cartesian_product(b.fuse()))