1 use paste;
2 use permutohedron;
3 use quickcheck as qc;
4 use rand::{distributions::{Distribution, Standard}, Rng, SeedableRng, rngs::StdRng};
5 use rand::{seq::SliceRandom, thread_rng};
6 use std::{cmp::min, fmt::Debug, marker::PhantomData};
7 use itertools as it;
8 use crate::it::Itertools;
9 use crate::it::ExactlyOneError;
10 use crate::it::multizip;
11 use crate::it::multipeek;
12 use crate::it::peek_nth;
13 use crate::it::free::rciter;
14 use crate::it::free::put_back_n;
15 use crate::it::FoldWhile;
16 use crate::it::cloned;
17 use crate::it::iproduct;
18 use crate::it::izip;
19
20 #[test]
product3()21 fn product3() {
22 let prod = iproduct!(0..3, 0..2, 0..2);
23 assert_eq!(prod.size_hint(), (12, Some(12)));
24 let v = prod.collect_vec();
25 for i in 0..3 {
26 for j in 0..2 {
27 for k in 0..2 {
28 assert!((i, j, k) == v[(i * 2 * 2 + j * 2 + k) as usize]);
29 }
30 }
31 }
32 for (_, _, _, _) in iproduct!(0..3, 0..2, 0..2, 0..3) {
33 /* test compiles */
34 }
35 }
36
37 #[test]
interleave_shortest()38 fn interleave_shortest() {
39 let v0: Vec<i32> = vec![0, 2, 4];
40 let v1: Vec<i32> = vec![1, 3, 5, 7];
41 let it = v0.into_iter().interleave_shortest(v1.into_iter());
42 assert_eq!(it.size_hint(), (6, Some(6)));
43 assert_eq!(it.collect_vec(), vec![0, 1, 2, 3, 4, 5]);
44
45 let v0: Vec<i32> = vec![0, 2, 4, 6, 8];
46 let v1: Vec<i32> = vec![1, 3, 5];
47 let it = v0.into_iter().interleave_shortest(v1.into_iter());
48 assert_eq!(it.size_hint(), (7, Some(7)));
49 assert_eq!(it.collect_vec(), vec![0, 1, 2, 3, 4, 5, 6]);
50
51 let i0 = ::std::iter::repeat(0);
52 let v1: Vec<_> = vec![1, 3, 5];
53 let it = i0.interleave_shortest(v1.into_iter());
54 assert_eq!(it.size_hint(), (7, Some(7)));
55
56 let v0: Vec<_> = vec![0, 2, 4];
57 let i1 = ::std::iter::repeat(1);
58 let it = v0.into_iter().interleave_shortest(i1);
59 assert_eq!(it.size_hint(), (6, Some(6)));
60 }
61
62 #[test]
duplicates_by()63 fn duplicates_by() {
64 let xs = ["aaa", "bbbbb", "aa", "ccc", "bbbb", "aaaaa", "cccc"];
65 let ys = ["aa", "bbbb", "cccc"];
66 it::assert_equal(ys.iter(), xs.iter().duplicates_by(|x| x[..2].to_string()));
67 it::assert_equal(ys.iter(), xs.iter().rev().duplicates_by(|x| x[..2].to_string()).rev());
68 let ys_rev = ["ccc", "aa", "bbbbb"];
69 it::assert_equal(ys_rev.iter(), xs.iter().duplicates_by(|x| x[..2].to_string()).rev());
70 }
71
72 #[test]
duplicates()73 fn duplicates() {
74 let xs = [0, 1, 2, 3, 2, 1, 3];
75 let ys = [2, 1, 3];
76 it::assert_equal(ys.iter(), xs.iter().duplicates());
77 it::assert_equal(ys.iter(), xs.iter().rev().duplicates().rev());
78 let ys_rev = [3, 2, 1];
79 it::assert_equal(ys_rev.iter(), xs.iter().duplicates().rev());
80
81 let xs = [0, 1, 0, 1];
82 let ys = [0, 1];
83 it::assert_equal(ys.iter(), xs.iter().duplicates());
84 it::assert_equal(ys.iter(), xs.iter().rev().duplicates().rev());
85 let ys_rev = [1, 0];
86 it::assert_equal(ys_rev.iter(), xs.iter().duplicates().rev());
87 }
88
89 #[test]
unique_by()90 fn unique_by() {
91 let xs = ["aaa", "bbbbb", "aa", "ccc", "bbbb", "aaaaa", "cccc"];
92 let ys = ["aaa", "bbbbb", "ccc"];
93 it::assert_equal(ys.iter(), xs.iter().unique_by(|x| x[..2].to_string()));
94 it::assert_equal(ys.iter(), xs.iter().rev().unique_by(|x| x[..2].to_string()).rev());
95 let ys_rev = ["cccc", "aaaaa", "bbbb"];
96 it::assert_equal(ys_rev.iter(), xs.iter().unique_by(|x| x[..2].to_string()).rev());
97 }
98
99 #[test]
unique()100 fn unique() {
101 let xs = [0, 1, 2, 3, 2, 1, 3];
102 let ys = [0, 1, 2, 3];
103 it::assert_equal(ys.iter(), xs.iter().unique());
104 it::assert_equal(ys.iter(), xs.iter().rev().unique().rev());
105 let ys_rev = [3, 1, 2, 0];
106 it::assert_equal(ys_rev.iter(), xs.iter().unique().rev());
107
108 let xs = [0, 1];
109 let ys = [0, 1];
110 it::assert_equal(ys.iter(), xs.iter().unique());
111 it::assert_equal(ys.iter(), xs.iter().rev().unique().rev());
112 let ys_rev = [1, 0];
113 it::assert_equal(ys_rev.iter(), xs.iter().unique().rev());
114 }
115
116 #[test]
intersperse()117 fn intersperse() {
118 let xs = ["a", "", "b", "c"];
119 let v: Vec<&str> = xs.iter().map(|x| x.clone()).intersperse(", ").collect();
120 let text: String = v.concat();
121 assert_eq!(text, "a, , b, c".to_string());
122
123 let ys = [0, 1, 2, 3];
124 let mut it = ys[..0].iter().map(|x| *x).intersperse(1);
125 assert!(it.next() == None);
126 }
127
128 #[test]
dedup()129 fn dedup() {
130 let xs = [0, 1, 1, 1, 2, 1, 3, 3];
131 let ys = [0, 1, 2, 1, 3];
132 it::assert_equal(ys.iter(), xs.iter().dedup());
133 let xs = [0, 0, 0, 0, 0];
134 let ys = [0];
135 it::assert_equal(ys.iter(), xs.iter().dedup());
136
137 let xs = [0, 1, 1, 1, 2, 1, 3, 3];
138 let ys = [0, 1, 2, 1, 3];
139 let mut xs_d = Vec::new();
140 xs.iter().dedup().fold((), |(), &elt| xs_d.push(elt));
141 assert_eq!(&xs_d, &ys);
142 }
143
144 #[test]
coalesce()145 fn coalesce() {
146 let data = vec![-1., -2., -3., 3., 1., 0., -1.];
147 let it = data.iter().cloned().coalesce(|x, y|
148 if (x >= 0.) == (y >= 0.) {
149 Ok(x + y)
150 } else {
151 Err((x, y))
152 }
153 );
154 itertools::assert_equal(it.clone(), vec![-6., 4., -1.]);
155 assert_eq!(
156 it.fold(vec![], |mut v, n| {
157 v.push(n);
158 v
159 }),
160 vec![-6., 4., -1.]
161 );
162 }
163
164 #[test]
dedup_by()165 fn dedup_by() {
166 let xs = [(0, 0), (0, 1), (1, 1), (2, 1), (0, 2), (3, 1), (0, 3), (1, 3)];
167 let ys = [(0, 0), (0, 1), (0, 2), (3, 1), (0, 3)];
168 it::assert_equal(ys.iter(), xs.iter().dedup_by(|x, y| x.1==y.1));
169 let xs = [(0, 1), (0, 2), (0, 3), (0, 4), (0, 5)];
170 let ys = [(0, 1)];
171 it::assert_equal(ys.iter(), xs.iter().dedup_by(|x, y| x.0==y.0));
172
173 let xs = [(0, 0), (0, 1), (1, 1), (2, 1), (0, 2), (3, 1), (0, 3), (1, 3)];
174 let ys = [(0, 0), (0, 1), (0, 2), (3, 1), (0, 3)];
175 let mut xs_d = Vec::new();
176 xs.iter().dedup_by(|x, y| x.1==y.1).fold((), |(), &elt| xs_d.push(elt));
177 assert_eq!(&xs_d, &ys);
178 }
179
180 #[test]
dedup_with_count()181 fn dedup_with_count() {
182 let xs: [i32; 8] = [0, 1, 1, 1, 2, 1, 3, 3];
183 let ys: [(usize, &i32); 5] = [(1, &0), (3, &1), (1, &2), (1, &1), (2, &3)];
184
185 it::assert_equal(ys.iter().cloned(), xs.iter().dedup_with_count());
186
187 let xs: [i32; 5] = [0, 0, 0, 0, 0];
188 let ys: [(usize, &i32); 1] = [(5, &0)];
189
190 it::assert_equal(ys.iter().cloned(), xs.iter().dedup_with_count());
191 }
192
193
194 #[test]
dedup_by_with_count()195 fn dedup_by_with_count() {
196 let xs = [(0, 0), (0, 1), (1, 1), (2, 1), (0, 2), (3, 1), (0, 3), (1, 3)];
197 let ys = [(1, &(0, 0)), (3, &(0, 1)), (1, &(0, 2)), (1, &(3, 1)), (2, &(0, 3))];
198
199 it::assert_equal(ys.iter().cloned(), xs.iter().dedup_by_with_count(|x, y| x.1==y.1));
200
201 let xs = [(0, 1), (0, 2), (0, 3), (0, 4), (0, 5)];
202 let ys = [( 5, &(0, 1))];
203
204 it::assert_equal(ys.iter().cloned(), xs.iter().dedup_by_with_count(|x, y| x.0==y.0));
205 }
206
207 #[test]
all_equal()208 fn all_equal() {
209 assert!("".chars().all_equal());
210 assert!("A".chars().all_equal());
211 assert!(!"AABBCCC".chars().all_equal());
212 assert!("AAAAAAA".chars().all_equal());
213 for (_key, mut sub) in &"AABBCCC".chars().group_by(|&x| x) {
214 assert!(sub.all_equal());
215 }
216 }
217
218 #[test]
all_unique()219 fn all_unique() {
220 assert!("ABCDEFGH".chars().all_unique());
221 assert!(!"ABCDEFGA".chars().all_unique());
222 assert!(::std::iter::empty::<usize>().all_unique());
223 }
224
225 #[test]
test_put_back_n()226 fn test_put_back_n() {
227 let xs = [0, 1, 1, 1, 2, 1, 3, 3];
228 let mut pb = put_back_n(xs.iter().cloned());
229 pb.next();
230 pb.next();
231 pb.put_back(1);
232 pb.put_back(0);
233 it::assert_equal(pb, xs.iter().cloned());
234 }
235
236 #[test]
tee()237 fn tee() {
238 let xs = [0, 1, 2, 3];
239 let (mut t1, mut t2) = xs.iter().cloned().tee();
240 assert_eq!(t1.next(), Some(0));
241 assert_eq!(t2.next(), Some(0));
242 assert_eq!(t1.next(), Some(1));
243 assert_eq!(t1.next(), Some(2));
244 assert_eq!(t1.next(), Some(3));
245 assert_eq!(t1.next(), None);
246 assert_eq!(t2.next(), Some(1));
247 assert_eq!(t2.next(), Some(2));
248 assert_eq!(t1.next(), None);
249 assert_eq!(t2.next(), Some(3));
250 assert_eq!(t2.next(), None);
251 assert_eq!(t1.next(), None);
252 assert_eq!(t2.next(), None);
253
254 let (t1, t2) = xs.iter().cloned().tee();
255 it::assert_equal(t1, xs.iter().cloned());
256 it::assert_equal(t2, xs.iter().cloned());
257
258 let (t1, t2) = xs.iter().cloned().tee();
259 it::assert_equal(t1.zip(t2), xs.iter().cloned().zip(xs.iter().cloned()));
260 }
261
262
263 #[test]
test_rciter()264 fn test_rciter() {
265 let xs = [0, 1, 1, 1, 2, 1, 3, 5, 6];
266
267 let mut r1 = rciter(xs.iter().cloned());
268 let mut r2 = r1.clone();
269 assert_eq!(r1.next(), Some(0));
270 assert_eq!(r2.next(), Some(1));
271 let mut z = r1.zip(r2);
272 assert_eq!(z.next(), Some((1, 1)));
273 assert_eq!(z.next(), Some((2, 1)));
274 assert_eq!(z.next(), Some((3, 5)));
275 assert_eq!(z.next(), None);
276
277 // test intoiterator
278 let r1 = rciter(0..5);
279 let mut z = izip!(&r1, r1);
280 assert_eq!(z.next(), Some((0, 1)));
281 }
282
283 #[allow(deprecated)]
284 #[test]
trait_pointers()285 fn trait_pointers() {
286 struct ByRef<'r, I: ?Sized>(&'r mut I) ;
287
288 impl<'r, X, I: ?Sized> Iterator for ByRef<'r, I> where
289 I: 'r + Iterator<Item=X>
290 {
291 type Item = X;
292 fn next(&mut self) -> Option<Self::Item>
293 {
294 self.0.next()
295 }
296 }
297
298 let mut it = Box::new(0..10) as Box<dyn Iterator<Item=i32>>;
299 assert_eq!(it.next(), Some(0));
300
301 {
302 /* make sure foreach works on non-Sized */
303 let jt: &mut dyn Iterator<Item = i32> = &mut *it;
304 assert_eq!(jt.next(), Some(1));
305
306 {
307 let mut r = ByRef(jt);
308 assert_eq!(r.next(), Some(2));
309 }
310
311 assert_eq!(jt.find_position(|x| *x == 4), Some((1, 4)));
312 jt.foreach(|_| ());
313 }
314 }
315
316 #[test]
merge_by()317 fn merge_by() {
318 let odd : Vec<(u32, &str)> = vec![(1, "hello"), (3, "world"), (5, "!")];
319 let even = vec![(2, "foo"), (4, "bar"), (6, "baz")];
320 let expected = vec![(1, "hello"), (2, "foo"), (3, "world"), (4, "bar"), (5, "!"), (6, "baz")];
321 let results = odd.iter().merge_by(even.iter(), |a, b| a.0 <= b.0);
322 it::assert_equal(results, expected.iter());
323 }
324
325 #[test]
merge_by_btree()326 fn merge_by_btree() {
327 use std::collections::BTreeMap;
328 let mut bt1 = BTreeMap::new();
329 bt1.insert("hello", 1);
330 bt1.insert("world", 3);
331 let mut bt2 = BTreeMap::new();
332 bt2.insert("foo", 2);
333 bt2.insert("bar", 4);
334 let results = bt1.into_iter().merge_by(bt2.into_iter(), |a, b| a.0 <= b.0 );
335 let expected = vec![("bar", 4), ("foo", 2), ("hello", 1), ("world", 3)];
336 it::assert_equal(results, expected.into_iter());
337 }
338
339 #[allow(deprecated)]
340 #[test]
kmerge()341 fn kmerge() {
342 let its = (0..4).map(|s| (s..10).step(4));
343
344 it::assert_equal(its.kmerge(), 0..10);
345 }
346
347 #[allow(deprecated)]
348 #[test]
kmerge_2()349 fn kmerge_2() {
350 let its = vec![3, 2, 1, 0].into_iter().map(|s| (s..10).step(4));
351
352 it::assert_equal(its.kmerge(), 0..10);
353 }
354
355 #[test]
kmerge_empty()356 fn kmerge_empty() {
357 let its = (0..4).map(|_| 0..0);
358 assert_eq!(its.kmerge().next(), None);
359 }
360
361 #[test]
kmerge_size_hint()362 fn kmerge_size_hint() {
363 let its = (0..5).map(|_| (0..10));
364 assert_eq!(its.kmerge().size_hint(), (50, Some(50)));
365 }
366
367 #[test]
kmerge_empty_size_hint()368 fn kmerge_empty_size_hint() {
369 let its = (0..5).map(|_| (0..0));
370 assert_eq!(its.kmerge().size_hint(), (0, Some(0)));
371 }
372
373 #[test]
join()374 fn join() {
375 let many = [1, 2, 3];
376 let one = [1];
377 let none: Vec<i32> = vec![];
378
379 assert_eq!(many.iter().join(", "), "1, 2, 3");
380 assert_eq!( one.iter().join(", "), "1");
381 assert_eq!(none.iter().join(", "), "");
382 }
383
384 #[test]
sorted_unstable_by()385 fn sorted_unstable_by() {
386 let sc = [3, 4, 1, 2].iter().cloned().sorted_by(|&a, &b| {
387 a.cmp(&b)
388 });
389 it::assert_equal(sc, vec![1, 2, 3, 4]);
390
391 let v = (0..5).sorted_unstable_by(|&a, &b| a.cmp(&b).reverse());
392 it::assert_equal(v, vec![4, 3, 2, 1, 0]);
393 }
394
395 #[test]
sorted_unstable_by_key()396 fn sorted_unstable_by_key() {
397 let sc = [3, 4, 1, 2].iter().cloned().sorted_unstable_by_key(|&x| x);
398 it::assert_equal(sc, vec![1, 2, 3, 4]);
399
400 let v = (0..5).sorted_unstable_by_key(|&x| -x);
401 it::assert_equal(v, vec![4, 3, 2, 1, 0]);
402 }
403
404 #[test]
sorted_by()405 fn sorted_by() {
406 let sc = [3, 4, 1, 2].iter().cloned().sorted_by(|&a, &b| {
407 a.cmp(&b)
408 });
409 it::assert_equal(sc, vec![1, 2, 3, 4]);
410
411 let v = (0..5).sorted_by(|&a, &b| a.cmp(&b).reverse());
412 it::assert_equal(v, vec![4, 3, 2, 1, 0]);
413 }
414
415 qc::quickcheck! {
416 fn k_smallest_range(n: u64, m: u16, k: u16) -> () {
417 // u16 is used to constrain k and m to 0..2¹⁶,
418 // otherwise the test could use too much memory.
419 let (k, m) = (k as u64, m as u64);
420
421 // Generate a random permutation of n..n+m
422 let i = {
423 let mut v: Vec<u64> = (n..n.saturating_add(m)).collect();
424 v.shuffle(&mut thread_rng());
425 v.into_iter()
426 };
427
428 // Check that taking the k smallest elements yields n..n+min(k, m)
429 it::assert_equal(
430 i.k_smallest(k as usize),
431 n..n.saturating_add(min(k, m))
432 );
433 }
434 }
435
436 #[derive(Clone, Debug)]
437 struct RandIter<T: 'static + Clone + Send, R: 'static + Clone + Rng + SeedableRng + Send = StdRng> {
438 idx: usize,
439 len: usize,
440 rng: R,
441 _t: PhantomData<T>
442 }
443
444 impl<T: Clone + Send, R: Clone + Rng + SeedableRng + Send> Iterator for RandIter<T, R>
445 where Standard: Distribution<T> {
446 type Item = T;
next(&mut self) -> Option<T>447 fn next(&mut self) -> Option<T> {
448 if self.idx == self.len {
449 None
450 } else {
451 self.idx += 1;
452 Some(self.rng.gen())
453 }
454 }
455 }
456
457 impl<T: Clone + Send, R: Clone + Rng + SeedableRng + Send> qc::Arbitrary for RandIter<T, R> {
arbitrary<G: qc::Gen>(g: &mut G) -> Self458 fn arbitrary<G: qc::Gen>(g: &mut G) -> Self {
459 RandIter {
460 idx: 0,
461 len: g.size(),
462 rng: R::seed_from_u64(g.next_u64()),
463 _t : PhantomData{},
464 }
465 }
466 }
467
468 // Check that taking the k smallest is the same as
469 // sorting then taking the k first elements
k_smallest_sort<I>(i: I, k: u16) -> () where I: Iterator + Clone, I::Item: Ord + Debug,470 fn k_smallest_sort<I>(i: I, k: u16) -> ()
471 where
472 I: Iterator + Clone,
473 I::Item: Ord + Debug,
474 {
475 let j = i.clone();
476 let k = k as usize;
477 it::assert_equal(
478 i.k_smallest(k),
479 j.sorted().take(k)
480 )
481 }
482
483 macro_rules! generic_test {
484 ($f:ident, $($t:ty),+) => {
485 $(paste::item! {
486 qc::quickcheck! {
487 fn [< $f _ $t >](i: RandIter<$t>, k: u16) -> () {
488 $f(i, k)
489 }
490 }
491 })+
492 };
493 }
494
495 generic_test!(k_smallest_sort, u8, u16, u32, u64, i8, i16, i32, i64);
496
497 #[test]
sorted_by_key()498 fn sorted_by_key() {
499 let sc = [3, 4, 1, 2].iter().cloned().sorted_by_key(|&x| x);
500 it::assert_equal(sc, vec![1, 2, 3, 4]);
501
502 let v = (0..5).sorted_by_key(|&x| -x);
503 it::assert_equal(v, vec![4, 3, 2, 1, 0]);
504 }
505
506 #[test]
test_multipeek()507 fn test_multipeek() {
508 let nums = vec![1u8,2,3,4,5];
509
510 let mp = multipeek(nums.iter().map(|&x| x));
511 assert_eq!(nums, mp.collect::<Vec<_>>());
512
513 let mut mp = multipeek(nums.iter().map(|&x| x));
514 assert_eq!(mp.peek(), Some(&1));
515 assert_eq!(mp.next(), Some(1));
516 assert_eq!(mp.peek(), Some(&2));
517 assert_eq!(mp.peek(), Some(&3));
518 assert_eq!(mp.next(), Some(2));
519 assert_eq!(mp.peek(), Some(&3));
520 assert_eq!(mp.peek(), Some(&4));
521 assert_eq!(mp.peek(), Some(&5));
522 assert_eq!(mp.peek(), None);
523 assert_eq!(mp.next(), Some(3));
524 assert_eq!(mp.next(), Some(4));
525 assert_eq!(mp.peek(), Some(&5));
526 assert_eq!(mp.peek(), None);
527 assert_eq!(mp.next(), Some(5));
528 assert_eq!(mp.next(), None);
529 assert_eq!(mp.peek(), None);
530 }
531
532 #[test]
test_multipeek_reset()533 fn test_multipeek_reset() {
534 let data = [1, 2, 3, 4];
535
536 let mut mp = multipeek(cloned(&data));
537 assert_eq!(mp.peek(), Some(&1));
538 assert_eq!(mp.next(), Some(1));
539 assert_eq!(mp.peek(), Some(&2));
540 assert_eq!(mp.peek(), Some(&3));
541 mp.reset_peek();
542 assert_eq!(mp.peek(), Some(&2));
543 assert_eq!(mp.next(), Some(2));
544 }
545
546 #[test]
test_multipeek_peeking_next()547 fn test_multipeek_peeking_next() {
548 use crate::it::PeekingNext;
549 let nums = vec![1u8,2,3,4,5,6,7];
550
551 let mut mp = multipeek(nums.iter().map(|&x| x));
552 assert_eq!(mp.peeking_next(|&x| x != 0), Some(1));
553 assert_eq!(mp.next(), Some(2));
554 assert_eq!(mp.peek(), Some(&3));
555 assert_eq!(mp.peek(), Some(&4));
556 assert_eq!(mp.peeking_next(|&x| x == 3), Some(3));
557 assert_eq!(mp.peek(), Some(&4));
558 assert_eq!(mp.peeking_next(|&x| x != 4), None);
559 assert_eq!(mp.peeking_next(|&x| x == 4), Some(4));
560 assert_eq!(mp.peek(), Some(&5));
561 assert_eq!(mp.peek(), Some(&6));
562 assert_eq!(mp.peeking_next(|&x| x != 5), None);
563 assert_eq!(mp.peek(), Some(&7));
564 assert_eq!(mp.peeking_next(|&x| x == 5), Some(5));
565 assert_eq!(mp.peeking_next(|&x| x == 6), Some(6));
566 assert_eq!(mp.peek(), Some(&7));
567 assert_eq!(mp.peek(), None);
568 assert_eq!(mp.next(), Some(7));
569 assert_eq!(mp.peek(), None);
570 }
571
572 #[test]
test_peek_nth()573 fn test_peek_nth() {
574 let nums = vec![1u8,2,3,4,5];
575
576 let iter = peek_nth(nums.iter().map(|&x| x));
577 assert_eq!(nums, iter.collect::<Vec<_>>());
578
579 let mut iter = peek_nth(nums.iter().map(|&x| x));
580
581 assert_eq!(iter.peek_nth(0), Some(&1));
582 assert_eq!(iter.peek_nth(0), Some(&1));
583 assert_eq!(iter.next(), Some(1));
584
585 assert_eq!(iter.peek_nth(0), Some(&2));
586 assert_eq!(iter.peek_nth(1), Some(&3));
587 assert_eq!(iter.next(), Some(2));
588
589 assert_eq!(iter.peek_nth(0), Some(&3));
590 assert_eq!(iter.peek_nth(1), Some(&4));
591 assert_eq!(iter.peek_nth(2), Some(&5));
592 assert_eq!(iter.peek_nth(3), None);
593
594 assert_eq!(iter.next(), Some(3));
595 assert_eq!(iter.next(), Some(4));
596
597 assert_eq!(iter.peek_nth(0), Some(&5));
598 assert_eq!(iter.peek_nth(1), None);
599 assert_eq!(iter.next(), Some(5));
600 assert_eq!(iter.next(), None);
601
602 assert_eq!(iter.peek_nth(0), None);
603 assert_eq!(iter.peek_nth(1), None);
604 }
605
606 #[test]
test_peek_nth_peeking_next()607 fn test_peek_nth_peeking_next() {
608 use it::PeekingNext;
609 let nums = vec![1u8,2,3,4,5,6,7];
610 let mut iter = peek_nth(nums.iter().map(|&x| x));
611
612 assert_eq!(iter.peeking_next(|&x| x != 0), Some(1));
613 assert_eq!(iter.next(), Some(2));
614
615 assert_eq!(iter.peek_nth(0), Some(&3));
616 assert_eq!(iter.peek_nth(1), Some(&4));
617 assert_eq!(iter.peeking_next(|&x| x == 3), Some(3));
618 assert_eq!(iter.peek(), Some(&4));
619
620 assert_eq!(iter.peeking_next(|&x| x != 4), None);
621 assert_eq!(iter.peeking_next(|&x| x == 4), Some(4));
622 assert_eq!(iter.peek_nth(0), Some(&5));
623 assert_eq!(iter.peek_nth(1), Some(&6));
624
625 assert_eq!(iter.peeking_next(|&x| x != 5), None);
626 assert_eq!(iter.peek(), Some(&5));
627
628 assert_eq!(iter.peeking_next(|&x| x == 5), Some(5));
629 assert_eq!(iter.peeking_next(|&x| x == 6), Some(6));
630 assert_eq!(iter.peek_nth(0), Some(&7));
631 assert_eq!(iter.peek_nth(1), None);
632 assert_eq!(iter.next(), Some(7));
633 assert_eq!(iter.peek(), None);
634 }
635
636 #[test]
pad_using()637 fn pad_using() {
638 it::assert_equal((0..0).pad_using(1, |_| 1), 1..2);
639
640 let v: Vec<usize> = vec![0, 1, 2];
641 let r = v.into_iter().pad_using(5, |n| n);
642 it::assert_equal(r, vec![0, 1, 2, 3, 4]);
643
644 let v: Vec<usize> = vec![0, 1, 2];
645 let r = v.into_iter().pad_using(1, |_| panic!());
646 it::assert_equal(r, vec![0, 1, 2]);
647 }
648
649 #[test]
group_by()650 fn group_by() {
651 for (ch1, sub) in &"AABBCCC".chars().group_by(|&x| x) {
652 for ch2 in sub {
653 assert_eq!(ch1, ch2);
654 }
655 }
656
657 for (ch1, sub) in &"AAABBBCCCCDDDD".chars().group_by(|&x| x) {
658 for ch2 in sub {
659 assert_eq!(ch1, ch2);
660 if ch1 == 'C' {
661 break;
662 }
663 }
664 }
665
666 let toupper = |ch: &char| ch.to_uppercase().nth(0).unwrap();
667
668 // try all possible orderings
669 for indices in permutohedron::Heap::new(&mut [0, 1, 2, 3]) {
670 let groups = "AaaBbbccCcDDDD".chars().group_by(&toupper);
671 let mut subs = groups.into_iter().collect_vec();
672
673 for &idx in &indices[..] {
674 let (key, text) = match idx {
675 0 => ('A', "Aaa".chars()),
676 1 => ('B', "Bbb".chars()),
677 2 => ('C', "ccCc".chars()),
678 3 => ('D', "DDDD".chars()),
679 _ => unreachable!(),
680 };
681 assert_eq!(key, subs[idx].0);
682 it::assert_equal(&mut subs[idx].1, text);
683 }
684 }
685
686 let groups = "AAABBBCCCCDDDD".chars().group_by(|&x| x);
687 let mut subs = groups.into_iter().map(|(_, g)| g).collect_vec();
688
689 let sd = subs.pop().unwrap();
690 let sc = subs.pop().unwrap();
691 let sb = subs.pop().unwrap();
692 let sa = subs.pop().unwrap();
693 for (a, b, c, d) in multizip((sa, sb, sc, sd)) {
694 assert_eq!(a, 'A');
695 assert_eq!(b, 'B');
696 assert_eq!(c, 'C');
697 assert_eq!(d, 'D');
698 }
699
700 // check that the key closure is called exactly n times
701 {
702 let mut ntimes = 0;
703 let text = "AABCCC";
704 for (_, sub) in &text.chars().group_by(|&x| { ntimes += 1; x}) {
705 for _ in sub {
706 }
707 }
708 assert_eq!(ntimes, text.len());
709 }
710
711 {
712 let mut ntimes = 0;
713 let text = "AABCCC";
714 for _ in &text.chars().group_by(|&x| { ntimes += 1; x}) {
715 }
716 assert_eq!(ntimes, text.len());
717 }
718
719 {
720 let text = "ABCCCDEEFGHIJJKK";
721 let gr = text.chars().group_by(|&x| x);
722 it::assert_equal(gr.into_iter().flat_map(|(_, sub)| sub), text.chars());
723 }
724 }
725
726 #[test]
group_by_lazy_2()727 fn group_by_lazy_2() {
728 let data = vec![0, 1];
729 let groups = data.iter().group_by(|k| *k);
730 let gs = groups.into_iter().collect_vec();
731 it::assert_equal(data.iter(), gs.into_iter().flat_map(|(_k, g)| g));
732
733 let data = vec![0, 1, 1, 0, 0];
734 let groups = data.iter().group_by(|k| *k);
735 let mut gs = groups.into_iter().collect_vec();
736 gs[1..].reverse();
737 it::assert_equal(&[0, 0, 0, 1, 1], gs.into_iter().flat_map(|(_, g)| g));
738
739 let grouper = data.iter().group_by(|k| *k);
740 let mut groups = Vec::new();
741 for (k, group) in &grouper {
742 if *k == 1 {
743 groups.push(group);
744 }
745 }
746 it::assert_equal(&mut groups[0], &[1, 1]);
747
748 let data = vec![0, 0, 0, 1, 1, 0, 0, 2, 2, 3, 3];
749 let grouper = data.iter().group_by(|k| *k);
750 let mut groups = Vec::new();
751 for (i, (_, group)) in grouper.into_iter().enumerate() {
752 if i < 2 {
753 groups.push(group);
754 } else if i < 4 {
755 for _ in group {
756 }
757 } else {
758 groups.push(group);
759 }
760 }
761 it::assert_equal(&mut groups[0], &[0, 0, 0]);
762 it::assert_equal(&mut groups[1], &[1, 1]);
763 it::assert_equal(&mut groups[2], &[3, 3]);
764
765 // use groups as chunks
766 let data = vec![0, 0, 0, 1, 1, 0, 0, 2, 2, 3, 3];
767 let mut i = 0;
768 let grouper = data.iter().group_by(move |_| { let k = i / 3; i += 1; k });
769 for (i, group) in &grouper {
770 match i {
771 0 => it::assert_equal(group, &[0, 0, 0]),
772 1 => it::assert_equal(group, &[1, 1, 0]),
773 2 => it::assert_equal(group, &[0, 2, 2]),
774 3 => it::assert_equal(group, &[3, 3]),
775 _ => unreachable!(),
776 }
777 }
778 }
779
780 #[test]
group_by_lazy_3()781 fn group_by_lazy_3() {
782 // test consuming each group on the lap after it was produced
783 let data = vec![0, 0, 0, 1, 1, 0, 0, 1, 1, 2, 2];
784 let grouper = data.iter().group_by(|elt| *elt);
785 let mut last = None;
786 for (key, group) in &grouper {
787 if let Some(gr) = last.take() {
788 for elt in gr {
789 assert!(elt != key && i32::abs(elt - key) == 1);
790 }
791 }
792 last = Some(group);
793 }
794 }
795
796 #[test]
chunks()797 fn chunks() {
798 let data = vec![0, 0, 0, 1, 1, 0, 0, 2, 2, 3, 3];
799 let grouper = data.iter().chunks(3);
800 for (i, chunk) in grouper.into_iter().enumerate() {
801 match i {
802 0 => it::assert_equal(chunk, &[0, 0, 0]),
803 1 => it::assert_equal(chunk, &[1, 1, 0]),
804 2 => it::assert_equal(chunk, &[0, 2, 2]),
805 3 => it::assert_equal(chunk, &[3, 3]),
806 _ => unreachable!(),
807 }
808 }
809 }
810
811 #[test]
concat_empty()812 fn concat_empty() {
813 let data: Vec<Vec<()>> = Vec::new();
814 assert_eq!(data.into_iter().concat(), Vec::new())
815 }
816
817 #[test]
concat_non_empty()818 fn concat_non_empty() {
819 let data = vec![vec![1,2,3], vec![4,5,6], vec![7,8,9]];
820 assert_eq!(data.into_iter().concat(), vec![1,2,3,4,5,6,7,8,9])
821 }
822
823 #[test]
combinations()824 fn combinations() {
825 assert!((1..3).combinations(5).next().is_none());
826
827 let it = (1..3).combinations(2);
828 it::assert_equal(it, vec![
829 vec![1, 2],
830 ]);
831
832 let it = (1..5).combinations(2);
833 it::assert_equal(it, vec![
834 vec![1, 2],
835 vec![1, 3],
836 vec![1, 4],
837 vec![2, 3],
838 vec![2, 4],
839 vec![3, 4],
840 ]);
841
842 it::assert_equal((0..0).tuple_combinations::<(_, _)>(), <Vec<_>>::new());
843 it::assert_equal((0..1).tuple_combinations::<(_, _)>(), <Vec<_>>::new());
844 it::assert_equal((0..2).tuple_combinations::<(_, _)>(), vec![(0, 1)]);
845
846 it::assert_equal((0..0).combinations(2), <Vec<Vec<_>>>::new());
847 it::assert_equal((0..1).combinations(1), vec![vec![0]]);
848 it::assert_equal((0..2).combinations(1), vec![vec![0], vec![1]]);
849 it::assert_equal((0..2).combinations(2), vec![vec![0, 1]]);
850 }
851
852 #[test]
combinations_of_too_short()853 fn combinations_of_too_short() {
854 for i in 1..10 {
855 assert!((0..0).combinations(i).next().is_none());
856 assert!((0..i - 1).combinations(i).next().is_none());
857 }
858 }
859
860
861 #[test]
combinations_zero()862 fn combinations_zero() {
863 it::assert_equal((1..3).combinations(0), vec![vec![]]);
864 it::assert_equal((0..0).combinations(0), vec![vec![]]);
865 }
866
867 #[test]
permutations_zero()868 fn permutations_zero() {
869 it::assert_equal((1..3).permutations(0), vec![vec![]]);
870 it::assert_equal((0..0).permutations(0), vec![vec![]]);
871 }
872
873 #[test]
combinations_with_replacement()874 fn combinations_with_replacement() {
875 // Pool smaller than n
876 it::assert_equal((0..1).combinations_with_replacement(2), vec![vec![0, 0]]);
877 // Pool larger than n
878 it::assert_equal(
879 (0..3).combinations_with_replacement(2),
880 vec![
881 vec![0, 0],
882 vec![0, 1],
883 vec![0, 2],
884 vec![1, 1],
885 vec![1, 2],
886 vec![2, 2],
887 ],
888 );
889 // Zero size
890 it::assert_equal(
891 (0..3).combinations_with_replacement(0),
892 vec![vec![]],
893 );
894 // Zero size on empty pool
895 it::assert_equal(
896 (0..0).combinations_with_replacement(0),
897 vec![vec![]],
898 );
899 // Empty pool
900 it::assert_equal(
901 (0..0).combinations_with_replacement(2),
902 <Vec<Vec<_>>>::new(),
903 );
904 }
905
906 #[test]
powerset()907 fn powerset() {
908 it::assert_equal((0..0).powerset(), vec![vec![]]);
909 it::assert_equal((0..1).powerset(), vec![vec![], vec![0]]);
910 it::assert_equal((0..2).powerset(), vec![vec![], vec![0], vec![1], vec![0, 1]]);
911 it::assert_equal((0..3).powerset(), vec![
912 vec![],
913 vec![0], vec![1], vec![2],
914 vec![0, 1], vec![0, 2], vec![1, 2],
915 vec![0, 1, 2]
916 ]);
917
918 assert_eq!((0..4).powerset().count(), 1 << 4);
919 assert_eq!((0..8).powerset().count(), 1 << 8);
920 assert_eq!((0..16).powerset().count(), 1 << 16);
921 }
922
923 #[test]
diff_mismatch()924 fn diff_mismatch() {
925 let a = vec![1, 2, 3, 4];
926 let b = vec![1.0, 5.0, 3.0, 4.0];
927 let b_map = b.into_iter().map(|f| f as i32);
928 let diff = it::diff_with(a.iter(), b_map, |a, b| *a == b);
929
930 assert!(match diff {
931 Some(it::Diff::FirstMismatch(1, _, from_diff)) =>
932 from_diff.collect::<Vec<_>>() == vec![5, 3, 4],
933 _ => false,
934 });
935 }
936
937 #[test]
diff_longer()938 fn diff_longer() {
939 let a = vec![1, 2, 3, 4];
940 let b = vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0];
941 let b_map = b.into_iter().map(|f| f as i32);
942 let diff = it::diff_with(a.iter(), b_map, |a, b| *a == b);
943
944 assert!(match diff {
945 Some(it::Diff::Longer(_, remaining)) =>
946 remaining.collect::<Vec<_>>() == vec![5, 6],
947 _ => false,
948 });
949 }
950
951 #[test]
diff_shorter()952 fn diff_shorter() {
953 let a = vec![1, 2, 3, 4];
954 let b = vec![1.0, 2.0];
955 let b_map = b.into_iter().map(|f| f as i32);
956 let diff = it::diff_with(a.iter(), b_map, |a, b| *a == b);
957
958 assert!(match diff {
959 Some(it::Diff::Shorter(len, _)) => len == 2,
960 _ => false,
961 });
962 }
963
964 #[test]
minmax()965 fn minmax() {
966 use std::cmp::Ordering;
967 use crate::it::MinMaxResult;
968
969 // A peculiar type: Equality compares both tuple items, but ordering only the
970 // first item. This is so we can check the stability property easily.
971 #[derive(Clone, Debug, PartialEq, Eq)]
972 struct Val(u32, u32);
973
974 impl PartialOrd<Val> for Val {
975 fn partial_cmp(&self, other: &Val) -> Option<Ordering> {
976 self.0.partial_cmp(&other.0)
977 }
978 }
979
980 impl Ord for Val {
981 fn cmp(&self, other: &Val) -> Ordering {
982 self.0.cmp(&other.0)
983 }
984 }
985
986 assert_eq!(None::<Option<u32>>.iter().minmax(), MinMaxResult::NoElements);
987
988 assert_eq!(Some(1u32).iter().minmax(), MinMaxResult::OneElement(&1));
989
990 let data = vec![Val(0, 1), Val(2, 0), Val(0, 2), Val(1, 0), Val(2, 1)];
991
992 let minmax = data.iter().minmax();
993 assert_eq!(minmax, MinMaxResult::MinMax(&Val(0, 1), &Val(2, 1)));
994
995 let (min, max) = data.iter().minmax_by_key(|v| v.1).into_option().unwrap();
996 assert_eq!(min, &Val(2, 0));
997 assert_eq!(max, &Val(0, 2));
998
999 let (min, max) = data.iter().minmax_by(|x, y| x.1.cmp(&y.1)).into_option().unwrap();
1000 assert_eq!(min, &Val(2, 0));
1001 assert_eq!(max, &Val(0, 2));
1002 }
1003
1004 #[test]
format()1005 fn format() {
1006 let data = [0, 1, 2, 3];
1007 let ans1 = "0, 1, 2, 3";
1008 let ans2 = "0--1--2--3";
1009
1010 let t1 = format!("{}", data.iter().format(", "));
1011 assert_eq!(t1, ans1);
1012 let t2 = format!("{:?}", data.iter().format("--"));
1013 assert_eq!(t2, ans2);
1014
1015 let dataf = [1.1, 2.71828, -22.];
1016 let t3 = format!("{:.2e}", dataf.iter().format(", "));
1017 assert_eq!(t3, "1.10e0, 2.72e0, -2.20e1");
1018 }
1019
1020 #[test]
while_some()1021 fn while_some() {
1022 let ns = (1..10).map(|x| if x % 5 != 0 { Some(x) } else { None })
1023 .while_some();
1024 it::assert_equal(ns, vec![1, 2, 3, 4]);
1025 }
1026
1027 #[allow(deprecated)]
1028 #[test]
fold_while()1029 fn fold_while() {
1030 let mut iterations = 0;
1031 let vec = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
1032 let sum = vec.into_iter().fold_while(0, |acc, item| {
1033 iterations += 1;
1034 let new_sum = acc.clone() + item;
1035 if new_sum <= 20 {
1036 FoldWhile::Continue(new_sum)
1037 } else {
1038 FoldWhile::Done(acc)
1039 }
1040 }).into_inner();
1041 assert_eq!(iterations, 6);
1042 assert_eq!(sum, 15);
1043 }
1044
1045 #[test]
tree_fold1()1046 fn tree_fold1() {
1047 let x = [
1048 "",
1049 "0",
1050 "0 1 x",
1051 "0 1 x 2 x",
1052 "0 1 x 2 3 x x",
1053 "0 1 x 2 3 x x 4 x",
1054 "0 1 x 2 3 x x 4 5 x x",
1055 "0 1 x 2 3 x x 4 5 x 6 x x",
1056 "0 1 x 2 3 x x 4 5 x 6 7 x x x",
1057 "0 1 x 2 3 x x 4 5 x 6 7 x x x 8 x",
1058 "0 1 x 2 3 x x 4 5 x 6 7 x x x 8 9 x x",
1059 "0 1 x 2 3 x x 4 5 x 6 7 x x x 8 9 x 10 x x",
1060 "0 1 x 2 3 x x 4 5 x 6 7 x x x 8 9 x 10 11 x x x",
1061 "0 1 x 2 3 x x 4 5 x 6 7 x x x 8 9 x 10 11 x x 12 x x",
1062 "0 1 x 2 3 x x 4 5 x 6 7 x x x 8 9 x 10 11 x x 12 13 x x x",
1063 "0 1 x 2 3 x x 4 5 x 6 7 x x x 8 9 x 10 11 x x 12 13 x 14 x x x",
1064 "0 1 x 2 3 x x 4 5 x 6 7 x x x 8 9 x 10 11 x x 12 13 x 14 15 x x x x",
1065 ];
1066 for (i, &s) in x.iter().enumerate() {
1067 let expected = if s == "" { None } else { Some(s.to_string()) };
1068 let num_strings = (0..i).map(|x| x.to_string());
1069 let actual = num_strings.tree_fold1(|a, b| format!("{} {} x", a, b));
1070 assert_eq!(actual, expected);
1071 }
1072 }
1073
1074 #[test]
exactly_one_question_mark_syntax_works()1075 fn exactly_one_question_mark_syntax_works() {
1076 exactly_one_question_mark_return().unwrap_err();
1077 }
1078
exactly_one_question_mark_return() -> Result<(), ExactlyOneError<std::slice::Iter<'static, ()>>>1079 fn exactly_one_question_mark_return() -> Result<(), ExactlyOneError<std::slice::Iter<'static, ()>>> {
1080 [].iter().exactly_one()?;
1081 Ok(())
1082 }
1083