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
17package com.google.common.collect;
18
19import static com.google.common.collect.Iterables.skip;
20import static com.google.common.collect.Lists.newArrayList;
21import static com.google.common.collect.Sets.newLinkedHashSet;
22import static com.google.common.collect.testing.IteratorFeature.MODIFIABLE;
23import static com.google.common.collect.testing.IteratorFeature.UNMODIFIABLE;
24import static com.google.common.truth.Truth.assertThat;
25import static java.util.Arrays.asList;
26import static java.util.Collections.emptyList;
27
28import com.google.common.annotations.GwtCompatible;
29import com.google.common.annotations.GwtIncompatible;
30import com.google.common.base.Function;
31import com.google.common.base.Optional;
32import com.google.common.base.Predicate;
33import com.google.common.base.Predicates;
34import com.google.common.collect.testing.IteratorTester;
35import com.google.common.testing.ClassSanityTester;
36import com.google.common.testing.NullPointerTester;
37
38import junit.framework.AssertionFailedError;
39import junit.framework.TestCase;
40
41import java.util.ArrayList;
42import java.util.Arrays;
43import java.util.Collection;
44import java.util.Collections;
45import java.util.ConcurrentModificationException;
46import java.util.Iterator;
47import java.util.List;
48import java.util.NoSuchElementException;
49import java.util.Queue;
50import java.util.RandomAccess;
51import java.util.Set;
52import java.util.SortedSet;
53import 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)
62public 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}
1362