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