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