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