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