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