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