library/core/tests/iter rearrange & add back missed doc comments

This commit is contained in:
Daniel Conley 2021-01-22 17:20:42 -05:00
parent 1e3a2def67
commit bc830a274b
18 changed files with 275 additions and 271 deletions

View file

@ -226,3 +226,47 @@ fn test_chain_try_folds() {
iter.nth(14); // skip the first 15, ending in state Back
assert_eq!(iter.try_rfold(7, f), (15..20).try_rfold(7, f));
}
#[test]
fn test_double_ended_chain() {
let xs = [1, 2, 3, 4, 5];
let ys = [7, 9, 11];
let mut it = xs.iter().chain(&ys).rev();
assert_eq!(it.next().unwrap(), &11);
assert_eq!(it.next().unwrap(), &9);
assert_eq!(it.next_back().unwrap(), &1);
assert_eq!(it.next_back().unwrap(), &2);
assert_eq!(it.next_back().unwrap(), &3);
assert_eq!(it.next_back().unwrap(), &4);
assert_eq!(it.next_back().unwrap(), &5);
assert_eq!(it.next_back().unwrap(), &7);
assert_eq!(it.next_back(), None);
// test that .chain() is well behaved with an unfused iterator
struct CrazyIterator(bool);
impl CrazyIterator {
fn new() -> CrazyIterator {
CrazyIterator(false)
}
}
impl Iterator for CrazyIterator {
type Item = i32;
fn next(&mut self) -> Option<i32> {
if self.0 {
Some(99)
} else {
self.0 = true;
None
}
}
}
impl DoubleEndedIterator for CrazyIterator {
fn next_back(&mut self) -> Option<i32> {
self.next()
}
}
assert_eq!(CrazyIterator::new().chain(0..10).rev().last(), Some(0));
assert!((0..10).chain(CrazyIterator::new()).rev().any(|i| i == 0));
}

View file

@ -92,3 +92,16 @@ fn test_enumerate_try_folds() {
assert_eq!(iter.try_rfold(0, f), None);
assert_eq!(iter.next_back(), Some((11, 111)));
}
#[test]
fn test_double_ended_enumerate() {
let xs = [1, 2, 3, 4, 5, 6];
let mut it = xs.iter().cloned().enumerate();
assert_eq!(it.next(), Some((0, 1)));
assert_eq!(it.next(), Some((1, 2)));
assert_eq!(it.next_back(), Some((5, 6)));
assert_eq!(it.next_back(), Some((4, 5)));
assert_eq!(it.next_back(), Some((3, 4)));
assert_eq!(it.next_back(), Some((2, 3)));
assert_eq!(it.next(), None);
}

View file

@ -40,3 +40,13 @@ fn test_filter_try_folds() {
assert_eq!(iter.try_rfold(0, i8::checked_add), None);
assert_eq!(iter.next_back(), Some(31));
}
#[test]
fn test_double_ended_filter() {
let xs = [1, 2, 3, 4, 5, 6];
let mut it = xs.iter().filter(|&x| *x & 1 == 0);
assert_eq!(it.next_back().unwrap(), &6);
assert_eq!(it.next_back().unwrap(), &4);
assert_eq!(it.next().unwrap(), &2);
assert_eq!(it.next_back(), None);
}

View file

@ -24,3 +24,27 @@ fn test_filter_map_fold() {
});
assert_eq!(i, 0);
}
#[test]
fn test_filter_map_try_folds() {
let mp = &|x| if 0 <= x && x < 10 { Some(x * 2) } else { None };
let f = &|acc, x| i32::checked_add(2 * acc, x);
assert_eq!((-9..20).filter_map(mp).try_fold(7, f), (0..10).map(|x| 2 * x).try_fold(7, f));
assert_eq!((-9..20).filter_map(mp).try_rfold(7, f), (0..10).map(|x| 2 * x).try_rfold(7, f));
let mut iter = (0..40).filter_map(|x| if x % 2 == 1 { None } else { Some(x * 2 + 10) });
assert_eq!(iter.try_fold(0, i8::checked_add), None);
assert_eq!(iter.next(), Some(38));
assert_eq!(iter.try_rfold(0, i8::checked_add), None);
assert_eq!(iter.next_back(), Some(78));
}
#[test]
fn test_double_ended_filter_map() {
let xs = [1, 2, 3, 4, 5, 6];
let mut it = xs.iter().filter_map(|&x| if x & 1 == 0 { Some(x * 2) } else { None });
assert_eq!(it.next_back().unwrap(), 12);
assert_eq!(it.next_back().unwrap(), 8);
assert_eq!(it.next().unwrap(), 4);
assert_eq!(it.next_back(), None);
}

