1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.google.common.collect;
18
19 import static com.google.common.collect.Iterables.skip;
20 import static com.google.common.collect.Lists.newArrayList;
21 import static com.google.common.collect.Sets.newLinkedHashSet;
22 import static com.google.common.collect.testing.IteratorFeature.MODIFIABLE;
23 import static com.google.common.collect.testing.IteratorFeature.UNMODIFIABLE;
24 import static com.google.common.truth.Truth.assertThat;
25 import static java.util.Arrays.asList;
26 import static java.util.Collections.emptyList;
27
28 import com.google.common.annotations.GwtCompatible;
29 import com.google.common.annotations.GwtIncompatible;
30 import com.google.common.base.Function;
31 import com.google.common.base.Optional;
32 import com.google.common.base.Predicate;
33 import com.google.common.base.Predicates;
34 import com.google.common.collect.testing.IteratorTester;
35 import com.google.common.testing.ClassSanityTester;
36 import com.google.common.testing.NullPointerTester;
37
38 import junit.framework.AssertionFailedError;
39 import junit.framework.TestCase;
40
41 import java.util.ArrayList;
42 import java.util.Arrays;
43 import java.util.Collection;
44 import java.util.Collections;
45 import java.util.ConcurrentModificationException;
46 import java.util.Iterator;
47 import java.util.List;
48 import java.util.NoSuchElementException;
49 import java.util.Queue;
50 import java.util.RandomAccess;
51 import java.util.Set;
52 import java.util.SortedSet;
53 import java.util.TreeSet;
54
55
56
57
58
59
60
61 @GwtCompatible(emulated = true)
62 public class IterablesTest extends TestCase {
63
64 public void testSize0() {
65 Iterable<String> iterable = Collections.emptySet();
66 assertEquals(0, Iterables.size(iterable));
67 }
68
69 public void testSize1Collection() {
70 Iterable<String> iterable = Collections.singleton("a");
71 assertEquals(1, Iterables.size(iterable));
72 }
73
74 public void testSize2NonCollection() {
75 Iterable<Integer> iterable = new Iterable<Integer>() {
76 @Override
77 public Iterator<Integer> iterator() {
78 return asList(0, 1).iterator();
79 }
80 };
81 assertEquals(2, Iterables.size(iterable));
82 }
83
84 @SuppressWarnings("serial")
85 public void testSize_collection_doesntIterate() {
86 List<Integer> nums = asList(1, 2, 3, 4, 5);
87 List<Integer> collection = new ArrayList<Integer>(nums) {
88 @Override public Iterator<Integer> iterator() {
89 throw new AssertionFailedError("Don't iterate me!");
90 }
91 };
92 assertEquals(5, Iterables.size(collection));
93 }
94
95 private static Iterable<String> iterable(String... elements) {
96 final List<String> list = asList(elements);
97 return new Iterable<String>() {
98 @Override
99 public Iterator<String> iterator() {
100 return list.iterator();
101 }
102 };
103 }
104
105 public void test_contains_null_set_yes() {
106 Iterable<String> set = Sets.newHashSet("a", null, "b");
107 assertTrue(Iterables.contains(set, null));
108 }
109
110 public void test_contains_null_set_no() {
111 Iterable<String> set = Sets.newHashSet("a", "b");
112 assertFalse(Iterables.contains(set, null));
113 }
114
115 public void test_contains_null_iterable_yes() {
116 Iterable<String> set = iterable("a", null, "b");
117 assertTrue(Iterables.contains(set, null));
118 }
119
120 public void test_contains_null_iterable_no() {
121 Iterable<String> set = iterable("a", "b");
122 assertFalse(Iterables.contains(set, null));
123 }
124
125 public void test_contains_nonnull_set_yes() {
126 Iterable<String> set = Sets.newHashSet("a", null, "b");
127 assertTrue(Iterables.contains(set, "b"));
128 }
129
130 public void test_contains_nonnull_set_no() {
131 Iterable<String> set = Sets.newHashSet("a", "b");
132 assertFalse(Iterables.contains(set, "c"));
133 }
134
135 public void test_contains_nonnull_iterable_yes() {
136 Iterable<String> set = iterable("a", null, "b");
137 assertTrue(Iterables.contains(set, "b"));
138 }
139
140 public void test_contains_nonnull_iterable_no() {
141 Iterable<String> set = iterable("a", "b");
142 assertFalse(Iterables.contains(set, "c"));
143 }
144
145 public void testGetOnlyElement_noDefault_valid() {
146 Iterable<String> iterable = Collections.singletonList("foo");
147 assertEquals("foo", Iterables.getOnlyElement(iterable));
148 }
149
150 public void testGetOnlyElement_noDefault_empty() {
151 Iterable<String> iterable = Collections.emptyList();
152 try {
153 Iterables.getOnlyElement(iterable);
154 fail();
155 } catch (NoSuchElementException expected) {
156 }
157 }
158
159 public void testGetOnlyElement_noDefault_multiple() {
160 Iterable<String> iterable = asList("foo", "bar");
161 try {
162 Iterables.getOnlyElement(iterable);
163 fail();
164 } catch (IllegalArgumentException expected) {
165 }
166 }
167
168 public void testGetOnlyElement_withDefault_singleton() {
169 Iterable<String> iterable = Collections.singletonList("foo");
170 assertEquals("foo", Iterables.getOnlyElement(iterable, "bar"));
171 }
172
173 public void testGetOnlyElement_withDefault_empty() {
174 Iterable<String> iterable = Collections.emptyList();
175 assertEquals("bar", Iterables.getOnlyElement(iterable, "bar"));
176 }
177
178 public void testGetOnlyElement_withDefault_empty_null() {
179 Iterable<String> iterable = Collections.emptyList();
180 assertNull(Iterables.getOnlyElement(iterable, null));
181 }
182
183 public void testGetOnlyElement_withDefault_multiple() {
184 Iterable<String> iterable = asList("foo", "bar");
185 try {
186 Iterables.getOnlyElement(iterable, "x");
187 fail();
188 } catch (IllegalArgumentException expected) {
189 }
190 }
191
192 @GwtIncompatible("Iterables.toArray(Iterable, Class)")
193 public void testToArrayEmpty() {
194 Iterable<String> iterable = Collections.emptyList();
195 String[] array = Iterables.toArray(iterable, String.class);
196 assertTrue(Arrays.equals(new String[0], array));
197 }
198
199 @GwtIncompatible("Iterables.toArray(Iterable, Class)")
200 public void testToArraySingleton() {
201 Iterable<String> iterable = Collections.singletonList("a");
202 String[] array = Iterables.toArray(iterable, String.class);
203 assertTrue(Arrays.equals(new String[] {"a"}, array));
204 }
205
206 @GwtIncompatible("Iterables.toArray(Iterable, Class)")
207 public void testToArray() {
208 String[] sourceArray = new String[] {"a", "b", "c"};
209 Iterable<String> iterable = asList(sourceArray);
210 String[] newArray = Iterables.toArray(iterable, String.class);
211 assertTrue(Arrays.equals(sourceArray, newArray));
212 }
213
214 public void testAny() {
215 List<String> list = newArrayList();
216 Predicate<String> predicate = Predicates.equalTo("pants");
217
218 assertFalse(Iterables.any(list, predicate));
219 list.add("cool");
220 assertFalse(Iterables.any(list, predicate));
221 list.add("pants");
222 assertTrue(Iterables.any(list, predicate));
223 }
224
225 public void testAll() {
226 List<String> list = newArrayList();
227 Predicate<String> predicate = Predicates.equalTo("cool");
228
229 assertTrue(Iterables.all(list, predicate));
230 list.add("cool");
231 assertTrue(Iterables.all(list, predicate));
232 list.add("pants");
233 assertFalse(Iterables.all(list, predicate));
234 }
235
236 public void testFind() {
237 Iterable<String> list = newArrayList("cool", "pants");
238 assertEquals("cool", Iterables.find(list, Predicates.equalTo("cool")));
239 assertEquals("pants", Iterables.find(list, Predicates.equalTo("pants")));
240 try {
241 Iterables.find(list, Predicates.alwaysFalse());
242 fail();
243 } catch (NoSuchElementException e) {
244 }
245 assertEquals("cool", Iterables.find(list, Predicates.alwaysTrue()));
246 assertCanIterateAgain(list);
247 }
248
249 public void testFind_withDefault() {
250 Iterable<String> list = Lists.newArrayList("cool", "pants");
251 assertEquals("cool",
252 Iterables.find(list, Predicates.equalTo("cool"), "woot"));
253 assertEquals("pants",
254 Iterables.find(list, Predicates.equalTo("pants"), "woot"));
255 assertEquals("woot", Iterables.find(list,
256 Predicates.alwaysFalse(), "woot"));
257 assertNull(Iterables.find(list, Predicates.alwaysFalse(), null));
258 assertEquals("cool",
259 Iterables.find(list, Predicates.alwaysTrue(), "woot"));
260 assertCanIterateAgain(list);
261 }
262
263 public void testTryFind() {
264 Iterable<String> list = newArrayList("cool", "pants");
265 assertEquals(Optional.of("cool"),
266 Iterables.tryFind(list, Predicates.equalTo("cool")));
267 assertEquals(Optional.of("pants"),
268 Iterables.tryFind(list, Predicates.equalTo("pants")));
269 assertEquals(Optional.of("cool"),
270 Iterables.tryFind(list, Predicates.alwaysTrue()));
271 assertEquals(Optional.absent(),
272 Iterables.tryFind(list, Predicates.alwaysFalse()));
273 assertCanIterateAgain(list);
274 }
275
276 private static class TypeA {}
277 private interface TypeB {}
278 private static class HasBoth extends TypeA implements TypeB {}
279
280 @GwtIncompatible("Iterables.filter(Iterable, Class)")
281 public void testFilterByType() throws Exception {
282 HasBoth hasBoth = new HasBoth();
283 Iterable<TypeA> alist = Lists
284 .newArrayList(new TypeA(), new TypeA(), hasBoth, new TypeA());
285 Iterable<TypeB> blist = Iterables.filter(alist, TypeB.class);
286 assertThat(blist).iteratesAs(hasBoth);
287 }
288
289 public void testTransform() {
290 List<String> input = asList("1", "2", "3");
291 Iterable<Integer> result = Iterables.transform(input,
292 new Function<String, Integer>() {
293 @Override
294 public Integer apply(String from) {
295 return Integer.valueOf(from);
296 }
297 });
298
299 List<Integer> actual = newArrayList(result);
300 List<Integer> expected = asList(1, 2, 3);
301 assertEquals(expected, actual);
302 assertCanIterateAgain(result);
303 assertEquals("[1, 2, 3]", result.toString());
304 }
305
306 public void testPoorlyBehavedTransform() {
307 List<String> input = asList("1", null, "3");
308 Iterable<Integer> result = Iterables.transform(input,
309 new Function<String, Integer>() {
310 @Override
311 public Integer apply(String from) {
312 return Integer.valueOf(from);
313 }
314 });
315
316 Iterator<Integer> resultIterator = result.iterator();
317 resultIterator.next();
318
319 try {
320 resultIterator.next();
321 fail("Expected NFE");
322 } catch (NumberFormatException nfe) {
323
324 }
325 }
326
327 public void testNullFriendlyTransform() {
328 List<Integer> input = asList(1, 2, null, 3);
329 Iterable<String> result = Iterables.transform(input,
330 new Function<Integer, String>() {
331 @Override
332 public String apply(Integer from) {
333 return String.valueOf(from);
334 }
335 });
336
337 List<String> actual = newArrayList(result);
338 List<String> expected = asList("1", "2", "null", "3");
339 assertEquals(expected, actual);
340 }
341
342
343 public void testCycle() {
344 Iterable<String> cycle = Iterables.cycle("a", "b");
345
346 int howManyChecked = 0;
347 for (String string : cycle) {
348 String expected = (howManyChecked % 2 == 0) ? "a" : "b";
349 assertEquals(expected, string);
350 if (howManyChecked++ == 5) {
351 break;
352 }
353 }
354
355
356
357 for (String string : cycle) {
358 assertEquals("a", string);
359 break;
360 }
361
362 assertEquals("[a, b] (cycled)", cycle.toString());
363 }
364
365
366 public void testConcatIterable() {
367 List<Integer> list1 = newArrayList(1);
368 List<Integer> list2 = newArrayList(4);
369
370 @SuppressWarnings("unchecked")
371 List<List<Integer>> input = newArrayList(list1, list2);
372
373 Iterable<Integer> result = Iterables.concat(input);
374 assertEquals(asList(1, 4), newArrayList(result));
375
376
377
378 list1.add(2);
379 List<Integer> list3 = newArrayList(3);
380 input.add(1, list3);
381
382 assertEquals(asList(1, 2, 3, 4), newArrayList(result));
383 assertEquals("[1, 2, 3, 4]", result.toString());
384 }
385
386 public void testConcatVarargs() {
387 List<Integer> list1 = newArrayList(1);
388 List<Integer> list2 = newArrayList(4);
389 List<Integer> list3 = newArrayList(7, 8);
390 List<Integer> list4 = newArrayList(9);
391 List<Integer> list5 = newArrayList(10);
392 @SuppressWarnings("unchecked")
393 Iterable<Integer> result =
394 Iterables.concat(list1, list2, list3, list4, list5);
395 assertEquals(asList(1, 4, 7, 8, 9, 10), newArrayList(result));
396 assertEquals("[1, 4, 7, 8, 9, 10]", result.toString());
397 }
398
399 public void testConcatNullPointerException() {
400 List<Integer> list1 = newArrayList(1);
401 List<Integer> list2 = newArrayList(4);
402
403 try {
404 Iterables.concat(list1, null, list2);
405 fail();
406 } catch (NullPointerException expected) {}
407 }
408
409 public void testConcatPeformingFiniteCycle() {
410 Iterable<Integer> iterable = asList(1, 2, 3);
411 int n = 4;
412 Iterable<Integer> repeated
413 = Iterables.concat(Collections.nCopies(n, iterable));
414 assertThat(repeated).iteratesAs(
415 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3);
416 }
417
418 public void testPartition_badSize() {
419 Iterable<Integer> source = Collections.singleton(1);
420 try {
421 Iterables.partition(source, 0);
422 fail();
423 } catch (IllegalArgumentException expected) {
424 }
425 }
426
427 public void testPartition_empty() {
428 Iterable<Integer> source = Collections.emptySet();
429 Iterable<List<Integer>> partitions = Iterables.partition(source, 1);
430 assertTrue(Iterables.isEmpty(partitions));
431 }
432
433 public void testPartition_singleton1() {
434 Iterable<Integer> source = Collections.singleton(1);
435 Iterable<List<Integer>> partitions = Iterables.partition(source, 1);
436 assertEquals(1, Iterables.size(partitions));
437 assertEquals(Collections.singletonList(1), partitions.iterator().next());
438 }
439
440 public void testPartition_view() {
441 List<Integer> list = asList(1, 2);
442 Iterable<List<Integer>> partitions = Iterables.partition(list, 2);
443
444
445 list.set(0, 3);
446
447 Iterator<List<Integer>> iterator = partitions.iterator();
448
449
450 list.set(1, 4);
451
452 List<Integer> first = iterator.next();
453
454
455 list.set(0, 5);
456
457 assertEquals(ImmutableList.of(3, 4), first);
458 }
459
460 @GwtIncompatible("?")
461
462 public void testPartitionRandomAccessInput() {
463 Iterable<Integer> source = asList(1, 2, 3);
464 Iterable<List<Integer>> partitions = Iterables.partition(source, 2);
465 Iterator<List<Integer>> iterator = partitions.iterator();
466 assertTrue(iterator.next() instanceof RandomAccess);
467 assertTrue(iterator.next() instanceof RandomAccess);
468 }
469
470 @GwtIncompatible("?")
471
472 public void testPartitionNonRandomAccessInput() {
473 Iterable<Integer> source = Lists.newLinkedList(asList(1, 2, 3));
474 Iterable<List<Integer>> partitions = Iterables.partition(source, 2);
475 Iterator<List<Integer>> iterator = partitions.iterator();
476
477
478 assertTrue(iterator.next() instanceof RandomAccess);
479 assertTrue(iterator.next() instanceof RandomAccess);
480 }
481
482 public void testPaddedPartition_basic() {
483 List<Integer> list = asList(1, 2, 3, 4, 5);
484 Iterable<List<Integer>> partitions = Iterables.paddedPartition(list, 2);
485 assertEquals(3, Iterables.size(partitions));
486 assertEquals(asList(5, null), Iterables.getLast(partitions));
487 }
488
489 public void testPaddedPartitionRandomAccessInput() {
490 Iterable<Integer> source = asList(1, 2, 3);
491 Iterable<List<Integer>> partitions = Iterables.paddedPartition(source, 2);
492 Iterator<List<Integer>> iterator = partitions.iterator();
493 assertTrue(iterator.next() instanceof RandomAccess);
494 assertTrue(iterator.next() instanceof RandomAccess);
495 }
496
497 public void testPaddedPartitionNonRandomAccessInput() {
498 Iterable<Integer> source = Lists.newLinkedList(asList(1, 2, 3));
499 Iterable<List<Integer>> partitions = Iterables.paddedPartition(source, 2);
500 Iterator<List<Integer>> iterator = partitions.iterator();
501
502
503 assertTrue(iterator.next() instanceof RandomAccess);
504 assertTrue(iterator.next() instanceof RandomAccess);
505 }
506
507
508 public void testAddAllToList() {
509 List<String> alreadyThere = newArrayList("already", "there");
510 List<String> freshlyAdded = newArrayList("freshly", "added");
511
512 boolean changed = Iterables.addAll(alreadyThere, freshlyAdded);
513 assertThat(alreadyThere).has().exactly(
514 "already", "there", "freshly", "added").inOrder();
515 assertTrue(changed);
516 }
517
518 private static void assertCanIterateAgain(Iterable<?> iterable) {
519 for (@SuppressWarnings("unused") Object obj : iterable) {
520 }
521 }
522
523 @GwtIncompatible("NullPointerTester")
524 public void testNullPointerExceptions() {
525 NullPointerTester tester = new NullPointerTester();
526 tester.testAllPublicStaticMethods(Iterables.class);
527 }
528
529
530 public void testElementsEqual() throws Exception {
531 Iterable<?> a;
532 Iterable<?> b;
533
534
535 a = asList(4, 8, 15, 16, 23, 42);
536 b = asList(4, 8, 15, 16, 23, 42);
537 assertTrue(Iterables.elementsEqual(a, b));
538
539
540 a = asList(4, 8, 15, 12, 23, 42);
541 b = asList(4, 8, 15, 16, 23, 42);
542 assertFalse(Iterables.elementsEqual(a, b));
543
544
545 a = asList(4, 8, 15, null, 23, 42);
546 b = asList(4, 8, 15, 16, 23, 42);
547 assertFalse(Iterables.elementsEqual(a, b));
548 assertFalse(Iterables.elementsEqual(b, a));
549
550
551 a = asList(4, 8, 15, 16, 23);
552 b = asList(4, 8, 15, 16, 23, 42);
553 assertFalse(Iterables.elementsEqual(a, b));
554 assertFalse(Iterables.elementsEqual(b, a));
555 }
556
557 public void testToString() {
558 List<String> list = Collections.emptyList();
559 assertEquals("[]", Iterables.toString(list));
560
561 list = newArrayList("yam", "bam", "jam", "ham");
562 assertEquals("[yam, bam, jam, ham]", Iterables.toString(list));
563 }
564
565 public void testLimit() {
566 Iterable<String> iterable = newArrayList("foo", "bar", "baz");
567 Iterable<String> limited = Iterables.limit(iterable, 2);
568
569 List<String> expected = ImmutableList.of("foo", "bar");
570 List<String> actual = newArrayList(limited);
571 assertEquals(expected, actual);
572 assertCanIterateAgain(limited);
573 assertEquals("[foo, bar]", limited.toString());
574 }
575
576 public void testLimit_illegalArgument() {
577 List<String> list = newArrayList("a", "b", "c");
578 try {
579 Iterables.limit(list, -1);
580 fail();
581 } catch (IllegalArgumentException expected) {}
582 }
583
584 public void testIsEmpty() {
585 Iterable<String> emptyList = Collections.emptyList();
586 assertTrue(Iterables.isEmpty(emptyList));
587
588 Iterable<String> singletonList = Collections.singletonList("foo");
589 assertFalse(Iterables.isEmpty(singletonList));
590 }
591
592 public void testSkip_simple() {
593 Collection<String> set = ImmutableSet.of("a", "b", "c", "d", "e");
594 assertEquals(newArrayList("c", "d", "e"), newArrayList(skip(set, 2)));
595 assertEquals("[c, d, e]", skip(set, 2).toString());
596 }
597
598 public void testSkip_simpleList() {
599 Collection<String> list = newArrayList("a", "b", "c", "d", "e");
600 assertEquals(newArrayList("c", "d", "e"), newArrayList(skip(list, 2)));
601 assertEquals("[c, d, e]", skip(list, 2).toString());
602 }
603
604 public void testSkip_pastEnd() {
605 Collection<String> set = ImmutableSet.of("a", "b");
606 assertEquals(emptyList(), newArrayList(skip(set, 20)));
607 }
608
609 public void testSkip_pastEndList() {
610 Collection<String> list = newArrayList("a", "b");
611 assertEquals(emptyList(), newArrayList(skip(list, 20)));
612 }
613
614 public void testSkip_skipNone() {
615 Collection<String> set = ImmutableSet.of("a", "b");
616 assertEquals(newArrayList("a", "b"), newArrayList(skip(set, 0)));
617 }
618
619 public void testSkip_skipNoneList() {
620 Collection<String> list = newArrayList("a", "b");
621 assertEquals(newArrayList("a", "b"), newArrayList(skip(list, 0)));
622 }
623
624 public void testSkip_removal() {
625 Collection<String> set = Sets.newHashSet("a", "b");
626 Iterator<String> iterator = skip(set, 2).iterator();
627 try {
628 iterator.next();
629 } catch (NoSuchElementException suppressed) {
630
631 }
632 try {
633 iterator.remove();
634 fail("Expected IllegalStateException");
635 } catch (IllegalStateException expected) {}
636 }
637
638 public void testSkip_allOfMutableList_modifiable() {
639 List<String> list = newArrayList("a", "b");
640 Iterator<String> iterator = skip(list, 2).iterator();
641 try {
642 iterator.remove();
643 fail("Expected IllegalStateException");
644 } catch (IllegalStateException expected) {}
645 }
646
647 public void testSkip_allOfImmutableList_modifiable() {
648 List<String> list = ImmutableList.of("a", "b");
649 Iterator<String> iterator = skip(list, 2).iterator();
650 try {
651 iterator.remove();
652 fail("Expected UnsupportedOperationException");
653 } catch (UnsupportedOperationException expected) {}
654 }
655
656 @GwtIncompatible("slow (~35s)")
657 public void testSkip_iterator() {
658 new IteratorTester<Integer>(5, MODIFIABLE, newArrayList(2, 3),
659 IteratorTester.KnownOrder.KNOWN_ORDER) {
660 @Override protected Iterator<Integer> newTargetIterator() {
661 return skip(newLinkedHashSet(asList(1, 2, 3)), 1).iterator();
662 }
663 }.test();
664 }
665
666 @GwtIncompatible("slow (~35s)")
667 public void testSkip_iteratorList() {
668 new IteratorTester<Integer>(5, MODIFIABLE, newArrayList(2, 3),
669 IteratorTester.KnownOrder.KNOWN_ORDER) {
670 @Override protected Iterator<Integer> newTargetIterator() {
671 return skip(newArrayList(1, 2, 3), 1).iterator();
672 }
673 }.test();
674 }
675
676 public void testSkip_nonStructurallyModifiedList() throws Exception {
677 List<String> list = newArrayList("a", "b", "c");
678 Iterable<String> tail = skip(list, 1);
679 Iterator<String> tailIterator = tail.iterator();
680 list.set(2, "C");
681 assertEquals("b", tailIterator.next());
682 assertEquals("C", tailIterator.next());
683 assertFalse(tailIterator.hasNext());
684 }
685
686 public void testSkip_structurallyModifiedSkipSome() throws Exception {
687 Collection<String> set = newLinkedHashSet(asList("a", "b", "c"));
688 Iterable<String> tail = skip(set, 1);
689 set.remove("b");
690 set.addAll(newArrayList("A", "B", "C"));
691 assertThat(tail).iteratesAs("c", "A", "B", "C");
692 }
693
694 public void testSkip_structurallyModifiedSkipSomeList() throws Exception {
695 List<String> list = newArrayList("a", "b", "c");
696 Iterable<String> tail = skip(list, 1);
697 list.subList(1, 3).clear();
698 list.addAll(0, newArrayList("A", "B", "C"));
699 assertThat(tail).iteratesAs("B", "C", "a");
700 }
701
702 public void testSkip_structurallyModifiedSkipAll() throws Exception {
703 Collection<String> set = newLinkedHashSet(asList("a", "b", "c"));
704 Iterable<String> tail = skip(set, 2);
705 set.remove("a");
706 set.remove("b");
707 assertFalse(tail.iterator().hasNext());
708 }
709
710 public void testSkip_structurallyModifiedSkipAllList() throws Exception {
711 List<String> list = newArrayList("a", "b", "c");
712 Iterable<String> tail = skip(list, 2);
713 list.subList(0, 2).clear();
714 assertTrue(Iterables.isEmpty(tail));
715 }
716
717 public void testSkip_illegalArgument() {
718 List<String> list = newArrayList("a", "b", "c");
719 try {
720 skip(list, -1);
721 fail();
722 } catch (IllegalArgumentException expected) {}
723 }
724
725 private void testGetOnAbc(Iterable<String> iterable) {
726 try {
727 Iterables.get(iterable, -1);
728 fail();
729 } catch (IndexOutOfBoundsException expected) {}
730 assertEquals("a", Iterables.get(iterable, 0));
731 assertEquals("b", Iterables.get(iterable, 1));
732 assertEquals("c", Iterables.get(iterable, 2));
733 try {
734 Iterables.get(iterable, 3);
735 fail();
736 } catch (IndexOutOfBoundsException nsee) {}
737 try {
738 Iterables.get(iterable, 4);
739 fail();
740 } catch (IndexOutOfBoundsException nsee) {}
741 }
742
743 private void testGetOnEmpty(Iterable<String> iterable) {
744 try {
745 Iterables.get(iterable, 0);
746 fail();
747 } catch (IndexOutOfBoundsException expected) {}
748 }
749
750 public void testGet_list() {
751 testGetOnAbc(newArrayList("a", "b", "c"));
752 }
753
754 public void testGet_emptyList() {
755 testGetOnEmpty(Collections.<String>emptyList());
756 }
757
758 public void testGet_sortedSet() {
759 testGetOnAbc(ImmutableSortedSet.of("b", "c", "a"));
760 }
761
762 public void testGet_emptySortedSet() {
763 testGetOnEmpty(ImmutableSortedSet.<String>of());
764 }
765
766 public void testGet_iterable() {
767 testGetOnAbc(ImmutableSet.of("a", "b", "c"));
768 }
769
770 public void testGet_emptyIterable() {
771 testGetOnEmpty(Sets.<String>newHashSet());
772 }
773
774 public void testGet_withDefault_negativePosition() {
775 try {
776 Iterables.get(newArrayList("a", "b", "c"), -1, "d");
777 fail();
778 } catch (IndexOutOfBoundsException expected) {
779
780 }
781 }
782
783 public void testGet_withDefault_simple() {
784 ArrayList<String> list = newArrayList("a", "b", "c");
785 assertEquals("b", Iterables.get(list, 1, "d"));
786 }
787
788 public void testGet_withDefault_iterable() {
789 Set<String> set = ImmutableSet.of("a", "b", "c");
790 assertEquals("b", Iterables.get(set, 1, "d"));
791 }
792
793 public void testGet_withDefault_last() {
794 ArrayList<String> list = newArrayList("a", "b", "c");
795 assertEquals("c", Iterables.get(list, 2, "d"));
796 }
797
798 public void testGet_withDefault_lastPlusOne() {
799 ArrayList<String> list = newArrayList("a", "b", "c");
800 assertEquals("d", Iterables.get(list, 3, "d"));
801 }
802
803 public void testGet_withDefault_doesntIterate() {
804 List<String> list = new DiesOnIteratorArrayList();
805 list.add("a");
806 assertEquals("a", Iterables.get(list, 0, "b"));
807 }
808
809 public void testGetFirst_withDefault_singleton() {
810 Iterable<String> iterable = Collections.singletonList("foo");
811 assertEquals("foo", Iterables.getFirst(iterable, "bar"));
812 }
813
814 public void testGetFirst_withDefault_empty() {
815 Iterable<String> iterable = Collections.emptyList();
816 assertEquals("bar", Iterables.getFirst(iterable, "bar"));
817 }
818
819 public void testGetFirst_withDefault_empty_null() {
820 Iterable<String> iterable = Collections.emptyList();
821 assertNull(Iterables.getFirst(iterable, null));
822 }
823
824 public void testGetFirst_withDefault_multiple() {
825 Iterable<String> iterable = asList("foo", "bar");
826 assertEquals("foo", Iterables.getFirst(iterable, "qux"));
827 }
828
829 public void testGetLast_list() {
830 List<String> list = newArrayList("a", "b", "c");
831 assertEquals("c", Iterables.getLast(list));
832 }
833
834 public void testGetLast_emptyList() {
835 List<String> list = Collections.emptyList();
836 try {
837 Iterables.getLast(list);
838 fail();
839 } catch (NoSuchElementException e) {}
840 }
841
842 public void testGetLast_sortedSet() {
843 SortedSet<String> sortedSet = ImmutableSortedSet.of("b", "c", "a");
844 assertEquals("c", Iterables.getLast(sortedSet));
845 }
846
847 public void testGetLast_withDefault_singleton() {
848 Iterable<String> iterable = Collections.singletonList("foo");
849 assertEquals("foo", Iterables.getLast(iterable, "bar"));
850 }
851
852 public void testGetLast_withDefault_empty() {
853 Iterable<String> iterable = Collections.emptyList();
854 assertEquals("bar", Iterables.getLast(iterable, "bar"));
855 }
856
857 public void testGetLast_withDefault_empty_null() {
858 Iterable<String> iterable = Collections.emptyList();
859 assertNull(Iterables.getLast(iterable, null));
860 }
861
862 public void testGetLast_withDefault_multiple() {
863 Iterable<String> iterable = asList("foo", "bar");
864 assertEquals("bar", Iterables.getLast(iterable, "qux"));
865 }
866
867
868
869
870
871
872 private static class DiesOnIteratorArrayList extends ArrayList<String> {
873
874
875
876 @Override
877 public Iterator<String> iterator() {
878 throw new UnsupportedOperationException();
879 }
880 }
881
882 public void testGetLast_withDefault_not_empty_list() {
883
884 List<String> diesOnIteratorList = new DiesOnIteratorArrayList();
885 diesOnIteratorList.add("bar");
886
887 assertEquals("bar", Iterables.getLast(diesOnIteratorList, "qux"));
888 }
889
890
891
892
893
894
895 private static final class DiesOnIteratorTreeSet extends TreeSet<String> {
896
897
898
899 @Override
900 public Iterator<String> iterator() {
901 throw new UnsupportedOperationException();
902 }
903 }
904
905 public void testGetLast_emptySortedSet() {
906 SortedSet<String> sortedSet = ImmutableSortedSet.of();
907 try {
908 Iterables.getLast(sortedSet);
909 fail();
910 } catch (NoSuchElementException e) {}
911 }
912
913 public void testGetLast_iterable() {
914 Set<String> set = ImmutableSet.of("a", "b", "c");
915 assertEquals("c", Iterables.getLast(set));
916 }
917
918 public void testGetLast_emptyIterable() {
919 Set<String> set = Sets.newHashSet();
920 try {
921 Iterables.getLast(set);
922 fail();
923 } catch (NoSuchElementException e) {}
924 }
925
926 public void testUnmodifiableIterable() {
927 List<String> list = newArrayList("a", "b", "c");
928 Iterable<String> iterable = Iterables.unmodifiableIterable(list);
929 Iterator<String> iterator = iterable.iterator();
930 iterator.next();
931 try {
932 iterator.remove();
933 fail();
934 } catch (UnsupportedOperationException expected) {}
935 assertEquals("[a, b, c]", iterable.toString());
936 }
937
938 @SuppressWarnings("deprecation")
939 public void testUnmodifiableIterableShortCircuit() {
940 List<String> list = newArrayList("a", "b", "c");
941 Iterable<String> iterable = Iterables.unmodifiableIterable(list);
942 Iterable<String> iterable2 = Iterables.unmodifiableIterable(iterable);
943 assertSame(iterable, iterable2);
944 ImmutableList<String> immutableList = ImmutableList.of("a", "b", "c");
945 assertSame(immutableList, Iterables.unmodifiableIterable(immutableList));
946 assertSame(immutableList,
947 Iterables.unmodifiableIterable((List<String>) immutableList));
948 }
949
950 public void testFrequency_multiset() {
951 Multiset<String> multiset
952 = ImmutableMultiset.of("a", "b", "a", "c", "b", "a");
953 assertEquals(3, Iterables.frequency(multiset, "a"));
954 assertEquals(2, Iterables.frequency(multiset, "b"));
955 assertEquals(1, Iterables.frequency(multiset, "c"));
956 assertEquals(0, Iterables.frequency(multiset, "d"));
957 assertEquals(0, Iterables.frequency(multiset, 4.2));
958 assertEquals(0, Iterables.frequency(multiset, null));
959 }
960
961 public void testFrequency_set() {
962 Set<String> set = Sets.newHashSet("a", "b", "c");
963 assertEquals(1, Iterables.frequency(set, "a"));
964 assertEquals(1, Iterables.frequency(set, "b"));
965 assertEquals(1, Iterables.frequency(set, "c"));
966 assertEquals(0, Iterables.frequency(set, "d"));
967 assertEquals(0, Iterables.frequency(set, 4.2));
968 assertEquals(0, Iterables.frequency(set, null));
969 }
970
971 public void testFrequency_list() {
972 List<String> list = newArrayList("a", "b", "a", "c", "b", "a");
973 assertEquals(3, Iterables.frequency(list, "a"));
974 assertEquals(2, Iterables.frequency(list, "b"));
975 assertEquals(1, Iterables.frequency(list, "c"));
976 assertEquals(0, Iterables.frequency(list, "d"));
977 assertEquals(0, Iterables.frequency(list, 4.2));
978 assertEquals(0, Iterables.frequency(list, null));
979 }
980
981 public void testRemoveAll_collection() {
982 List<String> list = newArrayList("a", "b", "c", "d", "e");
983 assertTrue(Iterables.removeAll(list, newArrayList("b", "d", "f")));
984 assertEquals(newArrayList("a", "c", "e"), list);
985 assertFalse(Iterables.removeAll(list, newArrayList("x", "y", "z")));
986 assertEquals(newArrayList("a", "c", "e"), list);
987 }
988
989 public void testRemoveAll_iterable() {
990 final List<String> list = newArrayList("a", "b", "c", "d", "e");
991 Iterable<String> iterable = new Iterable<String>() {
992 @Override
993 public Iterator<String> iterator() {
994 return list.iterator();
995 }
996 };
997 assertTrue(Iterables.removeAll(iterable, newArrayList("b", "d", "f")));
998 assertEquals(newArrayList("a", "c", "e"), list);
999 assertFalse(Iterables.removeAll(iterable, newArrayList("x", "y", "z")));
1000 assertEquals(newArrayList("a", "c", "e"), list);
1001 }
1002
1003 public void testRetainAll_collection() {
1004 List<String> list = newArrayList("a", "b", "c", "d", "e");
1005 assertTrue(Iterables.retainAll(list, newArrayList("b", "d", "f")));
1006 assertEquals(newArrayList("b", "d"), list);
1007 assertFalse(Iterables.retainAll(list, newArrayList("b", "e", "d")));
1008 assertEquals(newArrayList("b", "d"), list);
1009 }
1010
1011 public void testRetainAll_iterable() {
1012 final List<String> list = newArrayList("a", "b", "c", "d", "e");
1013 Iterable<String> iterable = new Iterable<String>() {
1014 @Override
1015 public Iterator<String> iterator() {
1016 return list.iterator();
1017 }
1018 };
1019 assertTrue(Iterables.retainAll(iterable, newArrayList("b", "d", "f")));
1020 assertEquals(newArrayList("b", "d"), list);
1021 assertFalse(Iterables.retainAll(iterable, newArrayList("b", "e", "d")));
1022 assertEquals(newArrayList("b", "d"), list);
1023 }
1024
1025 public void testRemoveIf_randomAccess() {
1026 List<String> list = newArrayList("a", "b", "c", "d", "e");
1027 assertTrue(Iterables.removeIf(list,
1028 new Predicate<String>() {
1029 @Override
1030 public boolean apply(String s) {
1031 return s.equals("b") || s.equals("d") || s.equals("f");
1032 }
1033 }));
1034 assertEquals(newArrayList("a", "c", "e"), list);
1035 assertFalse(Iterables.removeIf(list,
1036 new Predicate<String>() {
1037 @Override
1038 public boolean apply(String s) {
1039 return s.equals("x") || s.equals("y") || s.equals("z");
1040 }
1041 }));
1042 assertEquals(newArrayList("a", "c", "e"), list);
1043 }
1044
1045 public void testRemoveIf_transformedList() {
1046 List<String> list = newArrayList("1", "2", "3", "4", "5");
1047 List<Integer> transformed = Lists.transform(list,
1048 new Function<String, Integer>() {
1049 @Override
1050 public Integer apply(String s) {
1051 return Integer.valueOf(s);
1052 }
1053 });
1054 assertTrue(Iterables.removeIf(transformed,
1055 new Predicate<Integer>() {
1056 @Override
1057 public boolean apply(Integer n) {
1058 return (n & 1) == 0;
1059 }
1060 }));
1061 assertEquals(newArrayList("1", "3", "5"), list);
1062 assertFalse(Iterables.removeIf(transformed,
1063 new Predicate<Integer>() {
1064 @Override
1065 public boolean apply(Integer n) {
1066 return (n & 1) == 0;
1067 }
1068 }));
1069 assertEquals(newArrayList("1", "3", "5"), list);
1070 }
1071
1072 public void testRemoveIf_noRandomAccess() {
1073 List<String> list = Lists.newLinkedList(asList("a", "b", "c", "d", "e"));
1074 assertTrue(Iterables.removeIf(list,
1075 new Predicate<String>() {
1076 @Override
1077 public boolean apply(String s) {
1078 return s.equals("b") || s.equals("d") || s.equals("f");
1079 }
1080 }));
1081 assertEquals(newArrayList("a", "c", "e"), list);
1082 assertFalse(Iterables.removeIf(list,
1083 new Predicate<String>() {
1084 @Override
1085 public boolean apply(String s) {
1086 return s.equals("x") || s.equals("y") || s.equals("z");
1087 }
1088 }));
1089 assertEquals(newArrayList("a", "c", "e"), list);
1090 }
1091
1092
1093
1094
1095
1096
1097 public void testIterableWithToString() {
1098 assertEquals("[]", create().toString());
1099 assertEquals("[a]", create("a").toString());
1100 assertEquals("[a, b, c]", create("a", "b", "c").toString());
1101 assertEquals("[c, a, a]", create("c", "a", "a").toString());
1102 }
1103
1104 public void testIterableWithToStringNull() {
1105 assertEquals("[null]", create((String) null).toString());
1106 assertEquals("[null, null]", create(null, null).toString());
1107 assertEquals("[, null, a]", create("", null, "a").toString());
1108 }
1109
1110
1111 private static Iterable<String> create(String... strings) {
1112 final List<String> list = asList(strings);
1113 return new FluentIterable<String>() {
1114 @Override
1115 public Iterator<String> iterator() {
1116 return list.iterator();
1117 }
1118 };
1119 }
1120
1121 public void testConsumingIterable() {
1122
1123 List<String> list = Lists.newArrayList(asList("a", "b"));
1124
1125
1126 Iterable<String> consumingIterable = Iterables.consumingIterable(list);
1127 assertEquals("Iterables.consumingIterable(...)", consumingIterable.toString());
1128 Iterator<String> consumingIterator = consumingIterable.iterator();
1129
1130 assertThat(list).has().exactly("a", "b").inOrder();
1131
1132 assertTrue(consumingIterator.hasNext());
1133 assertThat(list).has().exactly("a", "b").inOrder();
1134 assertEquals("a", consumingIterator.next());
1135 assertThat(list).has().item("b");
1136
1137 assertTrue(consumingIterator.hasNext());
1138 assertEquals("b", consumingIterator.next());
1139 assertThat(list).isEmpty();
1140
1141 assertFalse(consumingIterator.hasNext());
1142 }
1143
1144 @GwtIncompatible("?")
1145
1146 public void testConsumingIterable_duelingIterators() {
1147
1148 List<String> list = Lists.newArrayList(asList("a", "b"));
1149
1150
1151 Iterator<String> i1 = Iterables.consumingIterable(list).iterator();
1152 Iterator<String> i2 = Iterables.consumingIterable(list).iterator();
1153
1154 i1.next();
1155 try {
1156 i2.next();
1157 fail("Concurrent modification should throw an exception.");
1158 } catch (ConcurrentModificationException cme) {
1159
1160 }
1161 }
1162
1163 public void testConsumingIterable_queue_iterator() {
1164 final List<Integer> items = ImmutableList.of(4, 8, 15, 16, 23, 42);
1165 new IteratorTester<Integer>(
1166 3,
1167 UNMODIFIABLE,
1168 items,
1169 IteratorTester.KnownOrder.KNOWN_ORDER) {
1170 @Override protected Iterator<Integer> newTargetIterator() {
1171 return Iterables.consumingIterable(Lists.newLinkedList(items))
1172 .iterator();
1173 }
1174 }.test();
1175 }
1176
1177 public void testConsumingIterable_queue_removesFromQueue() {
1178 Queue<Integer> queue = Lists.newLinkedList(asList(5, 14));
1179
1180 Iterator<Integer> consumingIterator =
1181 Iterables.consumingIterable(queue).iterator();
1182
1183 assertEquals(5, queue.peek().intValue());
1184 assertEquals(5, consumingIterator.next().intValue());
1185
1186 assertEquals(14, queue.peek().intValue());
1187 assertTrue(consumingIterator.hasNext());
1188 assertTrue(queue.isEmpty());
1189 }
1190
1191 public void testConsumingIterable_noIteratorCall() {
1192 Queue<Integer> queue =
1193 new UnIterableQueue<Integer>(Lists.newLinkedList(asList(5, 14)));
1194
1195 Iterator<Integer> consumingIterator =
1196 Iterables.consumingIterable(queue).iterator();
1197
1198
1199
1200
1201 assertEquals(5, consumingIterator.next().intValue());
1202 }
1203
1204 private static class UnIterableQueue<T> extends ForwardingQueue<T> {
1205 private Queue<T> queue;
1206
1207 UnIterableQueue(Queue<T> queue) {
1208 this.queue = queue;
1209 }
1210
1211 @Override public Iterator<T> iterator() {
1212 throw new UnsupportedOperationException();
1213 }
1214
1215 @Override protected Queue<T> delegate() {
1216 return queue;
1217 }
1218 }
1219
1220 public void testIndexOf_empty() {
1221 List<String> list = new ArrayList<String>();
1222 assertEquals(-1, Iterables.indexOf(list, Predicates.equalTo("")));
1223 }
1224
1225 public void testIndexOf_oneElement() {
1226 List<String> list = Lists.newArrayList("bob");
1227 assertEquals(0, Iterables.indexOf(list, Predicates.equalTo("bob")));
1228 assertEquals(-1, Iterables.indexOf(list, Predicates.equalTo("jack")));
1229 }
1230
1231 public void testIndexOf_twoElements() {
1232 List<String> list = Lists.newArrayList("mary", "bob");
1233 assertEquals(0, Iterables.indexOf(list, Predicates.equalTo("mary")));
1234 assertEquals(1, Iterables.indexOf(list, Predicates.equalTo("bob")));
1235 assertEquals(-1, Iterables.indexOf(list, Predicates.equalTo("jack")));
1236 }
1237
1238 public void testIndexOf_withDuplicates() {
1239 List<String> list =
1240 Lists.newArrayList("mary", "bob", "bob", "bob", "sam");
1241 assertEquals(0, Iterables.indexOf(list, Predicates.equalTo("mary")));
1242 assertEquals(1, Iterables.indexOf(list, Predicates.equalTo("bob")));
1243 assertEquals(4, Iterables.indexOf(list, Predicates.equalTo("sam")));
1244 assertEquals(-1, Iterables.indexOf(list, Predicates.equalTo("jack")));
1245 }
1246
1247 private static final Predicate<CharSequence> STARTSWITH_A =
1248 new Predicate<CharSequence>() {
1249 @Override public boolean apply(CharSequence input) {
1250 return (input.length() > 0) && (input.charAt(0) == 'a');
1251 }
1252 };
1253
1254 public void testIndexOf_genericPredicate() {
1255 List<CharSequence> sequences = Lists.newArrayList();
1256 sequences.add("bob");
1257 sequences.add(new StringBuilder("charlie"));
1258 sequences.add(new StringBuffer("henry"));
1259 sequences.add(new StringBuilder("apple"));
1260 sequences.add("lemon");
1261
1262 assertEquals(3, Iterables.indexOf(sequences, STARTSWITH_A));
1263 }
1264
1265 public void testIndexOf_genericPredicate2() {
1266 List<String> sequences =
1267 Lists.newArrayList("bob", "charlie", "henry", "apple", "lemon");
1268 assertEquals(3, Iterables.indexOf(sequences, STARTSWITH_A));
1269 }
1270
1271 public void testMergeSorted_empty() {
1272
1273 Iterable<Iterable<Integer>> elements = ImmutableList.of();
1274
1275
1276 Iterable<Integer> iterable =
1277 Iterables.mergeSorted(elements, Ordering.natural());
1278
1279
1280 Iterator<Integer> iterator = iterable.iterator();
1281 assertFalse(iterator.hasNext());
1282 try {
1283 iterator.next();
1284 fail("next() on empty iterator should throw NoSuchElementException");
1285 } catch (NoSuchElementException e) {
1286
1287 }
1288 }
1289
1290 public void testMergeSorted_single_empty() {
1291
1292 Iterable<Integer> iterable0 = ImmutableList.of();
1293 Iterable<Iterable<Integer>> iterables = ImmutableList.of(iterable0);
1294
1295
1296 verifyMergeSorted(iterables, ImmutableList.<Integer>of());
1297 }
1298
1299 public void testMergeSorted_single() {
1300
1301 Iterable<Integer> iterable0 = ImmutableList.of(1, 2, 3);
1302 Iterable<Iterable<Integer>> iterables = ImmutableList.of(iterable0);
1303
1304
1305 verifyMergeSorted(iterables, iterable0);
1306 }
1307
1308 public void testMergeSorted_pyramid() {
1309 List<Iterable<Integer>> iterables = Lists.newLinkedList();
1310 List<Integer> allIntegers = Lists.newArrayList();
1311
1312
1313 for (int i = 0; i < 10; i++) {
1314 List<Integer> list = Lists.newLinkedList();
1315 for (int j = 0; j < i; j++) {
1316 list.add(j);
1317 allIntegers.add(j);
1318 }
1319 iterables.add(Ordering.natural().sortedCopy(list));
1320 }
1321
1322 verifyMergeSorted(iterables, allIntegers);
1323 }
1324
1325
1326 public void testMergeSorted_skipping_pyramid() {
1327 List<Iterable<Integer>> iterables = Lists.newLinkedList();
1328 List<Integer> allIntegers = Lists.newArrayList();
1329
1330 for (int i = 0; i < 20; i++) {
1331 List<Integer> list = Lists.newLinkedList();
1332 for (int j = 0; j < i; j++) {
1333 list.add(j * i);
1334 allIntegers.add(j * i);
1335 }
1336 iterables.add(Ordering.natural().sortedCopy(list));
1337 }
1338
1339 verifyMergeSorted(iterables, allIntegers);
1340 }
1341
1342 @GwtIncompatible("reflection")
1343 public void testIterables_nullCheck() throws Exception {
1344 new ClassSanityTester()
1345 .forAllPublicStaticMethods(Iterables.class)
1346 .thatReturn(Iterable.class)
1347 .testNulls();
1348 }
1349
1350 private static void verifyMergeSorted(Iterable<Iterable<Integer>> iterables,
1351 Iterable<Integer> unsortedExpected) {
1352 Iterable<Integer> expected =
1353 Ordering.natural().sortedCopy(unsortedExpected);
1354
1355 Iterable<Integer> mergedIterator =
1356 Iterables.mergeSorted(iterables, Ordering.natural());
1357
1358 assertEquals(Lists.newLinkedList(expected),
1359 Lists.newLinkedList(mergedIterator));
1360 }
1361 }