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