View file

@ -13,6 +13,8 @@ fn test_iterator_flat_map() {
assert_eq!(i, ys.len());
}
/// Tests `FlatMap::fold` with items already picked off the front and back,
/// to make sure all parts of the `FlatMap` are folded correctly.
#[test]
fn test_iterator_flat_map_fold() {
let xs = [0, 3, 6];
@ -53,3 +55,20 @@ fn test_flat_map_try_folds() {
assert_eq!(iter.try_rfold(0, i8::checked_add), None);
assert_eq!(iter.next_back(), Some(35));
}
#[test]
fn test_double_ended_flat_map() {
let u = [0, 1];
let v = [5, 6, 7, 8];
let mut it = u.iter().flat_map(|x| &v[*x..v.len()]);
assert_eq!(it.next_back().unwrap(), &8);
assert_eq!(it.next().unwrap(), &5);
assert_eq!(it.next_back().unwrap(), &7);
assert_eq!(it.next_back().unwrap(), &6);
assert_eq!(it.next_back().unwrap(), &8);
assert_eq!(it.next().unwrap(), &6);
assert_eq!(it.next_back().unwrap(), &7);
assert_eq!(it.next_back(), None);
assert_eq!(it.next(), None);
assert_eq!(it.next_back(), None);
}

View file

@ -14,6 +14,8 @@ fn test_iterator_flatten() {
assert_eq!(i, ys.len());
}
/// Tests `Flatten::fold` with items already picked off the front and back,
/// to make sure all parts of the `Flatten` are folded correctly.
#[test]
fn test_iterator_flatten_fold() {
let xs = [0, 3, 6];
@ -73,3 +75,20 @@ fn test_flatten_non_fused_inner() {
assert_eq!(iter.next(), Some(1));
assert_eq!(iter.next(), None);
}
#[test]
fn test_double_ended_flatten() {
let u = [0, 1];
let v = [5, 6, 7, 8];
let mut it = u.iter().map(|x| &v[*x..v.len()]).flatten();
assert_eq!(it.next_back().unwrap(), &8);
assert_eq!(it.next().unwrap(), &5);
assert_eq!(it.next_back().unwrap(), &7);
assert_eq!(it.next_back().unwrap(), &6);
assert_eq!(it.next_back().unwrap(), &8);
assert_eq!(it.next().unwrap(), &6);
assert_eq!(it.next_back().unwrap(), &7);
assert_eq!(it.next_back(), None);
assert_eq!(it.next(), None);
assert_eq!(it.next_back(), None);
}

View file

@ -55,3 +55,21 @@ fn test_fuse_fold() {
});
assert_eq!(i, xs.len());
}
#[test]
fn test_fuse() {
let mut it = 0..3;
assert_eq!(it.len(), 3);
assert_eq!(it.next(), Some(0));
assert_eq!(it.len(), 2);
assert_eq!(it.next(), Some(1));
assert_eq!(it.len(), 1);
assert_eq!(it.next(), Some(2));
assert_eq!(it.len(), 0);
assert_eq!(it.next(), None);
assert_eq!(it.len(), 0);
assert_eq!(it.next(), None);
assert_eq!(it.len(), 0);
assert_eq!(it.next(), None);
assert_eq!(it.len(), 0);
}

View file

