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.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   * Unit test for {@code Iterables}.
57   *
58   * @author Kevin Bourrillion
59   * @author Jared Levy
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       // Expected to fail.
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   // Far less exhaustive than the tests in IteratorsTest
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     // We left the last iterator pointing to "b". But a new iterator should
356     // always point to "a".
357     for (String string : cycle) {
358       assertEquals("a", string);
359       break;
360     }
361 
362     assertEquals("[a, b] (cycled)", cycle.toString());
363   }
364 
365   // Again, the exhaustive tests are in IteratorsTest
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     // Now change the inputs and see result dynamically change as well
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     // Changes before the partition is retrieved are reflected
445     list.set(0, 3);
446 
447     Iterator<List<Integer>> iterator = partitions.iterator();
448 
449     // Changes before the partition is retrieved are reflected
450     list.set(1, 4);
451 
452     List<Integer> first = iterator.next();
453 
454     // Changes after are not
455     list.set(0, 5);
456 
457     assertEquals(ImmutableList.of(3, 4), first);
458   }
459 
460   @GwtIncompatible("?")
461   // TODO: Figure out why this is failing in GWT.
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   // TODO: Figure out why this is failing in GWT.
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     // Even though the input list doesn't implement RandomAccess, the output
477     // lists do.
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     // Even though the input list doesn't implement RandomAccess, the output
502     // lists do.
503     assertTrue(iterator.next() instanceof RandomAccess);
504     assertTrue(iterator.next() instanceof RandomAccess);
505   }
506 
507   // More tests in IteratorsTest
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   // More exhaustive tests are in IteratorsTest.
530   public void testElementsEqual() throws Exception {
531     Iterable<?> a;
532     Iterable<?> b;
533 
534     // A few elements.
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     // An element differs.
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     // null versus non-null.
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     // Different lengths.
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       // We want remove() to fail even after a failed call to next().
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       // pass
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    * {@link ArrayList} extension that forbids the use of
869    * {@link Collection#iterator} for tests that need to prove that it isn't
870    * called.
871    */
872   private static class DiesOnIteratorArrayList extends ArrayList<String> {
873     /**
874      * @throws UnsupportedOperationException all the time
875      */
876     @Override
877     public Iterator<String> iterator() {
878       throw new UnsupportedOperationException();
879     }
880   }
881 
882   public void testGetLast_withDefault_not_empty_list() {
883     // TODO: verify that this is the best testing strategy.
884     List<String> diesOnIteratorList = new DiesOnIteratorArrayList();
885     diesOnIteratorList.add("bar");
886 
887     assertEquals("bar", Iterables.getLast(diesOnIteratorList, "qux"));
888   }
889 
890   /**
891    * {@link TreeSet} extension that forbids the use of
892    * {@link Collection#iterator} for tests that need to prove that it isn't
893    * called.
894    */
895   private static final class DiesOnIteratorTreeSet extends TreeSet<String> {
896     /**
897      * @throws UnsupportedOperationException all the time
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") // test of deprecated method
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;  // isEven()
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;  // isEven()
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   // The Maps returned by Maps.filterEntries(), Maps.filterKeys(), and
1093   // Maps.filterValues() are not tested with removeIf() since Maps are not
1094   // Iterable.  Those returned by Iterators.filter() and Iterables.filter()
1095   // are not tested because they are unmodifiable.
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   /** Returns a new iterable over the specified strings. */
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     // Test data
1123     List<String> list = Lists.newArrayList(asList("a", "b"));
1124 
1125     // Test & Verify
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   // TODO: Figure out why this is failing in GWT.
1146   public void testConsumingIterable_duelingIterators() {
1147     // Test data
1148     List<String> list = Lists.newArrayList(asList("a", "b"));
1149 
1150     // Test & Verify
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       // Pass
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      * Make sure that we can get an element off without calling
1199      * UnIterableQueue.iterator().
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     // Setup
1273     Iterable<Iterable<Integer>> elements = ImmutableList.of();
1274 
1275     // Test
1276     Iterable<Integer> iterable =
1277         Iterables.mergeSorted(elements, Ordering.natural());
1278 
1279     // Verify
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       // Huzzah!
1287     }
1288   }
1289 
1290   public void testMergeSorted_single_empty() {
1291     // Setup
1292     Iterable<Integer> iterable0 = ImmutableList.of();
1293     Iterable<Iterable<Integer>> iterables = ImmutableList.of(iterable0);
1294 
1295     // Test & Verify
1296     verifyMergeSorted(iterables, ImmutableList.<Integer>of());
1297   }
1298 
1299   public void testMergeSorted_single() {
1300     // Setup
1301     Iterable<Integer> iterable0 = ImmutableList.of(1, 2, 3);
1302     Iterable<Iterable<Integer>> iterables = ImmutableList.of(iterable0);
1303 
1304     // Test & Verify
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     // Creates iterators like: {{}, {0}, {0, 1}, {0, 1, 2}, ...}
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   // Like the pyramid, but creates more unique values, along with repeated ones.
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 }