]>
Commit | Line | Data |
---|---|---|
abe05a73 XL |
1 | //! Licensed under the Apache License, Version 2.0 |
2 | //! http://www.apache.org/licenses/LICENSE-2.0 or the MIT license | |
3 | //! http://opensource.org/licenses/MIT, at your | |
4 | //! option. This file may not be copied, modified, or distributed | |
5 | //! except according to those terms. | |
6 | ||
7 | #[macro_use] extern crate itertools as it; | |
8 | extern crate permutohedron; | |
9 | ||
10 | use it::Itertools; | |
11 | use it::interleave; | |
12 | use it::multizip; | |
13 | use it::multipeek; | |
14 | use it::FoldWhile; | |
15 | use it::free::rciter; | |
16 | use it::free::put_back; | |
17 | use it::free::put_back_n; | |
18 | use it::cloned; | |
19 | ||
20 | #[test] | |
21 | fn product2() { | |
22 | let s = "αβ"; | |
23 | ||
24 | let mut prod = iproduct!(s.chars(), 0..2); | |
25 | assert!(prod.next() == Some(('α', 0))); | |
26 | assert!(prod.next() == Some(('α', 1))); | |
27 | assert!(prod.next() == Some(('β', 0))); | |
28 | assert!(prod.next() == Some(('β', 1))); | |
29 | assert!(prod.next() == None); | |
30 | } | |
31 | ||
32 | #[test] | |
33 | fn product3() { | |
34 | let prod = iproduct!(0..3, 0..2, 0..2); | |
35 | assert_eq!(prod.size_hint(), (12, Some(12))); | |
36 | let v = prod.collect_vec(); | |
37 | for i in 0..3 { | |
38 | for j in 0..2 { | |
39 | for k in 0..2 { | |
40 | assert!((i, j, k) == v[(i * 2 * 2 + j * 2 + k) as usize]); | |
41 | } | |
42 | } | |
43 | } | |
44 | for (_, _, _, _) in iproduct!(0..3, 0..2, 0..2, 0..3) { | |
45 | /* test compiles */ | |
46 | } | |
47 | } | |
48 | ||
49 | #[test] | |
50 | fn product_temporary() { | |
51 | for (_x, _y, _z) in iproduct!( | |
52 | [0, 1, 2].iter().cloned(), | |
53 | [0, 1, 2].iter().cloned(), | |
54 | [0, 1, 2].iter().cloned()) | |
55 | { | |
56 | // ok | |
57 | } | |
58 | } | |
59 | ||
60 | ||
61 | #[test] | |
62 | fn izip_macro() { | |
63 | let mut zip = izip!(0..3, 0..2, 0..2i8); | |
64 | for i in 0..2 { | |
65 | assert!((i as usize, i, i as i8) == zip.next().unwrap()); | |
66 | } | |
67 | assert!(zip.next().is_none()); | |
68 | ||
69 | let xs: [isize; 0] = []; | |
70 | let mut zip = izip!(0..3, 0..2, 0..2i8, &xs); | |
71 | assert!(zip.next().is_none()); | |
72 | } | |
73 | ||
74 | #[test] | |
75 | fn izip3() { | |
76 | let mut zip = multizip((0..3, 0..2, 0..2i8)); | |
77 | for i in 0..2 { | |
78 | assert!((i as usize, i, i as i8) == zip.next().unwrap()); | |
79 | } | |
80 | assert!(zip.next().is_none()); | |
81 | ||
82 | let xs: [isize; 0] = []; | |
83 | let mut zip = multizip((0..3, 0..2, 0..2i8, xs.iter())); | |
84 | assert!(zip.next().is_none()); | |
85 | ||
86 | for (_, _, _, _, _) in multizip((0..3, 0..2, xs.iter(), &xs, xs.to_vec())) { | |
87 | /* test compiles */ | |
88 | } | |
89 | } | |
90 | ||
91 | #[test] | |
92 | fn write_to() { | |
93 | let xs = [7, 9, 8]; | |
94 | let mut ys = [0; 5]; | |
95 | let cnt = ys.iter_mut().set_from(xs.iter().map(|x| *x)); | |
96 | assert!(cnt == xs.len()); | |
97 | assert!(ys == [7, 9, 8, 0, 0]); | |
98 | ||
99 | let cnt = ys.iter_mut().set_from(0..10); | |
100 | assert!(cnt == ys.len()); | |
101 | assert!(ys == [0, 1, 2, 3, 4]); | |
102 | } | |
103 | ||
104 | #[test] | |
105 | fn test_interleave() { | |
106 | let xs: [u8; 0] = []; | |
107 | let ys = [7u8, 9, 8, 10]; | |
108 | let zs = [2u8, 77]; | |
109 | let it = interleave(xs.iter(), ys.iter()); | |
110 | it::assert_equal(it, ys.iter()); | |
111 | ||
112 | let rs = [7u8, 2, 9, 77, 8, 10]; | |
113 | let it = interleave(ys.iter(), zs.iter()); | |
114 | it::assert_equal(it, rs.iter()); | |
115 | } | |
116 | ||
117 | #[test] | |
118 | fn interleave_shortest() { | |
119 | let v0: Vec<i32> = vec![0, 2, 4]; | |
120 | let v1: Vec<i32> = vec![1, 3, 5, 7]; | |
121 | let it = v0.into_iter().interleave_shortest(v1.into_iter()); | |
122 | assert_eq!(it.size_hint(), (6, Some(6))); | |
123 | assert_eq!(it.collect_vec(), vec![0, 1, 2, 3, 4, 5]); | |
124 | ||
125 | let v0: Vec<i32> = vec![0, 2, 4, 6, 8]; | |
126 | let v1: Vec<i32> = vec![1, 3, 5]; | |
127 | let it = v0.into_iter().interleave_shortest(v1.into_iter()); | |
128 | assert_eq!(it.size_hint(), (7, Some(7))); | |
129 | assert_eq!(it.collect_vec(), vec![0, 1, 2, 3, 4, 5, 6]); | |
130 | ||
131 | let i0 = ::std::iter::repeat(0); | |
132 | let v1: Vec<_> = vec![1, 3, 5]; | |
133 | let it = i0.interleave_shortest(v1.into_iter()); | |
134 | assert_eq!(it.size_hint(), (7, Some(7))); | |
135 | ||
136 | let v0: Vec<_> = vec![0, 2, 4]; | |
137 | let i1 = ::std::iter::repeat(1); | |
138 | let it = v0.into_iter().interleave_shortest(i1); | |
139 | assert_eq!(it.size_hint(), (6, Some(6))); | |
140 | } | |
141 | ||
142 | #[test] | |
143 | fn foreach() { | |
144 | let xs = [1i32, 2, 3]; | |
145 | let mut sum = 0; | |
146 | xs.iter().foreach(|elt| sum += *elt); | |
147 | assert!(sum == 6); | |
148 | } | |
149 | ||
150 | #[test] | |
151 | fn dropping() { | |
152 | let xs = [1, 2, 3]; | |
153 | let mut it = xs.iter().dropping(2); | |
154 | assert_eq!(it.next(), Some(&3)); | |
155 | assert!(it.next().is_none()); | |
156 | let mut it = xs.iter().dropping(5); | |
157 | assert!(it.next().is_none()); | |
158 | } | |
159 | ||
160 | #[test] | |
161 | fn intersperse() { | |
162 | let xs = ["a", "", "b", "c"]; | |
163 | let v: Vec<&str> = xs.iter().map(|x| x.clone()).intersperse(", ").collect(); | |
164 | let text: String = v.concat(); | |
165 | assert_eq!(text, "a, , b, c".to_string()); | |
166 | ||
167 | let ys = [0, 1, 2, 3]; | |
168 | let mut it = ys[..0].iter().map(|x| *x).intersperse(1); | |
169 | assert!(it.next() == None); | |
170 | } | |
171 | ||
172 | #[test] | |
173 | fn dedup() { | |
174 | let xs = [0, 1, 1, 1, 2, 1, 3, 3]; | |
175 | let ys = [0, 1, 2, 1, 3]; | |
176 | it::assert_equal(ys.iter(), xs.iter().dedup()); | |
177 | let xs = [0, 0, 0, 0, 0]; | |
178 | let ys = [0]; | |
179 | it::assert_equal(ys.iter(), xs.iter().dedup()); | |
180 | ||
181 | let xs = [0, 1, 1, 1, 2, 1, 3, 3]; | |
182 | let ys = [0, 1, 2, 1, 3]; | |
183 | let mut xs_d = Vec::new(); | |
184 | xs.iter().dedup().fold((), |(), &elt| xs_d.push(elt)); | |
185 | assert_eq!(&xs_d, &ys); | |
186 | } | |
187 | ||
188 | #[test] | |
189 | fn all_equal() { | |
190 | assert!(!"AABBCCC".chars().all_equal()); | |
191 | assert!("AAAAAAA".chars().all_equal()); | |
192 | for (_key, mut sub) in &"AABBCCC".chars().group_by(|&x| x) { | |
193 | assert!(sub.all_equal()); | |
194 | } | |
195 | } | |
196 | ||
197 | #[test] | |
198 | fn unique_by() { | |
199 | let xs = ["aaa", "bbbbb", "aa", "ccc", "bbbb", "aaaaa", "cccc"]; | |
200 | let ys = ["aaa", "bbbbb", "ccc"]; | |
201 | it::assert_equal(ys.iter(), xs.iter().unique_by(|x| x[..2].to_string())); | |
202 | } | |
203 | ||
204 | #[test] | |
205 | fn unique() { | |
206 | let xs = [0, 1, 2, 3, 2, 1, 3]; | |
207 | let ys = [0, 1, 2, 3]; | |
208 | it::assert_equal(ys.iter(), xs.iter().unique()); | |
209 | let xs = [0, 1]; | |
210 | let ys = [0, 1]; | |
211 | it::assert_equal(ys.iter(), xs.iter().unique()); | |
212 | } | |
213 | ||
214 | #[test] | |
215 | fn batching() { | |
216 | let xs = [0, 1, 2, 1, 3]; | |
217 | let ys = [(0, 1), (2, 1)]; | |
218 | ||
219 | // An iterator that gathers elements up in pairs | |
220 | let pit = xs.iter().cloned().batching(|it| { | |
221 | match it.next() { | |
222 | None => None, | |
223 | Some(x) => match it.next() { | |
224 | None => None, | |
225 | Some(y) => Some((x, y)), | |
226 | } | |
227 | } | |
228 | }); | |
229 | it::assert_equal(pit, ys.iter().cloned()); | |
230 | } | |
231 | ||
232 | #[test] | |
233 | fn test_put_back() { | |
234 | let xs = [0, 1, 1, 1, 2, 1, 3, 3]; | |
235 | let mut pb = put_back(xs.iter().cloned()); | |
236 | pb.next(); | |
237 | pb.put_back(1); | |
238 | pb.put_back(0); | |
239 | it::assert_equal(pb, xs.iter().cloned()); | |
240 | } | |
241 | ||
242 | #[test] | |
243 | fn test_put_back_n() { | |
244 | let xs = [0, 1, 1, 1, 2, 1, 3, 3]; | |
245 | let mut pb = put_back_n(xs.iter().cloned()); | |
246 | pb.next(); | |
247 | pb.next(); | |
248 | pb.put_back(1); | |
249 | pb.put_back(0); | |
250 | it::assert_equal(pb, xs.iter().cloned()); | |
251 | } | |
252 | ||
253 | #[test] | |
254 | fn tee() { | |
255 | let xs = [0, 1, 2, 3]; | |
256 | let (mut t1, mut t2) = xs.iter().cloned().tee(); | |
257 | assert_eq!(t1.next(), Some(0)); | |
258 | assert_eq!(t2.next(), Some(0)); | |
259 | assert_eq!(t1.next(), Some(1)); | |
260 | assert_eq!(t1.next(), Some(2)); | |
261 | assert_eq!(t1.next(), Some(3)); | |
262 | assert_eq!(t1.next(), None); | |
263 | assert_eq!(t2.next(), Some(1)); | |
264 | assert_eq!(t2.next(), Some(2)); | |
265 | assert_eq!(t1.next(), None); | |
266 | assert_eq!(t2.next(), Some(3)); | |
267 | assert_eq!(t2.next(), None); | |
268 | assert_eq!(t1.next(), None); | |
269 | assert_eq!(t2.next(), None); | |
270 | ||
271 | let (t1, t2) = xs.iter().cloned().tee(); | |
272 | it::assert_equal(t1, xs.iter().cloned()); | |
273 | it::assert_equal(t2, xs.iter().cloned()); | |
274 | ||
275 | let (t1, t2) = xs.iter().cloned().tee(); | |
276 | it::assert_equal(t1.zip(t2), xs.iter().cloned().zip(xs.iter().cloned())); | |
277 | } | |
278 | ||
279 | ||
280 | #[test] | |
281 | fn test_rciter() { | |
282 | let xs = [0, 1, 1, 1, 2, 1, 3, 5, 6]; | |
283 | ||
284 | let mut r1 = rciter(xs.iter().cloned()); | |
285 | let mut r2 = r1.clone(); | |
286 | assert_eq!(r1.next(), Some(0)); | |
287 | assert_eq!(r2.next(), Some(1)); | |
288 | let mut z = r1.zip(r2); | |
289 | assert_eq!(z.next(), Some((1, 1))); | |
290 | assert_eq!(z.next(), Some((2, 1))); | |
291 | assert_eq!(z.next(), Some((3, 5))); | |
292 | assert_eq!(z.next(), None); | |
293 | ||
294 | // test intoiterator | |
295 | let r1 = rciter(0..5); | |
296 | let mut z = izip!(&r1, r1); | |
297 | assert_eq!(z.next(), Some((0, 1))); | |
298 | } | |
299 | ||
300 | #[test] | |
301 | fn step() { | |
302 | it::assert_equal((0..10).step(1), (0..10)); | |
303 | it::assert_equal((0..10).step(2), (0..10).filter(|x: &i32| *x % 2 == 0)); | |
304 | it::assert_equal((0..10).step(10), 0..1); | |
305 | } | |
306 | ||
307 | #[test] | |
308 | fn trait_pointers() { | |
309 | struct ByRef<'r, I: ?Sized>(&'r mut I) where I: 'r; | |
310 | ||
311 | impl<'r, X, I: ?Sized> Iterator for ByRef<'r, I> where | |
312 | I: 'r + Iterator<Item=X> | |
313 | { | |
314 | type Item = X; | |
315 | fn next(&mut self) -> Option<X> | |
316 | { | |
317 | self.0.next() | |
318 | } | |
319 | } | |
320 | ||
321 | let mut it = Box::new(0..10) as Box<Iterator<Item=i32>>; | |
322 | assert_eq!(it.next(), Some(0)); | |
323 | ||
324 | { | |
325 | /* make sure foreach works on non-Sized */ | |
326 | let jt: &mut Iterator<Item = i32> = &mut *it; | |
327 | assert_eq!(jt.next(), Some(1)); | |
328 | ||
329 | { | |
330 | let mut r = ByRef(jt); | |
331 | assert_eq!(r.next(), Some(2)); | |
332 | } | |
333 | ||
334 | assert_eq!(jt.find_position(|x| *x == 4), Some((1, 4))); | |
335 | jt.foreach(|_| ()); | |
336 | } | |
337 | } | |
338 | ||
339 | #[test] | |
340 | fn merge() { | |
341 | it::assert_equal((0..10).step(2).merge((1..10).step(2)), (0..10)); | |
342 | } | |
343 | ||
344 | #[test] | |
345 | fn merge_by() { | |
346 | let odd : Vec<(u32, &str)> = vec![(1, "hello"), (3, "world"), (5, "!")]; | |
347 | let even = vec![(2, "foo"), (4, "bar"), (6, "baz")]; | |
348 | let expected = vec![(1, "hello"), (2, "foo"), (3, "world"), (4, "bar"), (5, "!"), (6, "baz")]; | |
349 | let results = odd.iter().merge_by(even.iter(), |a, b| a.0 <= b.0); | |
350 | it::assert_equal(results, expected.iter()); | |
351 | } | |
352 | ||
353 | #[test] | |
354 | fn merge_by_btree() { | |
355 | use std::collections::BTreeMap; | |
356 | let mut bt1 = BTreeMap::new(); | |
357 | bt1.insert("hello", 1); | |
358 | bt1.insert("world", 3); | |
359 | let mut bt2 = BTreeMap::new(); | |
360 | bt2.insert("foo", 2); | |
361 | bt2.insert("bar", 4); | |
362 | let results = bt1.into_iter().merge_by(bt2.into_iter(), |a, b| a.0 <= b.0 ); | |
363 | let expected = vec![("bar", 4), ("foo", 2), ("hello", 1), ("world", 3)]; | |
364 | it::assert_equal(results, expected.into_iter()); | |
365 | } | |
366 | ||
367 | #[test] | |
368 | fn kmerge() { | |
369 | let its = (0..4).map(|s| (s..10).step(4)); | |
370 | ||
371 | it::assert_equal(its.kmerge(), (0..10)); | |
372 | } | |
373 | ||
374 | #[test] | |
375 | fn kmerge_2() { | |
376 | let its = vec![3, 2, 1, 0].into_iter().map(|s| (s..10).step(4)); | |
377 | ||
378 | it::assert_equal(its.kmerge(), (0..10)); | |
379 | } | |
380 | ||
381 | #[test] | |
382 | fn kmerge_empty() { | |
383 | let its = (0..4).map(|_| (0..0)); | |
384 | assert_eq!(its.kmerge().next(), None); | |
385 | } | |
386 | ||
387 | #[test] | |
388 | fn kmerge_size_hint() { | |
389 | let its = (0..5).map(|_| (0..10)); | |
390 | assert_eq!(its.kmerge().size_hint(), (50, Some(50))); | |
391 | } | |
392 | ||
393 | #[test] | |
394 | fn kmerge_empty_size_hint() { | |
395 | let its = (0..5).map(|_| (0..0)); | |
396 | assert_eq!(its.kmerge().size_hint(), (0, Some(0))); | |
397 | } | |
398 | ||
399 | #[test] | |
400 | fn join() { | |
401 | let many = [1, 2, 3]; | |
402 | let one = [1]; | |
403 | let none: Vec<i32> = vec![]; | |
404 | ||
405 | assert_eq!(many.iter().join(", "), "1, 2, 3"); | |
406 | assert_eq!( one.iter().join(", "), "1"); | |
407 | assert_eq!(none.iter().join(", "), ""); | |
408 | } | |
409 | ||
410 | #[test] | |
411 | fn sorted_by() { | |
412 | let sc = [3, 4, 1, 2].iter().cloned().sorted_by(|&a, &b| { | |
413 | a.cmp(&b) | |
414 | }); | |
415 | assert_eq!(sc, vec![1, 2, 3, 4]); | |
416 | ||
417 | let v = (0..5).sorted_by(|&a, &b| a.cmp(&b).reverse()); | |
418 | assert_eq!(v, vec![4, 3, 2, 1, 0]); | |
419 | } | |
420 | ||
421 | #[test] | |
422 | fn test_multipeek() { | |
423 | let nums = vec![1u8,2,3,4,5]; | |
424 | ||
425 | let mp = multipeek(nums.iter().map(|&x| x)); | |
426 | assert_eq!(nums, mp.collect::<Vec<_>>()); | |
427 | ||
428 | let mut mp = multipeek(nums.iter().map(|&x| x)); | |
429 | assert_eq!(mp.peek(), Some(&1)); | |
430 | assert_eq!(mp.next(), Some(1)); | |
431 | assert_eq!(mp.peek(), Some(&2)); | |
432 | assert_eq!(mp.peek(), Some(&3)); | |
433 | assert_eq!(mp.next(), Some(2)); | |
434 | assert_eq!(mp.peek(), Some(&3)); | |
435 | assert_eq!(mp.peek(), Some(&4)); | |
436 | assert_eq!(mp.peek(), Some(&5)); | |
437 | assert_eq!(mp.peek(), None); | |
438 | assert_eq!(mp.next(), Some(3)); | |
439 | assert_eq!(mp.next(), Some(4)); | |
440 | assert_eq!(mp.next(), Some(5)); | |
441 | assert_eq!(mp.next(), None); | |
442 | assert_eq!(mp.peek(), None); | |
443 | ||
444 | } | |
445 | ||
446 | #[test] | |
447 | fn test_multipeek_reset() { | |
448 | let data = [1, 2, 3, 4]; | |
449 | ||
450 | let mut mp = multipeek(cloned(&data)); | |
451 | assert_eq!(mp.peek(), Some(&1)); | |
452 | assert_eq!(mp.next(), Some(1)); | |
453 | assert_eq!(mp.peek(), Some(&2)); | |
454 | assert_eq!(mp.peek(), Some(&3)); | |
455 | mp.reset_peek(); | |
456 | assert_eq!(mp.peek(), Some(&2)); | |
457 | assert_eq!(mp.next(), Some(2)); | |
458 | } | |
459 | ||
460 | #[test] | |
461 | fn repeatn() { | |
462 | let s = "α"; | |
463 | let mut it = it::repeat_n(s, 3); | |
464 | assert_eq!(it.len(), 3); | |
465 | assert_eq!(it.next(), Some(s)); | |
466 | assert_eq!(it.next(), Some(s)); | |
467 | assert_eq!(it.next(), Some(s)); | |
468 | assert_eq!(it.next(), None); | |
469 | assert_eq!(it.next(), None); | |
470 | } | |
471 | ||
472 | #[test] | |
473 | fn count_clones() { | |
474 | // Check that RepeatN only clones N - 1 times. | |
475 | ||
476 | use std::cell::Cell; | |
477 | #[derive(PartialEq, Debug)] | |
478 | struct Foo { | |
479 | n: Cell<usize> | |
480 | } | |
481 | ||
482 | impl Clone for Foo | |
483 | { | |
484 | fn clone(&self) -> Self | |
485 | { | |
486 | let n = self.n.get(); | |
487 | self.n.set(n + 1); | |
488 | Foo { n: Cell::new(n + 1) } | |
489 | } | |
490 | } | |
491 | ||
492 | ||
493 | for n in 0..10 { | |
494 | let f = Foo{n: Cell::new(0)}; | |
495 | let it = it::repeat_n(f, n); | |
496 | // drain it | |
497 | let last = it.last(); | |
498 | if n == 0 { | |
499 | assert_eq!(last, None); | |
500 | } else { | |
501 | assert_eq!(last, Some(Foo{n: Cell::new(n - 1)})); | |
502 | } | |
503 | } | |
504 | } | |
505 | ||
506 | #[test] | |
507 | fn part() { | |
508 | let mut data = [7, 1, 1, 9, 1, 1, 3]; | |
509 | let i = it::partition(&mut data, |elt| *elt >= 3); | |
510 | assert_eq!(i, 3); | |
511 | assert_eq!(data, [7, 3, 9, 1, 1, 1, 1]); | |
512 | ||
513 | let i = it::partition(&mut data, |elt| *elt == 1); | |
514 | assert_eq!(i, 4); | |
515 | assert_eq!(data, [1, 1, 1, 1, 9, 3, 7]); | |
516 | ||
517 | let mut data = [1, 2, 3, 4, 5, 6, 7, 8, 9]; | |
518 | let i = it::partition(&mut data, |elt| *elt % 3 == 0); | |
519 | assert_eq!(i, 3); | |
520 | assert_eq!(data, [9, 6, 3, 4, 5, 2, 7, 8, 1]); | |
521 | } | |
522 | ||
523 | #[test] | |
524 | fn pad_using() { | |
525 | it::assert_equal((0..0).pad_using(1, |_| 1), (1..2)); | |
526 | ||
527 | let v: Vec<usize> = vec![0, 1, 2]; | |
528 | let r = v.into_iter().pad_using(5, |n| n); | |
529 | it::assert_equal(r, vec![0, 1, 2, 3, 4]); | |
530 | ||
531 | let v: Vec<usize> = vec![0, 1, 2]; | |
532 | let r = v.into_iter().pad_using(1, |_| panic!()); | |
533 | it::assert_equal(r, vec![0, 1, 2]); | |
534 | } | |
535 | ||
536 | #[test] | |
537 | fn while_some() { | |
538 | let ns = (1..10).map(|x| if x % 5 != 0 { Some(x) } else { None }) | |
539 | .while_some(); | |
540 | it::assert_equal(ns, vec![1, 2, 3, 4]); | |
541 | } | |
542 | ||
543 | #[test] | |
544 | fn group_by() { | |
545 | for (ch1, sub) in &"AABBCCC".chars().group_by(|&x| x) { | |
546 | for ch2 in sub { | |
547 | assert_eq!(ch1, ch2); | |
548 | } | |
549 | } | |
550 | ||
551 | for (ch1, sub) in &"AAABBBCCCCDDDD".chars().group_by(|&x| x) { | |
552 | for ch2 in sub { | |
553 | assert_eq!(ch1, ch2); | |
554 | if ch1 == 'C' { | |
555 | break; | |
556 | } | |
557 | } | |
558 | } | |
559 | ||
560 | let toupper = |ch: &char| ch.to_uppercase().nth(0).unwrap(); | |
561 | ||
562 | // try all possible orderings | |
563 | for indices in permutohedron::Heap::new(&mut [0, 1, 2, 3]) { | |
564 | let groups = "AaaBbbccCcDDDD".chars().group_by(&toupper); | |
565 | let mut subs = groups.into_iter().collect_vec(); | |
566 | ||
567 | for &idx in &indices[..] { | |
568 | let (key, text) = match idx { | |
569 | 0 => ('A', "Aaa".chars()), | |
570 | 1 => ('B', "Bbb".chars()), | |
571 | 2 => ('C', "ccCc".chars()), | |
572 | 3 => ('D', "DDDD".chars()), | |
573 | _ => unreachable!(), | |
574 | }; | |
575 | assert_eq!(key, subs[idx].0); | |
576 | it::assert_equal(&mut subs[idx].1, text); | |
577 | } | |
578 | } | |
579 | ||
580 | let groups = "AAABBBCCCCDDDD".chars().group_by(|&x| x); | |
581 | let mut subs = groups.into_iter().map(|(_, g)| g).collect_vec(); | |
582 | ||
583 | let sd = subs.pop().unwrap(); | |
584 | let sc = subs.pop().unwrap(); | |
585 | let sb = subs.pop().unwrap(); | |
586 | let sa = subs.pop().unwrap(); | |
587 | for (a, b, c, d) in multizip((sa, sb, sc, sd)) { | |
588 | assert_eq!(a, 'A'); | |
589 | assert_eq!(b, 'B'); | |
590 | assert_eq!(c, 'C'); | |
591 | assert_eq!(d, 'D'); | |
592 | } | |
593 | ||
594 | // check that the key closure is called exactly n times | |
595 | { | |
596 | let mut ntimes = 0; | |
597 | let text = "AABCCC"; | |
598 | for (_, sub) in &text.chars().group_by(|&x| { ntimes += 1; x}) { | |
599 | for _ in sub { | |
600 | } | |
601 | } | |
602 | assert_eq!(ntimes, text.len()); | |
603 | } | |
604 | ||
605 | { | |
606 | let mut ntimes = 0; | |
607 | let text = "AABCCC"; | |
608 | for _ in &text.chars().group_by(|&x| { ntimes += 1; x}) { | |
609 | } | |
610 | assert_eq!(ntimes, text.len()); | |
611 | } | |
612 | ||
613 | { | |
614 | let text = "ABCCCDEEFGHIJJKK"; | |
615 | let gr = text.chars().group_by(|&x| x); | |
616 | it::assert_equal(gr.into_iter().flat_map(|(_, sub)| sub), text.chars()); | |
617 | } | |
618 | } | |
619 | ||
620 | #[test] | |
621 | fn group_by_lazy_2() { | |
622 | let data = vec![0, 1]; | |
623 | let groups = data.iter().group_by(|k| *k); | |
624 | let gs = groups.into_iter().collect_vec(); | |
625 | it::assert_equal(data.iter(), gs.into_iter().flat_map(|(_k, g)| g)); | |
626 | ||
627 | let data = vec![0, 1, 1, 0, 0]; | |
628 | let groups = data.iter().group_by(|k| *k); | |
629 | let mut gs = groups.into_iter().collect_vec(); | |
630 | gs[1..].reverse(); | |
631 | it::assert_equal(&[0, 0, 0, 1, 1], gs.into_iter().flat_map(|(_, g)| g)); | |
632 | ||
633 | let grouper = data.iter().group_by(|k| *k); | |
634 | let mut groups = Vec::new(); | |
635 | for (k, group) in &grouper { | |
636 | if *k == 1 { | |
637 | groups.push(group); | |
638 | } | |
639 | } | |
640 | it::assert_equal(&mut groups[0], &[1, 1]); | |
641 | ||
642 | let data = vec![0, 0, 0, 1, 1, 0, 0, 2, 2, 3, 3]; | |
643 | let grouper = data.iter().group_by(|k| *k); | |
644 | let mut groups = Vec::new(); | |
645 | for (i, (_, group)) in grouper.into_iter().enumerate() { | |
646 | if i < 2 { | |
647 | groups.push(group); | |
648 | } else if i < 4 { | |
649 | for _ in group { | |
650 | } | |
651 | } else { | |
652 | groups.push(group); | |
653 | } | |
654 | } | |
655 | it::assert_equal(&mut groups[0], &[0, 0, 0]); | |
656 | it::assert_equal(&mut groups[1], &[1, 1]); | |
657 | it::assert_equal(&mut groups[2], &[3, 3]); | |
658 | ||
659 | // use groups as chunks | |
660 | let data = vec![0, 0, 0, 1, 1, 0, 0, 2, 2, 3, 3]; | |
661 | let mut i = 0; | |
662 | let grouper = data.iter().group_by(move |_| { let k = i / 3; i += 1; k }); | |
663 | for (i, group) in &grouper { | |
664 | match i { | |
665 | 0 => it::assert_equal(group, &[0, 0, 0]), | |
666 | 1 => it::assert_equal(group, &[1, 1, 0]), | |
667 | 2 => it::assert_equal(group, &[0, 2, 2]), | |
668 | 3 => it::assert_equal(group, &[3, 3]), | |
669 | _ => unreachable!(), | |
670 | } | |
671 | } | |
672 | } | |
673 | ||
674 | #[test] | |
675 | fn group_by_lazy_3() { | |
676 | // test consuming each group on the lap after it was produced | |
677 | let data = vec![0, 0, 0, 1, 1, 0, 0, 1, 1, 2, 2]; | |
678 | let grouper = data.iter().group_by(|elt| *elt); | |
679 | let mut last = None; | |
680 | for (key, group) in &grouper { | |
681 | if let Some(gr) = last.take() { | |
682 | for elt in gr { | |
683 | assert!(elt != key && i32::abs(elt - key) == 1); | |
684 | } | |
685 | } | |
686 | last = Some(group); | |
687 | } | |
688 | } | |
689 | ||
690 | #[test] | |
691 | fn chunks() { | |
692 | let data = vec![0, 0, 0, 1, 1, 0, 0, 2, 2, 3, 3]; | |
693 | let grouper = data.iter().chunks(3); | |
694 | for (i, chunk) in grouper.into_iter().enumerate() { | |
695 | match i { | |
696 | 0 => it::assert_equal(chunk, &[0, 0, 0]), | |
697 | 1 => it::assert_equal(chunk, &[1, 1, 0]), | |
698 | 2 => it::assert_equal(chunk, &[0, 2, 2]), | |
699 | 3 => it::assert_equal(chunk, &[3, 3]), | |
700 | _ => unreachable!(), | |
701 | } | |
702 | } | |
703 | } | |
704 | ||
705 | #[test] | |
706 | fn concat_empty() { | |
707 | let data: Vec<Vec<()>> = Vec::new(); | |
708 | assert_eq!(data.into_iter().concat(), Vec::new()) | |
709 | } | |
710 | ||
711 | #[test] | |
712 | fn concat_non_empty() { | |
713 | let data = vec![vec![1,2,3], vec![4,5,6], vec![7,8,9]]; | |
714 | assert_eq!(data.into_iter().concat(), vec![1,2,3,4,5,6,7,8,9]) | |
715 | } | |
716 | ||
717 | #[test] | |
718 | fn flatten_iter() { | |
719 | let data = vec![vec![1,2,3], vec![4,5,6]]; | |
720 | let flattened = data.into_iter().flatten(); | |
721 | ||
722 | it::assert_equal(flattened, vec![1,2,3,4,5,6]); | |
723 | } | |
724 | ||
725 | #[test] | |
726 | fn flatten_clone() { | |
727 | let data = &[ | |
728 | &[1,2,3], | |
729 | &[4,5,6] | |
730 | ]; | |
731 | let flattened1 = data.into_iter().cloned().flatten(); | |
732 | let flattened2 = flattened1.clone(); | |
733 | ||
734 | it::assert_equal(flattened1, &[1,2,3,4,5,6]); | |
735 | it::assert_equal(flattened2, &[1,2,3,4,5,6]); | |
736 | } | |
737 | ||
738 | #[test] | |
739 | fn flatten_fold() { | |
740 | let xs = [0, 1, 1, 1, 2, 1, 3, 3]; | |
741 | let ch = xs.iter().chunks(3); | |
742 | let mut iter = ch.into_iter().flatten(); | |
743 | iter.next(); | |
744 | let mut xs_d = Vec::new(); | |
745 | iter.fold((), |(), &elt| xs_d.push(elt)); | |
746 | assert_eq!(&xs_d[..], &xs[1..]); | |
747 | } | |
748 | ||
749 | #[test] | |
750 | fn combinations() { | |
751 | assert!((1..3).combinations(5).next().is_none()); | |
752 | ||
753 | let it = (1..3).combinations(2); | |
754 | it::assert_equal(it, vec![ | |
755 | vec![1, 2], | |
756 | ]); | |
757 | ||
758 | let it = (1..5).combinations(2); | |
759 | it::assert_equal(it, vec![ | |
760 | vec![1, 2], | |
761 | vec![1, 3], | |
762 | vec![1, 4], | |
763 | vec![2, 3], | |
764 | vec![2, 4], | |
765 | vec![3, 4], | |
766 | ]); | |
767 | ||
768 | it::assert_equal((0..0).tuple_combinations::<(_, _)>(), <Vec<_>>::new()); | |
769 | it::assert_equal((0..1).tuple_combinations::<(_, _)>(), <Vec<_>>::new()); | |
770 | it::assert_equal((0..2).tuple_combinations::<(_, _)>(), vec![(0, 1)]); | |
771 | ||
772 | it::assert_equal((0..0).combinations(2), <Vec<Vec<_>>>::new()); | |
773 | it::assert_equal((0..1).combinations(1), vec![vec![0]]); | |
774 | it::assert_equal((0..2).combinations(1), vec![vec![0], vec![1]]); | |
775 | it::assert_equal((0..2).combinations(2), vec![vec![0, 1]]); | |
776 | } | |
777 | ||
778 | #[test] | |
779 | fn combinations_of_too_short() { | |
780 | for i in 1..10 { | |
781 | assert!((0..0).combinations(i).next().is_none()); | |
782 | assert!((0..i - 1).combinations(i).next().is_none()); | |
783 | } | |
784 | } | |
785 | ||
786 | ||
787 | #[test] | |
788 | fn combinations_zero() { | |
789 | it::assert_equal((1..3).combinations(0), vec![vec![]]); | |
790 | } | |
791 | ||
792 | #[test] | |
793 | fn diff_mismatch() { | |
794 | let a = vec![1, 2, 3, 4]; | |
795 | let b = vec![1.0, 5.0, 3.0, 4.0]; | |
796 | let b_map = b.into_iter().map(|f| f as i32); | |
797 | let diff = it::diff_with(a.iter(), b_map, |a, b| *a == b); | |
798 | ||
799 | assert!(match diff { | |
800 | Some(it::Diff::FirstMismatch(1, _, from_diff)) => | |
801 | from_diff.collect::<Vec<_>>() == vec![5, 3, 4], | |
802 | _ => false, | |
803 | }); | |
804 | } | |
805 | ||
806 | #[test] | |
807 | fn diff_longer() { | |
808 | let a = vec![1, 2, 3, 4]; | |
809 | let b = vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0]; | |
810 | let b_map = b.into_iter().map(|f| f as i32); | |
811 | let diff = it::diff_with(a.iter(), b_map, |a, b| *a == b); | |
812 | ||
813 | assert!(match diff { | |
814 | Some(it::Diff::Longer(_, remaining)) => | |
815 | remaining.collect::<Vec<_>>() == vec![5, 6], | |
816 | _ => false, | |
817 | }); | |
818 | } | |
819 | ||
820 | #[test] | |
821 | fn diff_shorter() { | |
822 | let a = vec![1, 2, 3, 4]; | |
823 | let b = vec![1.0, 2.0]; | |
824 | let b_map = b.into_iter().map(|f| f as i32); | |
825 | let diff = it::diff_with(a.iter(), b_map, |a, b| *a == b); | |
826 | ||
827 | assert!(match diff { | |
828 | Some(it::Diff::Shorter(len, _)) => len == 2, | |
829 | _ => false, | |
830 | }); | |
831 | } | |
832 | ||
833 | #[test] | |
834 | fn fold_while() { | |
835 | let mut iterations = 0; | |
836 | let vec = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; | |
837 | let sum = vec.into_iter().fold_while(0, |acc, item| { | |
838 | iterations += 1; | |
839 | let new_sum = acc.clone() + item; | |
840 | if new_sum <= 20 { | |
841 | FoldWhile::Continue(new_sum) | |
842 | } else { | |
843 | FoldWhile::Done(acc) | |
844 | } | |
845 | }).into_inner(); | |
846 | assert_eq!(iterations, 6); | |
847 | assert_eq!(sum, 15); | |
848 | } | |
849 | ||
850 | #[test] | |
851 | fn minmax() { | |
852 | use std::cmp::Ordering; | |
853 | use it::MinMaxResult; | |
854 | ||
855 | // A peculiar type: Equality compares both tuple items, but ordering only the | |
856 | // first item. This is so we can check the stability property easily. | |
857 | #[derive(Clone, Debug, PartialEq, Eq)] | |
858 | struct Val(u32, u32); | |
859 | ||
860 | impl PartialOrd<Val> for Val { | |
861 | fn partial_cmp(&self, other: &Val) -> Option<Ordering> { | |
862 | self.0.partial_cmp(&other.0) | |
863 | } | |
864 | } | |
865 | ||
866 | impl Ord for Val { | |
867 | fn cmp(&self, other: &Val) -> Ordering { | |
868 | self.0.cmp(&other.0) | |
869 | } | |
870 | } | |
871 | ||
872 | assert_eq!(None::<Option<u32>>.iter().minmax(), MinMaxResult::NoElements); | |
873 | ||
874 | assert_eq!(Some(1u32).iter().minmax(), MinMaxResult::OneElement(&1)); | |
875 | ||
876 | let data = vec![Val(0, 1), Val(2, 0), Val(0, 2), Val(1, 0), Val(2, 1)]; | |
877 | ||
878 | let minmax = data.iter().minmax(); | |
879 | assert_eq!(minmax, MinMaxResult::MinMax(&Val(0, 1), &Val(2, 1))); | |
880 | ||
881 | let (min, max) = data.iter().minmax_by_key(|v| v.1).into_option().unwrap(); | |
882 | assert_eq!(min, &Val(2, 0)); | |
883 | assert_eq!(max, &Val(0, 2)); | |
884 | ||
885 | let (min, max) = data.iter().minmax_by(|x, y| x.1.cmp(&y.1)).into_option().unwrap(); | |
886 | assert_eq!(min, &Val(2, 0)); | |
887 | assert_eq!(max, &Val(0, 2)); | |
888 | } | |
889 | ||
890 | #[test] | |
891 | fn format() { | |
892 | let data = [0, 1, 2, 3]; | |
893 | let ans1 = "0, 1, 2, 3"; | |
894 | let ans2 = "0--1--2--3"; | |
895 | ||
896 | let t1 = format!("{}", data.iter().format(", ")); | |
897 | assert_eq!(t1, ans1); | |
898 | let t2 = format!("{:?}", data.iter().format("--")); | |
899 | assert_eq!(t2, ans2); | |
900 | ||
901 | let dataf = [1.1, 2.71828, -22.]; | |
902 | let t3 = format!("{:.2e}", dataf.iter().format(", ")); | |
903 | assert_eq!(t3, "1.10e0, 2.72e0, -2.20e1"); | |
904 | } |