• 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.CollectPreconditions.checkRemove;
20 import static com.google.common.collect.Iterators.advance;
21 import static com.google.common.collect.Iterators.get;
22 import static com.google.common.collect.Iterators.getLast;
23 import static com.google.common.collect.Lists.newArrayList;
24 import static com.google.common.collect.testing.IteratorFeature.MODIFIABLE;
25 import static com.google.common.collect.testing.IteratorFeature.UNMODIFIABLE;
26 import static com.google.common.truth.Truth.assertThat;
27 import static java.util.Arrays.asList;
28 import static java.util.Collections.singleton;
29 
30 import com.google.common.annotations.GwtCompatible;
31 import com.google.common.annotations.GwtIncompatible;
32 import com.google.common.base.Function;
33 import com.google.common.base.Predicate;
34 import com.google.common.base.Predicates;
35 import com.google.common.collect.testing.IteratorFeature;
36 import com.google.common.collect.testing.IteratorTester;
37 import com.google.common.collect.testing.ListTestSuiteBuilder;
38 import com.google.common.collect.testing.TestStringListGenerator;
39 import com.google.common.collect.testing.features.CollectionFeature;
40 import com.google.common.collect.testing.features.CollectionSize;
41 import com.google.common.collect.testing.features.ListFeature;
42 import com.google.common.testing.NullPointerTester;
43 import java.util.ArrayList;
44 import java.util.Arrays;
45 import java.util.Collection;
46 import java.util.Collections;
47 import java.util.ConcurrentModificationException;
48 import java.util.Enumeration;
49 import java.util.Iterator;
50 import java.util.List;
51 import java.util.ListIterator;
52 import java.util.NoSuchElementException;
53 import java.util.RandomAccess;
54 import java.util.Set;
55 import java.util.Vector;
56 import junit.framework.AssertionFailedError;
57 import junit.framework.Test;
58 import junit.framework.TestCase;
59 import junit.framework.TestSuite;
60 
61 /**
62  * Unit test for {@code Iterators}.
63  *
64  * @author Kevin Bourrillion
65  */
66 @GwtCompatible(emulated = true)
67 public class IteratorsTest extends TestCase {
68 
69   @GwtIncompatible // suite
suite()70   public static Test suite() {
71     TestSuite suite = new TestSuite(IteratorsTest.class.getSimpleName());
72     suite.addTest(testsForRemoveAllAndRetainAll());
73     suite.addTestSuite(IteratorsTest.class);
74     return suite;
75   }
76 
77   @SuppressWarnings("DoNotCall")
testEmptyIterator()78   public void testEmptyIterator() {
79     Iterator<String> iterator = Iterators.emptyIterator();
80     assertFalse(iterator.hasNext());
81     try {
82       iterator.next();
83       fail("no exception thrown");
84     } catch (NoSuchElementException expected) {
85     }
86     try {
87       iterator.remove();
88       fail("no exception thrown");
89     } catch (UnsupportedOperationException expected) {
90     }
91   }
92 
93   @SuppressWarnings("DoNotCall")
testEmptyListIterator()94   public void testEmptyListIterator() {
95     ListIterator<String> iterator = Iterators.emptyListIterator();
96     assertFalse(iterator.hasNext());
97     assertFalse(iterator.hasPrevious());
98     assertEquals(0, iterator.nextIndex());
99     assertEquals(-1, iterator.previousIndex());
100     try {
101       iterator.next();
102       fail("no exception thrown");
103     } catch (NoSuchElementException expected) {
104     }
105     try {
106       iterator.previous();
107       fail("no exception thrown");
108     } catch (NoSuchElementException expected) {
109     }
110     try {
111       iterator.remove();
112       fail("no exception thrown");
113     } catch (UnsupportedOperationException expected) {
114     }
115     try {
116       iterator.set("a");
117       fail("no exception thrown");
118     } catch (UnsupportedOperationException expected) {
119     }
120     try {
121       iterator.add("a");
122       fail("no exception thrown");
123     } catch (UnsupportedOperationException expected) {
124     }
125   }
126 
testEmptyModifiableIterator()127   public void testEmptyModifiableIterator() {
128     Iterator<String> iterator = Iterators.emptyModifiableIterator();
129     assertFalse(iterator.hasNext());
130     try {
131       iterator.next();
132       fail("Expected NoSuchElementException");
133     } catch (NoSuchElementException expected) {
134     }
135     try {
136       iterator.remove();
137       fail("Expected IllegalStateException");
138     } catch (IllegalStateException expected) {
139     }
140   }
141 
testSize0()142   public void testSize0() {
143     Iterator<String> iterator = Iterators.emptyIterator();
144     assertEquals(0, Iterators.size(iterator));
145   }
146 
testSize1()147   public void testSize1() {
148     Iterator<Integer> iterator = Collections.singleton(0).iterator();
149     assertEquals(1, Iterators.size(iterator));
150   }
151 
testSize_partiallyConsumed()152   public void testSize_partiallyConsumed() {
153     Iterator<Integer> iterator = asList(1, 2, 3, 4, 5).iterator();
154     iterator.next();
155     iterator.next();
156     assertEquals(3, Iterators.size(iterator));
157   }
158 
test_contains_nonnull_yes()159   public void test_contains_nonnull_yes() {
160     Iterator<String> set = asList("a", null, "b").iterator();
161     assertTrue(Iterators.contains(set, "b"));
162   }
163 
test_contains_nonnull_no()164   public void test_contains_nonnull_no() {
165     Iterator<String> set = asList("a", "b").iterator();
166     assertFalse(Iterators.contains(set, "c"));
167   }
168 
test_contains_null_yes()169   public void test_contains_null_yes() {
170     Iterator<String> set = asList("a", null, "b").iterator();
171     assertTrue(Iterators.contains(set, null));
172   }
173 
test_contains_null_no()174   public void test_contains_null_no() {
175     Iterator<String> set = asList("a", "b").iterator();
176     assertFalse(Iterators.contains(set, null));
177   }
178 
testGetOnlyElement_noDefault_valid()179   public void testGetOnlyElement_noDefault_valid() {
180     Iterator<String> iterator = Collections.singletonList("foo").iterator();
181     assertEquals("foo", Iterators.getOnlyElement(iterator));
182   }
183 
testGetOnlyElement_noDefault_empty()184   public void testGetOnlyElement_noDefault_empty() {
185     Iterator<String> iterator = Iterators.emptyIterator();
186     try {
187       Iterators.getOnlyElement(iterator);
188       fail();
189     } catch (NoSuchElementException expected) {
190     }
191   }
192 
testGetOnlyElement_noDefault_moreThanOneLessThanFiveElements()193   public void testGetOnlyElement_noDefault_moreThanOneLessThanFiveElements() {
194     Iterator<String> iterator = asList("one", "two").iterator();
195     try {
196       Iterators.getOnlyElement(iterator);
197       fail();
198     } catch (IllegalArgumentException expected) {
199       assertThat(expected).hasMessageThat().isEqualTo("expected one element but was: <one, two>");
200     }
201   }
202 
testGetOnlyElement_noDefault_fiveElements()203   public void testGetOnlyElement_noDefault_fiveElements() {
204     Iterator<String> iterator = asList("one", "two", "three", "four", "five").iterator();
205     try {
206       Iterators.getOnlyElement(iterator);
207       fail();
208     } catch (IllegalArgumentException expected) {
209       assertThat(expected)
210           .hasMessageThat()
211           .isEqualTo("expected one element but was: <one, two, three, four, five>");
212     }
213   }
214 
testGetOnlyElement_noDefault_moreThanFiveElements()215   public void testGetOnlyElement_noDefault_moreThanFiveElements() {
216     Iterator<String> iterator = asList("one", "two", "three", "four", "five", "six").iterator();
217     try {
218       Iterators.getOnlyElement(iterator);
219       fail();
220     } catch (IllegalArgumentException expected) {
221       assertThat(expected)
222           .hasMessageThat()
223           .isEqualTo("expected one element but was: <one, two, three, four, five, ...>");
224     }
225   }
226 
testGetOnlyElement_withDefault_singleton()227   public void testGetOnlyElement_withDefault_singleton() {
228     Iterator<String> iterator = Collections.singletonList("foo").iterator();
229     assertEquals("foo", Iterators.getOnlyElement(iterator, "bar"));
230   }
231 
testGetOnlyElement_withDefault_empty()232   public void testGetOnlyElement_withDefault_empty() {
233     Iterator<String> iterator = Iterators.emptyIterator();
234     assertEquals("bar", Iterators.getOnlyElement(iterator, "bar"));
235   }
236 
testGetOnlyElement_withDefault_empty_null()237   public void testGetOnlyElement_withDefault_empty_null() {
238     Iterator<String> iterator = Iterators.emptyIterator();
239     assertNull(Iterators.getOnlyElement(iterator, null));
240   }
241 
testGetOnlyElement_withDefault_two()242   public void testGetOnlyElement_withDefault_two() {
243     Iterator<String> iterator = asList("foo", "bar").iterator();
244     try {
245       Iterators.getOnlyElement(iterator, "x");
246       fail();
247     } catch (IllegalArgumentException expected) {
248       assertThat(expected).hasMessageThat().isEqualTo("expected one element but was: <foo, bar>");
249     }
250   }
251 
252   @GwtIncompatible // Iterators.toArray(Iterator, Class)
testToArrayEmpty()253   public void testToArrayEmpty() {
254     Iterator<String> iterator = Collections.<String>emptyList().iterator();
255     String[] array = Iterators.toArray(iterator, String.class);
256     assertTrue(Arrays.equals(new String[0], array));
257   }
258 
259   @GwtIncompatible // Iterators.toArray(Iterator, Class)
testToArraySingleton()260   public void testToArraySingleton() {
261     Iterator<String> iterator = Collections.singletonList("a").iterator();
262     String[] array = Iterators.toArray(iterator, String.class);
263     assertTrue(Arrays.equals(new String[] {"a"}, array));
264   }
265 
266   @GwtIncompatible // Iterators.toArray(Iterator, Class)
testToArray()267   public void testToArray() {
268     String[] sourceArray = new String[] {"a", "b", "c"};
269     Iterator<String> iterator = asList(sourceArray).iterator();
270     String[] newArray = Iterators.toArray(iterator, String.class);
271     assertTrue(Arrays.equals(sourceArray, newArray));
272   }
273 
testFilterSimple()274   public void testFilterSimple() {
275     Iterator<String> unfiltered = Lists.newArrayList("foo", "bar").iterator();
276     Iterator<String> filtered = Iterators.filter(unfiltered, Predicates.equalTo("foo"));
277     List<String> expected = Collections.singletonList("foo");
278     List<String> actual = Lists.newArrayList(filtered);
279     assertEquals(expected, actual);
280   }
281 
testFilterNoMatch()282   public void testFilterNoMatch() {
283     Iterator<String> unfiltered = Lists.newArrayList("foo", "bar").iterator();
284     Iterator<String> filtered = Iterators.filter(unfiltered, Predicates.alwaysFalse());
285     List<String> expected = Collections.emptyList();
286     List<String> actual = Lists.newArrayList(filtered);
287     assertEquals(expected, actual);
288   }
289 
testFilterMatchAll()290   public void testFilterMatchAll() {
291     Iterator<String> unfiltered = Lists.newArrayList("foo", "bar").iterator();
292     Iterator<String> filtered = Iterators.filter(unfiltered, Predicates.alwaysTrue());
293     List<String> expected = Lists.newArrayList("foo", "bar");
294     List<String> actual = Lists.newArrayList(filtered);
295     assertEquals(expected, actual);
296   }
297 
testFilterNothing()298   public void testFilterNothing() {
299     Iterator<String> unfiltered = Collections.<String>emptyList().iterator();
300     Iterator<String> filtered =
301         Iterators.filter(
302             unfiltered,
303             new Predicate<String>() {
304               @Override
305               public boolean apply(String s) {
306                 throw new AssertionFailedError("Should never be evaluated");
307               }
308             });
309 
310     List<String> expected = Collections.emptyList();
311     List<String> actual = Lists.newArrayList(filtered);
312     assertEquals(expected, actual);
313   }
314 
315   @GwtIncompatible // unreasonably slow
testFilterUsingIteratorTester()316   public void testFilterUsingIteratorTester() {
317     final List<Integer> list = asList(1, 2, 3, 4, 5);
318     final Predicate<Integer> isEven =
319         new Predicate<Integer>() {
320           @Override
321           public boolean apply(Integer integer) {
322             return integer % 2 == 0;
323           }
324         };
325     new IteratorTester<Integer>(
326         5, UNMODIFIABLE, asList(2, 4), IteratorTester.KnownOrder.KNOWN_ORDER) {
327       @Override
328       protected Iterator<Integer> newTargetIterator() {
329         return Iterators.filter(list.iterator(), isEven);
330       }
331     }.test();
332   }
333 
testAny()334   public void testAny() {
335     List<String> list = Lists.newArrayList();
336     Predicate<String> predicate = Predicates.equalTo("pants");
337 
338     assertFalse(Iterators.any(list.iterator(), predicate));
339     list.add("cool");
340     assertFalse(Iterators.any(list.iterator(), predicate));
341     list.add("pants");
342     assertTrue(Iterators.any(list.iterator(), predicate));
343   }
344 
testAll()345   public void testAll() {
346     List<String> list = Lists.newArrayList();
347     Predicate<String> predicate = Predicates.equalTo("cool");
348 
349     assertTrue(Iterators.all(list.iterator(), predicate));
350     list.add("cool");
351     assertTrue(Iterators.all(list.iterator(), predicate));
352     list.add("pants");
353     assertFalse(Iterators.all(list.iterator(), predicate));
354   }
355 
testFind_firstElement()356   public void testFind_firstElement() {
357     Iterable<String> list = Lists.newArrayList("cool", "pants");
358     Iterator<String> iterator = list.iterator();
359     assertEquals("cool", Iterators.find(iterator, Predicates.equalTo("cool")));
360     assertEquals("pants", iterator.next());
361   }
362 
testFind_lastElement()363   public void testFind_lastElement() {
364     Iterable<String> list = Lists.newArrayList("cool", "pants");
365     Iterator<String> iterator = list.iterator();
366     assertEquals("pants", Iterators.find(iterator, Predicates.equalTo("pants")));
367     assertFalse(iterator.hasNext());
368   }
369 
testFind_notPresent()370   public void testFind_notPresent() {
371     Iterable<String> list = Lists.newArrayList("cool", "pants");
372     Iterator<String> iterator = list.iterator();
373     try {
374       Iterators.find(iterator, Predicates.alwaysFalse());
375       fail();
376     } catch (NoSuchElementException e) {
377     }
378     assertFalse(iterator.hasNext());
379   }
380 
testFind_matchAlways()381   public void testFind_matchAlways() {
382     Iterable<String> list = Lists.newArrayList("cool", "pants");
383     Iterator<String> iterator = list.iterator();
384     assertEquals("cool", Iterators.find(iterator, Predicates.alwaysTrue()));
385   }
386 
testFind_withDefault_first()387   public void testFind_withDefault_first() {
388     Iterable<String> list = Lists.newArrayList("cool", "pants");
389     Iterator<String> iterator = list.iterator();
390     assertEquals("cool", Iterators.find(iterator, Predicates.equalTo("cool"), "woot"));
391     assertEquals("pants", iterator.next());
392   }
393 
testFind_withDefault_last()394   public void testFind_withDefault_last() {
395     Iterable<String> list = Lists.newArrayList("cool", "pants");
396     Iterator<String> iterator = list.iterator();
397     assertEquals("pants", Iterators.find(iterator, Predicates.equalTo("pants"), "woot"));
398     assertFalse(iterator.hasNext());
399   }
400 
testFind_withDefault_notPresent()401   public void testFind_withDefault_notPresent() {
402     Iterable<String> list = Lists.newArrayList("cool", "pants");
403     Iterator<String> iterator = list.iterator();
404     assertEquals("woot", Iterators.find(iterator, Predicates.alwaysFalse(), "woot"));
405     assertFalse(iterator.hasNext());
406   }
407 
testFind_withDefault_notPresent_nullReturn()408   public void testFind_withDefault_notPresent_nullReturn() {
409     Iterable<String> list = Lists.newArrayList("cool", "pants");
410     Iterator<String> iterator = list.iterator();
411     assertNull(Iterators.find(iterator, Predicates.alwaysFalse(), null));
412     assertFalse(iterator.hasNext());
413   }
414 
testFind_withDefault_matchAlways()415   public void testFind_withDefault_matchAlways() {
416     Iterable<String> list = Lists.newArrayList("cool", "pants");
417     Iterator<String> iterator = list.iterator();
418     assertEquals("cool", Iterators.find(iterator, Predicates.alwaysTrue(), "woot"));
419     assertEquals("pants", iterator.next());
420   }
421 
testTryFind_firstElement()422   public void testTryFind_firstElement() {
423     Iterable<String> list = Lists.newArrayList("cool", "pants");
424     Iterator<String> iterator = list.iterator();
425     assertThat(Iterators.tryFind(iterator, Predicates.equalTo("cool"))).hasValue("cool");
426   }
427 
testTryFind_lastElement()428   public void testTryFind_lastElement() {
429     Iterable<String> list = Lists.newArrayList("cool", "pants");
430     Iterator<String> iterator = list.iterator();
431     assertThat(Iterators.tryFind(iterator, Predicates.equalTo("pants"))).hasValue("pants");
432   }
433 
testTryFind_alwaysTrue()434   public void testTryFind_alwaysTrue() {
435     Iterable<String> list = Lists.newArrayList("cool", "pants");
436     Iterator<String> iterator = list.iterator();
437     assertThat(Iterators.tryFind(iterator, Predicates.alwaysTrue())).hasValue("cool");
438   }
439 
testTryFind_alwaysFalse_orDefault()440   public void testTryFind_alwaysFalse_orDefault() {
441     Iterable<String> list = Lists.newArrayList("cool", "pants");
442     Iterator<String> iterator = list.iterator();
443     assertEquals("woot", Iterators.tryFind(iterator, Predicates.alwaysFalse()).or("woot"));
444     assertFalse(iterator.hasNext());
445   }
446 
testTryFind_alwaysFalse_isPresent()447   public void testTryFind_alwaysFalse_isPresent() {
448     Iterable<String> list = Lists.newArrayList("cool", "pants");
449     Iterator<String> iterator = list.iterator();
450     assertThat(Iterators.tryFind(iterator, Predicates.alwaysFalse())).isAbsent();
451     assertFalse(iterator.hasNext());
452   }
453 
testTransform()454   public void testTransform() {
455     Iterator<String> input = asList("1", "2", "3").iterator();
456     Iterator<Integer> result =
457         Iterators.transform(
458             input,
459             new Function<String, Integer>() {
460               @Override
461               public Integer apply(String from) {
462                 return Integer.valueOf(from);
463               }
464             });
465 
466     List<Integer> actual = Lists.newArrayList(result);
467     List<Integer> expected = asList(1, 2, 3);
468     assertEquals(expected, actual);
469   }
470 
testTransformRemove()471   public void testTransformRemove() {
472     List<String> list = Lists.newArrayList("1", "2", "3");
473     Iterator<String> input = list.iterator();
474     Iterator<Integer> iterator =
475         Iterators.transform(
476             input,
477             new Function<String, Integer>() {
478               @Override
479               public Integer apply(String from) {
480                 return Integer.valueOf(from);
481               }
482             });
483 
484     assertEquals(Integer.valueOf(1), iterator.next());
485     assertEquals(Integer.valueOf(2), iterator.next());
486     iterator.remove();
487     assertEquals(asList("1", "3"), list);
488   }
489 
testPoorlyBehavedTransform()490   public void testPoorlyBehavedTransform() {
491     Iterator<String> input = asList("1", null, "3").iterator();
492     Iterator<Integer> result =
493         Iterators.transform(
494             input,
495             new Function<String, Integer>() {
496               @Override
497               public Integer apply(String from) {
498                 return Integer.valueOf(from);
499               }
500             });
501 
502     result.next();
503     try {
504       result.next();
505       fail("Expected NFE");
506     } catch (NumberFormatException expected) {
507     }
508   }
509 
testNullFriendlyTransform()510   public void testNullFriendlyTransform() {
511     Iterator<Integer> input = asList(1, 2, null, 3).iterator();
512     Iterator<String> result =
513         Iterators.transform(
514             input,
515             new Function<Integer, String>() {
516               @Override
517               public String apply(Integer from) {
518                 return String.valueOf(from);
519               }
520             });
521 
522     List<String> actual = Lists.newArrayList(result);
523     List<String> expected = asList("1", "2", "null", "3");
524     assertEquals(expected, actual);
525   }
526 
testCycleOfEmpty()527   public void testCycleOfEmpty() {
528     // "<String>" for javac 1.5.
529     Iterator<String> cycle = Iterators.<String>cycle();
530     assertFalse(cycle.hasNext());
531   }
532 
testCycleOfOne()533   public void testCycleOfOne() {
534     Iterator<String> cycle = Iterators.cycle("a");
535     for (int i = 0; i < 3; i++) {
536       assertTrue(cycle.hasNext());
537       assertEquals("a", cycle.next());
538     }
539   }
540 
testCycleOfOneWithRemove()541   public void testCycleOfOneWithRemove() {
542     Iterable<String> iterable = Lists.newArrayList("a");
543     Iterator<String> cycle = Iterators.cycle(iterable);
544     assertTrue(cycle.hasNext());
545     assertEquals("a", cycle.next());
546     cycle.remove();
547     assertEquals(Collections.emptyList(), iterable);
548     assertFalse(cycle.hasNext());
549   }
550 
testCycleOfTwo()551   public void testCycleOfTwo() {
552     Iterator<String> cycle = Iterators.cycle("a", "b");
553     for (int i = 0; i < 3; i++) {
554       assertTrue(cycle.hasNext());
555       assertEquals("a", cycle.next());
556       assertTrue(cycle.hasNext());
557       assertEquals("b", cycle.next());
558     }
559   }
560 
testCycleOfTwoWithRemove()561   public void testCycleOfTwoWithRemove() {
562     Iterable<String> iterable = Lists.newArrayList("a", "b");
563     Iterator<String> cycle = Iterators.cycle(iterable);
564     assertTrue(cycle.hasNext());
565     assertEquals("a", cycle.next());
566     assertTrue(cycle.hasNext());
567     assertEquals("b", cycle.next());
568     assertTrue(cycle.hasNext());
569     assertEquals("a", cycle.next());
570     cycle.remove();
571     assertEquals(Collections.singletonList("b"), iterable);
572     assertTrue(cycle.hasNext());
573     assertEquals("b", cycle.next());
574     assertTrue(cycle.hasNext());
575     assertEquals("b", cycle.next());
576     cycle.remove();
577     assertEquals(Collections.emptyList(), iterable);
578     assertFalse(cycle.hasNext());
579   }
580 
testCycleRemoveWithoutNext()581   public void testCycleRemoveWithoutNext() {
582     Iterator<String> cycle = Iterators.cycle("a", "b");
583     assertTrue(cycle.hasNext());
584     try {
585       cycle.remove();
586       fail("no exception thrown");
587     } catch (IllegalStateException expected) {
588     }
589   }
590 
testCycleRemoveSameElementTwice()591   public void testCycleRemoveSameElementTwice() {
592     Iterator<String> cycle = Iterators.cycle("a", "b");
593     cycle.next();
594     cycle.remove();
595     try {
596       cycle.remove();
597       fail("no exception thrown");
598     } catch (IllegalStateException expected) {
599     }
600   }
601 
testCycleWhenRemoveIsNotSupported()602   public void testCycleWhenRemoveIsNotSupported() {
603     Iterable<String> iterable = asList("a", "b");
604     Iterator<String> cycle = Iterators.cycle(iterable);
605     cycle.next();
606     try {
607       cycle.remove();
608       fail("no exception thrown");
609     } catch (UnsupportedOperationException expected) {
610     }
611   }
612 
testCycleRemoveAfterHasNext()613   public void testCycleRemoveAfterHasNext() {
614     Iterable<String> iterable = Lists.newArrayList("a");
615     Iterator<String> cycle = Iterators.cycle(iterable);
616     assertTrue(cycle.hasNext());
617     assertEquals("a", cycle.next());
618     assertTrue(cycle.hasNext());
619     cycle.remove();
620     assertEquals(Collections.emptyList(), iterable);
621     assertFalse(cycle.hasNext());
622   }
623 
624   /** An Iterable whose Iterator is rigorous in checking for concurrent modification. */
625   private static final class PickyIterable<E> implements Iterable<E> {
626     final List<E> elements;
627     int modCount = 0;
628 
PickyIterable(E... elements)629     PickyIterable(E... elements) {
630       this.elements = new ArrayList<E>(asList(elements));
631     }
632 
633     @Override
iterator()634     public Iterator<E> iterator() {
635       return new PickyIterator();
636     }
637 
638     final class PickyIterator implements Iterator<E> {
639       int expectedModCount = modCount;
640       int index = 0;
641       boolean canRemove;
642 
643       @Override
hasNext()644       public boolean hasNext() {
645         checkConcurrentModification();
646         return index < elements.size();
647       }
648 
649       @Override
next()650       public E next() {
651         checkConcurrentModification();
652         if (!hasNext()) {
653           throw new NoSuchElementException();
654         }
655         canRemove = true;
656         return elements.get(index++);
657       }
658 
659       @Override
remove()660       public void remove() {
661         checkConcurrentModification();
662         checkRemove(canRemove);
663         elements.remove(--index);
664         expectedModCount = ++modCount;
665         canRemove = false;
666       }
667 
checkConcurrentModification()668       void checkConcurrentModification() {
669         if (expectedModCount != modCount) {
670           throw new ConcurrentModificationException();
671         }
672       }
673     }
674   }
675 
testCycleRemoveAfterHasNextExtraPicky()676   public void testCycleRemoveAfterHasNextExtraPicky() {
677     PickyIterable<String> iterable = new PickyIterable("a");
678     Iterator<String> cycle = Iterators.cycle(iterable);
679     assertTrue(cycle.hasNext());
680     assertEquals("a", cycle.next());
681     assertTrue(cycle.hasNext());
682     cycle.remove();
683     assertTrue(iterable.elements.isEmpty());
684     assertFalse(cycle.hasNext());
685   }
686 
testCycleNoSuchElementException()687   public void testCycleNoSuchElementException() {
688     Iterable<String> iterable = Lists.newArrayList("a");
689     Iterator<String> cycle = Iterators.cycle(iterable);
690     assertTrue(cycle.hasNext());
691     assertEquals("a", cycle.next());
692     cycle.remove();
693     assertFalse(cycle.hasNext());
694     try {
695       cycle.next();
696       fail();
697     } catch (NoSuchElementException expected) {
698     }
699   }
700 
701   @GwtIncompatible // unreasonably slow
testCycleUsingIteratorTester()702   public void testCycleUsingIteratorTester() {
703     new IteratorTester<Integer>(
704         5,
705         UNMODIFIABLE,
706         asList(1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2),
707         IteratorTester.KnownOrder.KNOWN_ORDER) {
708       @Override
709       protected Iterator<Integer> newTargetIterator() {
710         return Iterators.cycle(asList(1, 2));
711       }
712     }.test();
713   }
714 
715   @GwtIncompatible // slow (~5s)
testConcatNoIteratorsYieldsEmpty()716   public void testConcatNoIteratorsYieldsEmpty() {
717     new EmptyIteratorTester() {
718       @SuppressWarnings("unchecked")
719       @Override
720       protected Iterator<Integer> newTargetIterator() {
721         return Iterators.concat();
722       }
723     }.test();
724   }
725 
726   @GwtIncompatible // slow (~5s)
testConcatOneEmptyIteratorYieldsEmpty()727   public void testConcatOneEmptyIteratorYieldsEmpty() {
728     new EmptyIteratorTester() {
729       @SuppressWarnings("unchecked")
730       @Override
731       protected Iterator<Integer> newTargetIterator() {
732         return Iterators.concat(iterateOver());
733       }
734     }.test();
735   }
736 
737   @GwtIncompatible // slow (~5s)
testConcatMultipleEmptyIteratorsYieldsEmpty()738   public void testConcatMultipleEmptyIteratorsYieldsEmpty() {
739     new EmptyIteratorTester() {
740       @Override
741       protected Iterator<Integer> newTargetIterator() {
742         return Iterators.concat(iterateOver(), iterateOver());
743       }
744     }.test();
745   }
746 
747   @GwtIncompatible // slow (~3s)
testConcatSingletonYieldsSingleton()748   public void testConcatSingletonYieldsSingleton() {
749     new SingletonIteratorTester() {
750       @SuppressWarnings("unchecked")
751       @Override
752       protected Iterator<Integer> newTargetIterator() {
753         return Iterators.concat(iterateOver(1));
754       }
755     }.test();
756   }
757 
758   @GwtIncompatible // slow (~5s)
testConcatEmptyAndSingletonAndEmptyYieldsSingleton()759   public void testConcatEmptyAndSingletonAndEmptyYieldsSingleton() {
760     new SingletonIteratorTester() {
761       @Override
762       protected Iterator<Integer> newTargetIterator() {
763         return Iterators.concat(iterateOver(), iterateOver(1), iterateOver());
764       }
765     }.test();
766   }
767 
768   @GwtIncompatible // fairly slow (~40s)
testConcatSingletonAndSingletonYieldsDoubleton()769   public void testConcatSingletonAndSingletonYieldsDoubleton() {
770     new DoubletonIteratorTester() {
771       @Override
772       protected Iterator<Integer> newTargetIterator() {
773         return Iterators.concat(iterateOver(1), iterateOver(2));
774       }
775     }.test();
776   }
777 
778   @GwtIncompatible // fairly slow (~40s)
testConcatSingletonAndSingletonWithEmptiesYieldsDoubleton()779   public void testConcatSingletonAndSingletonWithEmptiesYieldsDoubleton() {
780     new DoubletonIteratorTester() {
781       @Override
782       protected Iterator<Integer> newTargetIterator() {
783         return Iterators.concat(iterateOver(1), iterateOver(), iterateOver(), iterateOver(2));
784       }
785     }.test();
786   }
787 
788   @GwtIncompatible // fairly slow (~50s)
testConcatUnmodifiable()789   public void testConcatUnmodifiable() {
790     new IteratorTester<Integer>(
791         5, UNMODIFIABLE, asList(1, 2), IteratorTester.KnownOrder.KNOWN_ORDER) {
792       @Override
793       protected Iterator<Integer> newTargetIterator() {
794         return Iterators.concat(
795             asList(1).iterator(), Arrays.<Integer>asList().iterator(), asList(2).iterator());
796       }
797     }.test();
798   }
799 
testConcatPartiallyAdvancedSecond()800   public void testConcatPartiallyAdvancedSecond() {
801     Iterator<String> itr1 =
802         Iterators.concat(Iterators.singletonIterator("a"), Iterators.forArray("b", "c"));
803     assertEquals("a", itr1.next());
804     assertEquals("b", itr1.next());
805     Iterator<String> itr2 = Iterators.concat(Iterators.singletonIterator("d"), itr1);
806     assertEquals("d", itr2.next());
807     assertEquals("c", itr2.next());
808   }
809 
testConcatPartiallyAdvancedFirst()810   public void testConcatPartiallyAdvancedFirst() {
811     Iterator<String> itr1 =
812         Iterators.concat(Iterators.singletonIterator("a"), Iterators.forArray("b", "c"));
813     assertEquals("a", itr1.next());
814     assertEquals("b", itr1.next());
815     Iterator<String> itr2 = Iterators.concat(itr1, Iterators.singletonIterator("d"));
816     assertEquals("c", itr2.next());
817     assertEquals("d", itr2.next());
818   }
819 
820   /** Illustrates the somewhat bizarre behavior when a null is passed in. */
testConcatContainingNull()821   public void testConcatContainingNull() {
822     @SuppressWarnings("unchecked")
823     Iterator<Iterator<Integer>> input = asList(iterateOver(1, 2), null, iterateOver(3)).iterator();
824     Iterator<Integer> result = Iterators.concat(input);
825     assertEquals(1, (int) result.next());
826     assertEquals(2, (int) result.next());
827     try {
828       result.hasNext();
829       fail("no exception thrown");
830     } catch (NullPointerException e) {
831     }
832     try {
833       result.next();
834       fail("no exception thrown");
835     } catch (NullPointerException e) {
836     }
837     // There is no way to get "through" to the 3.  Buh-bye
838   }
839 
840   @SuppressWarnings("unchecked")
testConcatVarArgsContainingNull()841   public void testConcatVarArgsContainingNull() {
842     try {
843       Iterators.concat(iterateOver(1, 2), null, iterateOver(3), iterateOver(4), iterateOver(5));
844       fail("no exception thrown");
845     } catch (NullPointerException e) {
846     }
847   }
848 
testConcatNested_appendToEnd()849   public void testConcatNested_appendToEnd() {
850     final int nestingDepth = 128;
851     Iterator<Integer> iterator = iterateOver();
852     for (int i = 0; i < nestingDepth; i++) {
853       iterator = Iterators.concat(iterator, iterateOver(1));
854     }
855     assertEquals(nestingDepth, Iterators.size(iterator));
856   }
857 
testConcatNested_appendToBeginning()858   public void testConcatNested_appendToBeginning() {
859     final int nestingDepth = 128;
860     Iterator<Integer> iterator = iterateOver();
861     for (int i = 0; i < nestingDepth; i++) {
862       iterator = Iterators.concat(iterateOver(1), iterator);
863     }
864     assertEquals(nestingDepth, Iterators.size(iterator));
865   }
866 
testAddAllWithEmptyIterator()867   public void testAddAllWithEmptyIterator() {
868     List<String> alreadyThere = Lists.newArrayList("already", "there");
869 
870     boolean changed = Iterators.addAll(alreadyThere, Iterators.<String>emptyIterator());
871     assertThat(alreadyThere).containsExactly("already", "there").inOrder();
872     assertFalse(changed);
873   }
874 
testAddAllToList()875   public void testAddAllToList() {
876     List<String> alreadyThere = Lists.newArrayList("already", "there");
877     List<String> freshlyAdded = Lists.newArrayList("freshly", "added");
878 
879     boolean changed = Iterators.addAll(alreadyThere, freshlyAdded.iterator());
880 
881     assertThat(alreadyThere).containsExactly("already", "there", "freshly", "added");
882     assertTrue(changed);
883   }
884 
testAddAllToSet()885   public void testAddAllToSet() {
886     Set<String> alreadyThere = Sets.newLinkedHashSet(asList("already", "there"));
887     List<String> oneMore = Lists.newArrayList("there");
888 
889     boolean changed = Iterators.addAll(alreadyThere, oneMore.iterator());
890     assertThat(alreadyThere).containsExactly("already", "there").inOrder();
891     assertFalse(changed);
892   }
893 
894   @GwtIncompatible // NullPointerTester
testNullPointerExceptions()895   public void testNullPointerExceptions() {
896     NullPointerTester tester = new NullPointerTester();
897     tester.testAllPublicStaticMethods(Iterators.class);
898   }
899 
900   @GwtIncompatible // Only used by @GwtIncompatible code
901   private abstract static class EmptyIteratorTester extends IteratorTester<Integer> {
EmptyIteratorTester()902     protected EmptyIteratorTester() {
903       super(3, MODIFIABLE, Collections.<Integer>emptySet(), IteratorTester.KnownOrder.KNOWN_ORDER);
904     }
905   }
906 
907   @GwtIncompatible // Only used by @GwtIncompatible code
908   private abstract static class SingletonIteratorTester extends IteratorTester<Integer> {
SingletonIteratorTester()909     protected SingletonIteratorTester() {
910       super(3, MODIFIABLE, singleton(1), IteratorTester.KnownOrder.KNOWN_ORDER);
911     }
912   }
913 
914   @GwtIncompatible // Only used by @GwtIncompatible code
915   private abstract static class DoubletonIteratorTester extends IteratorTester<Integer> {
DoubletonIteratorTester()916     protected DoubletonIteratorTester() {
917       super(5, MODIFIABLE, newArrayList(1, 2), IteratorTester.KnownOrder.KNOWN_ORDER);
918     }
919   }
920 
iterateOver(final Integer... values)921   private static Iterator<Integer> iterateOver(final Integer... values) {
922     return newArrayList(values).iterator();
923   }
924 
testElementsEqual()925   public void testElementsEqual() {
926     Iterable<?> a;
927     Iterable<?> b;
928 
929     // Base case.
930     a = Lists.newArrayList();
931     b = Collections.emptySet();
932     assertTrue(Iterators.elementsEqual(a.iterator(), b.iterator()));
933 
934     // A few elements.
935     a = asList(4, 8, 15, 16, 23, 42);
936     b = asList(4, 8, 15, 16, 23, 42);
937     assertTrue(Iterators.elementsEqual(a.iterator(), b.iterator()));
938 
939     // The same, but with nulls.
940     a = asList(4, 8, null, 16, 23, 42);
941     b = asList(4, 8, null, 16, 23, 42);
942     assertTrue(Iterators.elementsEqual(a.iterator(), b.iterator()));
943 
944     // Different Iterable types (still equal elements, though).
945     a = ImmutableList.of(4, 8, 15, 16, 23, 42);
946     b = asList(4, 8, 15, 16, 23, 42);
947     assertTrue(Iterators.elementsEqual(a.iterator(), b.iterator()));
948 
949     // An element differs.
950     a = asList(4, 8, 15, 12, 23, 42);
951     b = asList(4, 8, 15, 16, 23, 42);
952     assertFalse(Iterators.elementsEqual(a.iterator(), b.iterator()));
953 
954     // null versus non-null.
955     a = asList(4, 8, 15, null, 23, 42);
956     b = asList(4, 8, 15, 16, 23, 42);
957     assertFalse(Iterators.elementsEqual(a.iterator(), b.iterator()));
958     assertFalse(Iterators.elementsEqual(b.iterator(), a.iterator()));
959 
960     // Different lengths.
961     a = asList(4, 8, 15, 16, 23);
962     b = asList(4, 8, 15, 16, 23, 42);
963     assertFalse(Iterators.elementsEqual(a.iterator(), b.iterator()));
964     assertFalse(Iterators.elementsEqual(b.iterator(), a.iterator()));
965 
966     // Different lengths, one is empty.
967     a = Collections.emptySet();
968     b = asList(4, 8, 15, 16, 23, 42);
969     assertFalse(Iterators.elementsEqual(a.iterator(), b.iterator()));
970     assertFalse(Iterators.elementsEqual(b.iterator(), a.iterator()));
971   }
972 
testPartition_badSize()973   public void testPartition_badSize() {
974     Iterator<Integer> source = Iterators.singletonIterator(1);
975     try {
976       Iterators.partition(source, 0);
977       fail();
978     } catch (IllegalArgumentException expected) {
979     }
980   }
981 
testPartition_empty()982   public void testPartition_empty() {
983     Iterator<Integer> source = Iterators.emptyIterator();
984     Iterator<List<Integer>> partitions = Iterators.partition(source, 1);
985     assertFalse(partitions.hasNext());
986   }
987 
testPartition_singleton1()988   public void testPartition_singleton1() {
989     Iterator<Integer> source = Iterators.singletonIterator(1);
990     Iterator<List<Integer>> partitions = Iterators.partition(source, 1);
991     assertTrue(partitions.hasNext());
992     assertTrue(partitions.hasNext());
993     assertEquals(ImmutableList.of(1), partitions.next());
994     assertFalse(partitions.hasNext());
995   }
996 
testPartition_singleton2()997   public void testPartition_singleton2() {
998     Iterator<Integer> source = Iterators.singletonIterator(1);
999     Iterator<List<Integer>> partitions = Iterators.partition(source, 2);
1000     assertTrue(partitions.hasNext());
1001     assertTrue(partitions.hasNext());
1002     assertEquals(ImmutableList.of(1), partitions.next());
1003     assertFalse(partitions.hasNext());
1004   }
1005 
1006   @GwtIncompatible // fairly slow (~50s)
testPartition_general()1007   public void testPartition_general() {
1008     new IteratorTester<List<Integer>>(
1009         5,
1010         IteratorFeature.UNMODIFIABLE,
1011         ImmutableList.of(asList(1, 2, 3), asList(4, 5, 6), asList(7)),
1012         IteratorTester.KnownOrder.KNOWN_ORDER) {
1013       @Override
1014       protected Iterator<List<Integer>> newTargetIterator() {
1015         Iterator<Integer> source = Iterators.forArray(1, 2, 3, 4, 5, 6, 7);
1016         return Iterators.partition(source, 3);
1017       }
1018     }.test();
1019   }
1020 
testPartition_view()1021   public void testPartition_view() {
1022     List<Integer> list = asList(1, 2);
1023     Iterator<List<Integer>> partitions = Iterators.partition(list.iterator(), 1);
1024 
1025     // Changes before the partition is retrieved are reflected
1026     list.set(0, 3);
1027     List<Integer> first = partitions.next();
1028 
1029     // Changes after are not
1030     list.set(0, 4);
1031 
1032     assertEquals(ImmutableList.of(3), first);
1033   }
1034 
1035   @GwtIncompatible // ?
1036   // TODO: Figure out why this is failing in GWT.
testPartitionRandomAccess()1037   public void testPartitionRandomAccess() {
1038     Iterator<Integer> source = asList(1, 2, 3).iterator();
1039     Iterator<List<Integer>> partitions = Iterators.partition(source, 2);
1040     assertTrue(partitions.next() instanceof RandomAccess);
1041     assertTrue(partitions.next() instanceof RandomAccess);
1042   }
1043 
testPaddedPartition_badSize()1044   public void testPaddedPartition_badSize() {
1045     Iterator<Integer> source = Iterators.singletonIterator(1);
1046     try {
1047       Iterators.paddedPartition(source, 0);
1048       fail();
1049     } catch (IllegalArgumentException expected) {
1050     }
1051   }
1052 
testPaddedPartition_empty()1053   public void testPaddedPartition_empty() {
1054     Iterator<Integer> source = Iterators.emptyIterator();
1055     Iterator<List<Integer>> partitions = Iterators.paddedPartition(source, 1);
1056     assertFalse(partitions.hasNext());
1057   }
1058 
testPaddedPartition_singleton1()1059   public void testPaddedPartition_singleton1() {
1060     Iterator<Integer> source = Iterators.singletonIterator(1);
1061     Iterator<List<Integer>> partitions = Iterators.paddedPartition(source, 1);
1062     assertTrue(partitions.hasNext());
1063     assertTrue(partitions.hasNext());
1064     assertEquals(ImmutableList.of(1), partitions.next());
1065     assertFalse(partitions.hasNext());
1066   }
1067 
testPaddedPartition_singleton2()1068   public void testPaddedPartition_singleton2() {
1069     Iterator<Integer> source = Iterators.singletonIterator(1);
1070     Iterator<List<Integer>> partitions = Iterators.paddedPartition(source, 2);
1071     assertTrue(partitions.hasNext());
1072     assertTrue(partitions.hasNext());
1073     assertEquals(asList(1, null), partitions.next());
1074     assertFalse(partitions.hasNext());
1075   }
1076 
1077   @GwtIncompatible // fairly slow (~50s)
testPaddedPartition_general()1078   public void testPaddedPartition_general() {
1079     new IteratorTester<List<Integer>>(
1080         5,
1081         IteratorFeature.UNMODIFIABLE,
1082         ImmutableList.of(asList(1, 2, 3), asList(4, 5, 6), asList(7, null, null)),
1083         IteratorTester.KnownOrder.KNOWN_ORDER) {
1084       @Override
1085       protected Iterator<List<Integer>> newTargetIterator() {
1086         Iterator<Integer> source = Iterators.forArray(1, 2, 3, 4, 5, 6, 7);
1087         return Iterators.paddedPartition(source, 3);
1088       }
1089     }.test();
1090   }
1091 
testPaddedPartition_view()1092   public void testPaddedPartition_view() {
1093     List<Integer> list = asList(1, 2);
1094     Iterator<List<Integer>> partitions = Iterators.paddedPartition(list.iterator(), 1);
1095 
1096     // Changes before the PaddedPartition is retrieved are reflected
1097     list.set(0, 3);
1098     List<Integer> first = partitions.next();
1099 
1100     // Changes after are not
1101     list.set(0, 4);
1102 
1103     assertEquals(ImmutableList.of(3), first);
1104   }
1105 
testPaddedPartitionRandomAccess()1106   public void testPaddedPartitionRandomAccess() {
1107     Iterator<Integer> source = asList(1, 2, 3).iterator();
1108     Iterator<List<Integer>> partitions = Iterators.paddedPartition(source, 2);
1109     assertTrue(partitions.next() instanceof RandomAccess);
1110     assertTrue(partitions.next() instanceof RandomAccess);
1111   }
1112 
testForArrayEmpty()1113   public void testForArrayEmpty() {
1114     String[] array = new String[0];
1115     Iterator<String> iterator = Iterators.forArray(array);
1116     assertFalse(iterator.hasNext());
1117     try {
1118       iterator.next();
1119       fail();
1120     } catch (NoSuchElementException expected) {
1121     }
1122     try {
1123       Iterators.forArrayWithPosition(array, 1);
1124       fail();
1125     } catch (IndexOutOfBoundsException expected) {
1126     }
1127   }
1128 
1129   @SuppressWarnings("DoNotCall")
testForArrayTypical()1130   public void testForArrayTypical() {
1131     String[] array = {"foo", "bar"};
1132     Iterator<String> iterator = Iterators.forArray(array);
1133     assertTrue(iterator.hasNext());
1134     assertEquals("foo", iterator.next());
1135     assertTrue(iterator.hasNext());
1136     try {
1137       iterator.remove();
1138       fail();
1139     } catch (UnsupportedOperationException expected) {
1140     }
1141     assertEquals("bar", iterator.next());
1142     assertFalse(iterator.hasNext());
1143     try {
1144       iterator.next();
1145       fail();
1146     } catch (NoSuchElementException expected) {
1147     }
1148   }
1149 
testForArrayWithPosition()1150   public void testForArrayWithPosition() {
1151     String[] array = {"foo", "bar", "cat"};
1152     Iterator<String> iterator = Iterators.forArrayWithPosition(array, 1);
1153     assertTrue(iterator.hasNext());
1154     assertEquals("bar", iterator.next());
1155     assertTrue(iterator.hasNext());
1156     assertEquals("cat", iterator.next());
1157     assertFalse(iterator.hasNext());
1158   }
1159 
testForArrayLengthWithPositionBoundaryCases()1160   public void testForArrayLengthWithPositionBoundaryCases() {
1161     String[] array = {"foo", "bar"};
1162     assertFalse(Iterators.forArrayWithPosition(array, 2).hasNext());
1163     try {
1164       Iterators.forArrayWithPosition(array, -1);
1165       fail();
1166     } catch (IndexOutOfBoundsException expected) {
1167     }
1168     try {
1169       Iterators.forArrayWithPosition(array, 3);
1170       fail();
1171     } catch (IndexOutOfBoundsException expected) {
1172     }
1173   }
1174 
1175   @GwtIncompatible // unreasonably slow
testForArrayUsingTester()1176   public void testForArrayUsingTester() {
1177     new IteratorTester<Integer>(
1178         6, UNMODIFIABLE, asList(1, 2, 3), IteratorTester.KnownOrder.KNOWN_ORDER) {
1179       @Override
1180       protected Iterator<Integer> newTargetIterator() {
1181         return Iterators.forArray(1, 2, 3);
1182       }
1183     }.test();
1184   }
1185 
1186   /*
1187    * TODO(cpovirk): Test forArray with ListIteratorTester (not just IteratorTester), including with
1188    * a start position other than 0.
1189    */
1190 
testForEnumerationEmpty()1191   public void testForEnumerationEmpty() {
1192     Enumeration<Integer> enumer = enumerate();
1193     Iterator<Integer> iter = Iterators.forEnumeration(enumer);
1194 
1195     assertFalse(iter.hasNext());
1196     try {
1197       iter.next();
1198       fail();
1199     } catch (NoSuchElementException expected) {
1200     }
1201   }
1202 
1203   @SuppressWarnings("DoNotCall")
testForEnumerationSingleton()1204   public void testForEnumerationSingleton() {
1205     Enumeration<Integer> enumer = enumerate(1);
1206     Iterator<Integer> iter = Iterators.forEnumeration(enumer);
1207 
1208     assertTrue(iter.hasNext());
1209     assertTrue(iter.hasNext());
1210     assertEquals(1, (int) iter.next());
1211     try {
1212       iter.remove();
1213       fail();
1214     } catch (UnsupportedOperationException expected) {
1215     }
1216     assertFalse(iter.hasNext());
1217     try {
1218       iter.next();
1219       fail();
1220     } catch (NoSuchElementException expected) {
1221     }
1222   }
1223 
testForEnumerationTypical()1224   public void testForEnumerationTypical() {
1225     Enumeration<Integer> enumer = enumerate(1, 2, 3);
1226     Iterator<Integer> iter = Iterators.forEnumeration(enumer);
1227 
1228     assertTrue(iter.hasNext());
1229     assertEquals(1, (int) iter.next());
1230     assertTrue(iter.hasNext());
1231     assertEquals(2, (int) iter.next());
1232     assertTrue(iter.hasNext());
1233     assertEquals(3, (int) iter.next());
1234     assertFalse(iter.hasNext());
1235   }
1236 
testAsEnumerationEmpty()1237   public void testAsEnumerationEmpty() {
1238     Iterator<Integer> iter = Iterators.emptyIterator();
1239     Enumeration<Integer> enumer = Iterators.asEnumeration(iter);
1240 
1241     assertFalse(enumer.hasMoreElements());
1242     try {
1243       enumer.nextElement();
1244       fail();
1245     } catch (NoSuchElementException expected) {
1246     }
1247   }
1248 
testAsEnumerationSingleton()1249   public void testAsEnumerationSingleton() {
1250     Iterator<Integer> iter = ImmutableList.of(1).iterator();
1251     Enumeration<Integer> enumer = Iterators.asEnumeration(iter);
1252 
1253     assertTrue(enumer.hasMoreElements());
1254     assertTrue(enumer.hasMoreElements());
1255     assertEquals(1, (int) enumer.nextElement());
1256     assertFalse(enumer.hasMoreElements());
1257     try {
1258       enumer.nextElement();
1259       fail();
1260     } catch (NoSuchElementException expected) {
1261     }
1262   }
1263 
testAsEnumerationTypical()1264   public void testAsEnumerationTypical() {
1265     Iterator<Integer> iter = ImmutableList.of(1, 2, 3).iterator();
1266     Enumeration<Integer> enumer = Iterators.asEnumeration(iter);
1267 
1268     assertTrue(enumer.hasMoreElements());
1269     assertEquals(1, (int) enumer.nextElement());
1270     assertTrue(enumer.hasMoreElements());
1271     assertEquals(2, (int) enumer.nextElement());
1272     assertTrue(enumer.hasMoreElements());
1273     assertEquals(3, (int) enumer.nextElement());
1274     assertFalse(enumer.hasMoreElements());
1275   }
1276 
enumerate(Integer... ints)1277   private static Enumeration<Integer> enumerate(Integer... ints) {
1278     Vector<Integer> vector = new Vector<>(asList(ints));
1279     return vector.elements();
1280   }
1281 
testToString()1282   public void testToString() {
1283     Iterator<String> iterator = Lists.newArrayList("yam", "bam", "jam", "ham").iterator();
1284     assertEquals("[yam, bam, jam, ham]", Iterators.toString(iterator));
1285   }
1286 
testToStringWithNull()1287   public void testToStringWithNull() {
1288     Iterator<String> iterator = Lists.newArrayList("hello", null, "world").iterator();
1289     assertEquals("[hello, null, world]", Iterators.toString(iterator));
1290   }
1291 
testToStringEmptyIterator()1292   public void testToStringEmptyIterator() {
1293     Iterator<String> iterator = Collections.<String>emptyList().iterator();
1294     assertEquals("[]", Iterators.toString(iterator));
1295   }
1296 
testLimit()1297   public void testLimit() {
1298     List<String> list = newArrayList();
1299     try {
1300       Iterators.limit(list.iterator(), -1);
1301       fail("expected exception");
1302     } catch (IllegalArgumentException expected) {
1303     }
1304 
1305     assertFalse(Iterators.limit(list.iterator(), 0).hasNext());
1306     assertFalse(Iterators.limit(list.iterator(), 1).hasNext());
1307 
1308     list.add("cool");
1309     assertFalse(Iterators.limit(list.iterator(), 0).hasNext());
1310     assertEquals(list, newArrayList(Iterators.limit(list.iterator(), 1)));
1311     assertEquals(list, newArrayList(Iterators.limit(list.iterator(), 2)));
1312 
1313     list.add("pants");
1314     assertFalse(Iterators.limit(list.iterator(), 0).hasNext());
1315     assertEquals(ImmutableList.of("cool"), newArrayList(Iterators.limit(list.iterator(), 1)));
1316     assertEquals(list, newArrayList(Iterators.limit(list.iterator(), 2)));
1317     assertEquals(list, newArrayList(Iterators.limit(list.iterator(), 3)));
1318   }
1319 
testLimitRemove()1320   public void testLimitRemove() {
1321     List<String> list = newArrayList();
1322     list.add("cool");
1323     list.add("pants");
1324     Iterator<String> iterator = Iterators.limit(list.iterator(), 1);
1325     iterator.next();
1326     iterator.remove();
1327     assertFalse(iterator.hasNext());
1328     assertEquals(1, list.size());
1329     assertEquals("pants", list.get(0));
1330   }
1331 
1332   @GwtIncompatible // fairly slow (~30s)
testLimitUsingIteratorTester()1333   public void testLimitUsingIteratorTester() {
1334     final List<Integer> list = Lists.newArrayList(1, 2, 3, 4, 5);
1335     new IteratorTester<Integer>(
1336         5, MODIFIABLE, newArrayList(1, 2, 3), IteratorTester.KnownOrder.KNOWN_ORDER) {
1337       @Override
1338       protected Iterator<Integer> newTargetIterator() {
1339         return Iterators.limit(Lists.newArrayList(list).iterator(), 3);
1340       }
1341     }.test();
1342   }
1343 
testGetNext_withDefault_singleton()1344   public void testGetNext_withDefault_singleton() {
1345     Iterator<String> iterator = Collections.singletonList("foo").iterator();
1346     assertEquals("foo", Iterators.getNext(iterator, "bar"));
1347   }
1348 
testGetNext_withDefault_empty()1349   public void testGetNext_withDefault_empty() {
1350     Iterator<String> iterator = Iterators.emptyIterator();
1351     assertEquals("bar", Iterators.getNext(iterator, "bar"));
1352   }
1353 
testGetNext_withDefault_empty_null()1354   public void testGetNext_withDefault_empty_null() {
1355     Iterator<String> iterator = Iterators.emptyIterator();
1356     assertNull(Iterators.getNext(iterator, null));
1357   }
1358 
testGetNext_withDefault_two()1359   public void testGetNext_withDefault_two() {
1360     Iterator<String> iterator = asList("foo", "bar").iterator();
1361     assertEquals("foo", Iterators.getNext(iterator, "x"));
1362   }
1363 
testGetLast_basic()1364   public void testGetLast_basic() {
1365     List<String> list = newArrayList();
1366     list.add("a");
1367     list.add("b");
1368     assertEquals("b", getLast(list.iterator()));
1369   }
1370 
testGetLast_exception()1371   public void testGetLast_exception() {
1372     List<String> list = newArrayList();
1373     try {
1374       getLast(list.iterator());
1375       fail();
1376     } catch (NoSuchElementException expected) {
1377     }
1378   }
1379 
testGetLast_withDefault_singleton()1380   public void testGetLast_withDefault_singleton() {
1381     Iterator<String> iterator = Collections.singletonList("foo").iterator();
1382     assertEquals("foo", Iterators.getLast(iterator, "bar"));
1383   }
1384 
testGetLast_withDefault_empty()1385   public void testGetLast_withDefault_empty() {
1386     Iterator<String> iterator = Iterators.emptyIterator();
1387     assertEquals("bar", Iterators.getLast(iterator, "bar"));
1388   }
1389 
testGetLast_withDefault_empty_null()1390   public void testGetLast_withDefault_empty_null() {
1391     Iterator<String> iterator = Iterators.emptyIterator();
1392     assertNull(Iterators.getLast(iterator, null));
1393   }
1394 
testGetLast_withDefault_two()1395   public void testGetLast_withDefault_two() {
1396     Iterator<String> iterator = asList("foo", "bar").iterator();
1397     assertEquals("bar", Iterators.getLast(iterator, "x"));
1398   }
1399 
testGet_basic()1400   public void testGet_basic() {
1401     List<String> list = newArrayList();
1402     list.add("a");
1403     list.add("b");
1404     Iterator<String> iterator = list.iterator();
1405     assertEquals("b", get(iterator, 1));
1406     assertFalse(iterator.hasNext());
1407   }
1408 
testGet_atSize()1409   public void testGet_atSize() {
1410     List<String> list = newArrayList();
1411     list.add("a");
1412     list.add("b");
1413     Iterator<String> iterator = list.iterator();
1414     try {
1415       get(iterator, 2);
1416       fail();
1417     } catch (IndexOutOfBoundsException expected) {
1418     }
1419     assertFalse(iterator.hasNext());
1420   }
1421 
testGet_pastEnd()1422   public void testGet_pastEnd() {
1423     List<String> list = newArrayList();
1424     list.add("a");
1425     list.add("b");
1426     Iterator<String> iterator = list.iterator();
1427     try {
1428       get(iterator, 5);
1429       fail();
1430     } catch (IndexOutOfBoundsException expected) {
1431     }
1432     assertFalse(iterator.hasNext());
1433   }
1434 
testGet_empty()1435   public void testGet_empty() {
1436     List<String> list = newArrayList();
1437     Iterator<String> iterator = list.iterator();
1438     try {
1439       get(iterator, 0);
1440       fail();
1441     } catch (IndexOutOfBoundsException expected) {
1442     }
1443     assertFalse(iterator.hasNext());
1444   }
1445 
testGet_negativeIndex()1446   public void testGet_negativeIndex() {
1447     List<String> list = newArrayList("a", "b", "c");
1448     Iterator<String> iterator = list.iterator();
1449     try {
1450       get(iterator, -1);
1451       fail();
1452     } catch (IndexOutOfBoundsException expected) {
1453     }
1454   }
1455 
testGet_withDefault_basic()1456   public void testGet_withDefault_basic() {
1457     List<String> list = newArrayList();
1458     list.add("a");
1459     list.add("b");
1460     Iterator<String> iterator = list.iterator();
1461     assertEquals("a", get(iterator, 0, "c"));
1462     assertTrue(iterator.hasNext());
1463   }
1464 
testGet_withDefault_atSize()1465   public void testGet_withDefault_atSize() {
1466     List<String> list = newArrayList();
1467     list.add("a");
1468     list.add("b");
1469     Iterator<String> iterator = list.iterator();
1470     assertEquals("c", get(iterator, 2, "c"));
1471     assertFalse(iterator.hasNext());
1472   }
1473 
testGet_withDefault_pastEnd()1474   public void testGet_withDefault_pastEnd() {
1475     List<String> list = newArrayList();
1476     list.add("a");
1477     list.add("b");
1478     Iterator<String> iterator = list.iterator();
1479     assertEquals("c", get(iterator, 3, "c"));
1480     assertFalse(iterator.hasNext());
1481   }
1482 
testGet_withDefault_negativeIndex()1483   public void testGet_withDefault_negativeIndex() {
1484     List<String> list = newArrayList();
1485     list.add("a");
1486     list.add("b");
1487     Iterator<String> iterator = list.iterator();
1488     try {
1489       get(iterator, -1, "c");
1490       fail();
1491     } catch (IndexOutOfBoundsException expected) {
1492       // pass
1493     }
1494     assertTrue(iterator.hasNext());
1495   }
1496 
testAdvance_basic()1497   public void testAdvance_basic() {
1498     List<String> list = newArrayList();
1499     list.add("a");
1500     list.add("b");
1501     Iterator<String> iterator = list.iterator();
1502     advance(iterator, 1);
1503     assertEquals("b", iterator.next());
1504   }
1505 
testAdvance_pastEnd()1506   public void testAdvance_pastEnd() {
1507     List<String> list = newArrayList();
1508     list.add("a");
1509     list.add("b");
1510     Iterator<String> iterator = list.iterator();
1511     advance(iterator, 5);
1512     assertFalse(iterator.hasNext());
1513   }
1514 
testAdvance_illegalArgument()1515   public void testAdvance_illegalArgument() {
1516     List<String> list = newArrayList("a", "b", "c");
1517     Iterator<String> iterator = list.iterator();
1518     try {
1519       advance(iterator, -1);
1520       fail();
1521     } catch (IllegalArgumentException expected) {
1522     }
1523   }
1524 
testFrequency()1525   public void testFrequency() {
1526     List<String> list = newArrayList("a", null, "b", null, "a", null);
1527     assertEquals(2, Iterators.frequency(list.iterator(), "a"));
1528     assertEquals(1, Iterators.frequency(list.iterator(), "b"));
1529     assertEquals(0, Iterators.frequency(list.iterator(), "c"));
1530     assertEquals(0, Iterators.frequency(list.iterator(), 4.2));
1531     assertEquals(3, Iterators.frequency(list.iterator(), null));
1532   }
1533 
1534   @GwtIncompatible // slow (~4s)
testSingletonIterator()1535   public void testSingletonIterator() {
1536     new IteratorTester<Integer>(
1537         3, UNMODIFIABLE, singleton(1), IteratorTester.KnownOrder.KNOWN_ORDER) {
1538       @Override
1539       protected Iterator<Integer> newTargetIterator() {
1540         return Iterators.singletonIterator(1);
1541       }
1542     }.test();
1543   }
1544 
testRemoveAll()1545   public void testRemoveAll() {
1546     List<String> list = newArrayList("a", "b", "c", "d", "e");
1547     assertTrue(Iterators.removeAll(list.iterator(), newArrayList("b", "d", "f")));
1548     assertEquals(newArrayList("a", "c", "e"), list);
1549     assertFalse(Iterators.removeAll(list.iterator(), newArrayList("x", "y", "z")));
1550     assertEquals(newArrayList("a", "c", "e"), list);
1551   }
1552 
testRemoveIf()1553   public void testRemoveIf() {
1554     List<String> list = newArrayList("a", "b", "c", "d", "e");
1555     assertTrue(
1556         Iterators.removeIf(
1557             list.iterator(),
1558             new Predicate<String>() {
1559               @Override
1560               public boolean apply(String s) {
1561                 return s.equals("b") || s.equals("d") || s.equals("f");
1562               }
1563             }));
1564     assertEquals(newArrayList("a", "c", "e"), list);
1565     assertFalse(
1566         Iterators.removeIf(
1567             list.iterator(),
1568             new Predicate<String>() {
1569               @Override
1570               public boolean apply(String s) {
1571                 return s.equals("x") || s.equals("y") || s.equals("z");
1572               }
1573             }));
1574     assertEquals(newArrayList("a", "c", "e"), list);
1575   }
1576 
testRetainAll()1577   public void testRetainAll() {
1578     List<String> list = newArrayList("a", "b", "c", "d", "e");
1579     assertTrue(Iterators.retainAll(list.iterator(), newArrayList("b", "d", "f")));
1580     assertEquals(newArrayList("b", "d"), list);
1581     assertFalse(Iterators.retainAll(list.iterator(), newArrayList("b", "e", "d")));
1582     assertEquals(newArrayList("b", "d"), list);
1583   }
1584 
1585   @GwtIncompatible // ListTestSuiteBuilder
testsForRemoveAllAndRetainAll()1586   private static Test testsForRemoveAllAndRetainAll() {
1587     return ListTestSuiteBuilder.using(
1588             new TestStringListGenerator() {
1589               @Override
1590               public List<String> create(final String[] elements) {
1591                 final List<String> delegate = newArrayList(elements);
1592                 return new ForwardingList<String>() {
1593                   @Override
1594                   protected List<String> delegate() {
1595                     return delegate;
1596                   }
1597 
1598                   @Override
1599                   public boolean removeAll(Collection<?> c) {
1600                     return Iterators.removeAll(iterator(), c);
1601                   }
1602 
1603                   @Override
1604                   public boolean retainAll(Collection<?> c) {
1605                     return Iterators.retainAll(iterator(), c);
1606                   }
1607                 };
1608               }
1609             })
1610         .named("ArrayList with Iterators.removeAll and retainAll")
1611         .withFeatures(
1612             ListFeature.GENERAL_PURPOSE, CollectionFeature.ALLOWS_NULL_VALUES, CollectionSize.ANY)
1613         .createTestSuite();
1614   }
1615 
1616   public void testConsumingIterator() {
1617     // Test data
1618     List<String> list = Lists.newArrayList("a", "b");
1619 
1620     // Test & Verify
1621     Iterator<String> consumingIterator = Iterators.consumingIterator(list.iterator());
1622 
1623     assertEquals("Iterators.consumingIterator(...)", consumingIterator.toString());
1624 
1625     assertThat(list).containsExactly("a", "b").inOrder();
1626 
1627     assertTrue(consumingIterator.hasNext());
1628     assertThat(list).containsExactly("a", "b").inOrder();
1629     assertEquals("a", consumingIterator.next());
1630     assertThat(list).contains("b");
1631 
1632     assertTrue(consumingIterator.hasNext());
1633     assertEquals("b", consumingIterator.next());
1634     assertThat(list).isEmpty();
1635 
1636     assertFalse(consumingIterator.hasNext());
1637   }
1638 
1639   @GwtIncompatible // ?
1640   // TODO: Figure out why this is failing in GWT.
1641   public void testConsumingIterator_duelingIterators() {
1642     // Test data
1643     List<String> list = Lists.newArrayList("a", "b");
1644 
1645     // Test & Verify
1646     Iterator<String> i1 = Iterators.consumingIterator(list.iterator());
1647     Iterator<String> i2 = Iterators.consumingIterator(list.iterator());
1648 
1649     i1.next();
1650     try {
1651       i2.next();
1652       fail("Concurrent modification should throw an exception.");
1653     } catch (ConcurrentModificationException cme) {
1654       // Pass
1655     }
1656   }
1657 
1658   public void testIndexOf_consumedData() {
1659     Iterator<String> iterator = Lists.newArrayList("manny", "mo", "jack").iterator();
1660     assertEquals(1, Iterators.indexOf(iterator, Predicates.equalTo("mo")));
1661     assertEquals("jack", iterator.next());
1662     assertFalse(iterator.hasNext());
1663   }
1664 
1665   public void testIndexOf_consumedDataWithDuplicates() {
1666     Iterator<String> iterator = Lists.newArrayList("manny", "mo", "mo", "jack").iterator();
1667     assertEquals(1, Iterators.indexOf(iterator, Predicates.equalTo("mo")));
1668     assertEquals("mo", iterator.next());
1669     assertEquals("jack", iterator.next());
1670     assertFalse(iterator.hasNext());
1671   }
1672 
1673   public void testIndexOf_consumedDataNoMatch() {
1674     Iterator<String> iterator = Lists.newArrayList("manny", "mo", "mo", "jack").iterator();
1675     assertEquals(-1, Iterators.indexOf(iterator, Predicates.equalTo("bob")));
1676     assertFalse(iterator.hasNext());
1677   }
1678 
1679   @SuppressWarnings("deprecation")
1680   public void testUnmodifiableIteratorShortCircuit() {
1681     Iterator<String> mod = Lists.newArrayList("a", "b", "c").iterator();
1682     UnmodifiableIterator<String> unmod = Iterators.unmodifiableIterator(mod);
1683     assertNotSame(mod, unmod);
1684     assertSame(unmod, Iterators.unmodifiableIterator(unmod));
1685     assertSame(unmod, Iterators.unmodifiableIterator((Iterator<String>) unmod));
1686   }
1687 
1688   @SuppressWarnings("deprecation")
1689   public void testPeekingIteratorShortCircuit() {
1690     Iterator<String> nonpeek = Lists.newArrayList("a", "b", "c").iterator();
1691     PeekingIterator<String> peek = Iterators.peekingIterator(nonpeek);
1692     assertNotSame(peek, nonpeek);
1693     assertSame(peek, Iterators.peekingIterator(peek));
1694     assertSame(peek, Iterators.peekingIterator((Iterator<String>) peek));
1695   }
1696 }
1697