@ -129,3 +129,26 @@ fn test_intersperse_collect_string() {
.collect::<String>();
assert_eq!(contents_string, "1, 2, 3");
}
#[test]
fn test_try_fold_specialization_intersperse_err() {
let orig_iter = ["a", "b"].iter().copied().intersperse("-");
// Abort after the first item.
let mut iter = orig_iter.clone();
iter.try_for_each(|_| None::<()>);
assert_eq!(iter.next(), Some("-"));
assert_eq!(iter.next(), Some("b"));
assert_eq!(iter.next(), None);
// Abort after the second item.
let mut iter = orig_iter.clone();
iter.try_for_each(|item| if item == "-" { None } else { Some(()) });
assert_eq!(iter.next(), Some("b"));
assert_eq!(iter.next(), None);
// Abort after the third item.
let mut iter = orig_iter.clone();
iter.try_for_each(|item| if item == "b" { None } else { Some(()) });
assert_eq!(iter.next(), None);
}

View file

@ -1,28 +1,5 @@
use core::iter::*;
#[test]
fn test_find_map() {
let xs: &[isize] = &[];
assert_eq!(xs.iter().find_map(half_if_even), None);
let xs: &[isize] = &[3, 5];
assert_eq!(xs.iter().find_map(half_if_even), None);
let xs: &[isize] = &[4, 5];
assert_eq!(xs.iter().find_map(half_if_even), Some(2));
let xs: &[isize] = &[3, 6];
assert_eq!(xs.iter().find_map(half_if_even), Some(3));
let xs: &[isize] = &[1, 2, 3, 4, 5, 6, 7];
let mut iter = xs.iter();
assert_eq!(iter.find_map(half_if_even), Some(1));
assert_eq!(iter.find_map(half_if_even), Some(2));
assert_eq!(iter.find_map(half_if_even), Some(3));
assert_eq!(iter.next(), Some(&7));
fn half_if_even(x: &isize) -> Option<isize> {
if x % 2 == 0 { Some(x / 2) } else { None }
}
}
#[test]
fn test_map_try_folds() {
let f = &|acc, x| i32::checked_add(2 * acc, x);
@ -37,15 +14,14 @@ fn test_map_try_folds() {
}
#[test]
fn test_filter_map_try_folds() {
let mp = &|x| if 0 <= x && x < 10 { Some(x * 2) } else { None };
let f = &|acc, x| i32::checked_add(2 * acc, x);
assert_eq!((-9..20).filter_map(mp).try_fold(7, f), (0..10).map(|x| 2 * x).try_fold(7, f));
assert_eq!((-9..20).filter_map(mp).try_rfold(7, f), (0..10).map(|x| 2 * x).try_rfold(7, f));
let mut iter = (0..40).filter_map(|x| if x % 2 == 1 { None } else { Some(x * 2 + 10) });
assert_eq!(iter.try_fold(0, i8::checked_add), None);
assert_eq!(iter.next(), Some(38));
assert_eq!(iter.try_rfold(0, i8::checked_add), None);
assert_eq!(iter.next_back(), Some(78));
fn test_double_ended_map() {
let xs = [1, 2, 3, 4, 5, 6];
let mut it = xs.iter().map(|&x| x * -1);
assert_eq!(it.next(), Some(-1));
assert_eq!(it.next(), Some(-2));
assert_eq!(it.next_back(), Some(-6));
assert_eq!(it.next_back(), Some(-5));
assert_eq!(it.next(), Some(-3));
assert_eq!(it.next_back(), Some(-4));
assert_eq!(it.next(), None);
}

View file

@ -15,7 +15,6 @@ mod peekable;
mod scan;
mod skip;
mod skip_while;
mod step;
mod step_by;
mod take;
mod take_while;

View file

@ -231,3 +231,17 @@ fn test_zip_trusted_random_access_composition() {
assert_trusted_random_access(&z2);
assert_eq!(z2.next().unwrap(), ((1, 1), 1));
}
#[test]
fn test_double_ended_zip() {
let xs = [1, 2, 3, 4, 5, 6];
let ys = [1, 2, 3, 7];
let a = xs.iter().cloned();
let b = ys.iter().cloned();
let mut it = a.zip(b);
assert_eq!(it.next(), Some((1, 1)));
assert_eq!(it.next(), Some((2, 2)));
assert_eq!(it.next_back(), Some((4, 7)));
assert_eq!(it.next_back(), Some((3, 3)));
assert_eq!(it.next(), None);
}

View file

@ -83,26 +83,3 @@ pub fn extend_for_unit() {
}
assert_eq!(x, 5);
}
#[test]
fn test_try_fold_specialization_intersperse_err() {
let orig_iter = ["a", "b"].iter().copied().intersperse("-");
// Abort after the first item.
let mut iter = orig_iter.clone();
iter.try_for_each(|_| None::<()>);
assert_eq!(iter.next(), Some("-"));
assert_eq!(iter.next(), Some("b"));
assert_eq!(iter.next(), None);
// Abort after the second item.
let mut iter = orig_iter.clone();
iter.try_for_each(|item| if item == "-" { None } else { Some(()) });
assert_eq!(iter.next(), Some("b"));
assert_eq!(iter.next(), None);
// Abort after the third item.
let mut iter = orig_iter.clone();
iter.try_for_each(|item| if item == "b" { None } else { Some(()) });
assert_eq!(iter.next(), None);
}

View file

@ -431,3 +431,16 @@ fn test_range_inclusive_size_hint() {
assert_eq!((imin..=imax).size_hint(), (usize::MAX, None));
assert_eq!((imin..=imax + 1).size_hint(), (usize::MAX, None));
}
#[test]
fn test_double_ended_range() {
assert_eq!((11..14).rev().collect::<Vec<_>>(), [13, 12, 11]);
for _ in (10..0).rev() {
panic!("unreachable");
}
assert_eq!((11..14).rev().collect::<Vec<_>>(), [13, 12, 11]);
for _ in (10..0).rev() {
panic!("unreachable");
}
}

View file

@ -16,14 +16,6 @@ fn test_iterator_rev_nth() {
assert_eq!(v.iter().rev().nth(v.len()), None);
}
#[test]
fn test_iterator_len() {
let v: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
assert_eq!(v[..4].iter().count(), 4);
assert_eq!(v[..10].iter().count(), 10);
assert_eq!(v[..0].iter().count(), 0);
}
#[test]
fn test_rev() {
let xs = [2, 4, 6, 8, 10, 12, 14, 16];
@ -33,157 +25,6 @@ fn test_rev() {
assert!(it.rev().cloned().collect::<Vec<isize>>() == vec![16, 14, 12, 10, 8, 6]);
}
#[test]
fn test_double_ended_map() {
let xs = [1, 2, 3, 4, 5, 6];
let mut it = xs.iter().map(|&x| x * -1);
assert_eq!(it.next(), Some(-1));
assert_eq!(it.next(), Some(-2));
assert_eq!(it.next_back(), Some(-6));
assert_eq!(it.next_back(), Some(-5));
assert_eq!(it.next(), Some(-3));
assert_eq!(it.next_back(), Some(-4));
assert_eq!(it.next(), None);
}
#[test]
fn test_double_ended_enumerate() {
let xs = [1, 2, 3, 4, 5, 6];
let mut it = xs.iter().cloned().enumerate();
assert_eq!(it.next(), Some((0, 1)));
assert_eq!(it.next(), Some((1, 2)));
assert_eq!(it.next_back(), Some((5, 6)));
assert_eq!(it.next_back(), Some((4, 5)));
assert_eq!(it.next_back(), Some((3, 4)));
assert_eq!(it.next_back(), Some((2, 3)));
assert_eq!(it.next(), None);
}
#[test]
fn test_double_ended_zip() {
let xs = [1, 2, 3, 4, 5, 6];
let ys = [1, 2, 3, 7];
let a = xs.iter().cloned();
let b = ys.iter().cloned();
let mut it = a.zip(b);
assert_eq!(it.next(), Some((1, 1)));
assert_eq!(it.next(), Some((2, 2)));
assert_eq!(it.next_back(), Some((4, 7)));
assert_eq!(it.next_back(), Some((3, 3)));
assert_eq!(it.next(), None);
}
#[test]
fn test_double_ended_filter() {
let xs = [1, 2, 3, 4, 5, 6];
let mut it = xs.iter().filter(|&x| *x & 1 == 0);
assert_eq!(it.next_back().unwrap(), &6);
assert_eq!(it.next_back().unwrap(), &4);
assert_eq!(it.next().unwrap(), &2);
assert_eq!(it.next_back(), None);
}
#[test]
fn test_double_ended_filter_map() {
let xs = [1, 2, 3, 4, 5, 6];
let mut it = xs.iter().filter_map(|&x| if x & 1 == 0 { Some(x * 2) } else { None });
assert_eq!(it.next_back().unwrap(), 12);
assert_eq!(it.next_back().unwrap(), 8);
assert_eq!(it.next().unwrap(), 4);
assert_eq!(it.next_back(), None);
}
#[test]
fn test_double_ended_chain() {
let xs = [1, 2, 3, 4, 5];
let ys = [7, 9, 11];
let mut it = xs.iter().chain(&ys).rev();
assert_eq!(it.next().unwrap(), &11);
assert_eq!(it.next().unwrap(), &9);
assert_eq!(it.next_back().unwrap(), &1);
assert_eq!(it.next_back().unwrap(), &2);
assert_eq!(it.next_back().unwrap(), &3);
assert_eq!(it.next_back().unwrap(), &4);
assert_eq!(it.next_back().unwrap(), &5);
assert_eq!(it.next_back().unwrap(), &7);
assert_eq!(it.next_back(), None);
// test that .chain() is well behaved with an unfused iterator
struct CrazyIterator(bool);
impl CrazyIterator {
fn new() -> CrazyIterator {
CrazyIterator(false)
}
}
impl Iterator for CrazyIterator {
type Item = i32;
fn next(&mut self) -> Option<i32> {
if self.0 {
Some(99)
} else {
self.0 = true;
None
}
}
}
impl DoubleEndedIterator for CrazyIterator {
fn next_back(&mut self) -> Option<i32> {
self.next()
}
}
assert_eq!(CrazyIterator::new().chain(0..10).rev().last(), Some(0));
assert!((0..10).chain(CrazyIterator::new()).rev().any(|i| i == 0));
}
#[test]
fn test_double_ended_flat_map() {
let u = [0, 1];
let v = [5, 6, 7, 8];
let mut it = u.iter().flat_map(|x| &v[*x..v.len()]);
assert_eq!(it.next_back().unwrap(), &8);
assert_eq!(it.next().unwrap(), &5);
assert_eq!(it.next_back().unwrap(), &7);
assert_eq!(it.next_back().unwrap(), &6);
assert_eq!(it.next_back().unwrap(), &8);
assert_eq!(it.next().unwrap(), &6);
assert_eq!(it.next_back().unwrap(), &7);
assert_eq!(it.next_back(), None);
assert_eq!(it.next(), None);
assert_eq!(it.next_back(), None);
}
#[test]
fn test_double_ended_flatten() {
let u = [0, 1];
let v = [5, 6, 7, 8];
let mut it = u.iter().map(|x| &v[*x..v.len()]).flatten();
assert_eq!(it.next_back().unwrap(), &8);
assert_eq!(it.next().unwrap(), &5);
assert_eq!(it.next_back().unwrap(), &7);
assert_eq!(it.next_back().unwrap(), &6);
assert_eq!(it.next_back().unwrap(), &8);
assert_eq!(it.next().unwrap(), &6);
assert_eq!(it.next_back().unwrap(), &7);
assert_eq!(it.next_back(), None);
assert_eq!(it.next(), None);
assert_eq!(it.next_back(), None);
}
#[test]
fn test_double_ended_range() {
assert_eq!((11..14).rev().collect::<Vec<_>>(), [13, 12, 11]);
for _ in (10..0).rev() {
panic!("unreachable");
}
assert_eq!((11..14).rev().collect::<Vec<_>>(), [13, 12, 11]);
for _ in (10..0).rev() {
panic!("unreachable");
}
}
#[test]
fn test_rev_try_folds() {
let f = &|acc, x| i32::checked_add(2 * acc, x);
@ -198,3 +39,39 @@ fn test_rev_try_folds() {
assert_eq!(iter.try_rfold(0_i8, |acc, &x| acc.checked_add(x)), None);
assert_eq!(iter.next_back(), Some(&60));
}
#[test]
fn test_rposition() {
fn f(xy: &(isize, char)) -> bool {
let (_x, y) = *xy;
y == 'b'
}
fn g(xy: &(isize, char)) -> bool {
let (_x, y) = *xy;
y == 'd'
}
let v = [(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')];
assert_eq!(v.iter().rposition(f), Some(3));
assert!(v.iter().rposition(g).is_none());
}
#[test]
fn test_rev_rposition() {
let v = [0, 0, 1, 1];
assert_eq!(v.iter().rev().rposition(|&x| x == 1), Some(1));
}
#[test]
#[should_panic]
fn test_rposition_panic() {
let v: [(Box<_>, Box<_>); 4] = [(box 0, box 0), (box 0, box 0), (box 0, box 0), (box 0, box 0)];
let mut i = 0;
v.iter().rposition(|_elt| {
if i == 2 {
panic!()
}
i += 1;
false
});
}

View file

@ -430,3 +430,34 @@ fn test_iterator_rev_advance_by() {
assert_eq!(v.iter().rev().advance_by(v.len()), Ok(()));
assert_eq!(v.iter().rev().advance_by(100), Err(v.len()));
}
#[test]
fn test_find_map() {
let xs: &[isize] = &[];
assert_eq!(xs.iter().find_map(half_if_even), None);
let xs: &[isize] = &[3, 5];
assert_eq!(xs.iter().find_map(half_if_even), None);
let xs: &[isize] = &[4, 5];
assert_eq!(xs.iter().find_map(half_if_even), Some(2));
let xs: &[isize] = &[3, 6];
assert_eq!(xs.iter().find_map(half_if_even), Some(3));
let xs: &[isize] = &[1, 2, 3, 4, 5, 6, 7];
let mut iter = xs.iter();
assert_eq!(iter.find_map(half_if_even), Some(1));
assert_eq!(iter.find_map(half_if_even), Some(2));
assert_eq!(iter.find_map(half_if_even), Some(3));
assert_eq!(iter.next(), Some(&7));
fn half_if_even(x: &isize) -> Option<isize> {
if x % 2 == 0 { Some(x / 2) } else { None }
}
}
#[test]
fn test_iterator_len() {
let v: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
assert_eq!(v[..4].iter().count(), 4);
assert_eq!(v[..10].iter().count(), 10);
assert_eq!(v[..0].iter().count(), 0);
}

View file

@ -1,17 +0,0 @@
#[test]
fn test_fuse() {
let mut it = 0..3;
assert_eq!(it.len(), 3);
assert_eq!(it.next(), Some(0));
assert_eq!(it.len(), 2);
assert_eq!(it.next(), Some(1));
assert_eq!(it.len(), 1);
assert_eq!(it.next(), Some(2));
assert_eq!(it.len(), 0);
assert_eq!(it.next(), None);
assert_eq!(it.len(), 0);
assert_eq!(it.next(), None);
assert_eq!(it.len(), 0);
assert_eq!(it.next(), None);
assert_eq!(it.len(), 0);
}

View file

@ -2,40 +2,4 @@ mod accum;
mod collect;
mod double_ended;
mod iterator;
mod marker;
#[test]
fn test_rposition() {
fn f(xy: &(isize, char)) -> bool {
let (_x, y) = *xy;
y == 'b'
}
fn g(xy: &(isize, char)) -> bool {
let (_x, y) = *xy;
y == 'd'
}
let v = [(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')];
assert_eq!(v.iter().rposition(f), Some(3));
assert!(v.iter().rposition(g).is_none());
}
#[test]
fn test_rev_rposition() {
let v = [0, 0, 1, 1];
assert_eq!(v.iter().rev().rposition(|&x| x == 1), Some(1));
}
#[test]
#[should_panic]
fn test_rposition_panic() {
let v: [(Box<_>, Box<_>); 4] = [(box 0, box 0), (box 0, box 0), (box 0, box 0), (box 0, box 0)];
let mut i = 0;
v.iter().rposition(|_elt| {
if i == 2 {
panic!()
}
i += 1;
false
});
}
mod step;