CollectionIteratorTester.java revision 7dd252788645e940eada959bdde927426e2531c9
1/*
2 * Copyright (C) 2008 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.testing.testers;
18
19import static com.google.common.collect.testing.IteratorFeature.MODIFIABLE;
20import static com.google.common.collect.testing.IteratorFeature.UNMODIFIABLE;
21import static com.google.common.collect.testing.features.CollectionFeature.KNOWN_ORDER;
22import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_REMOVE;
23
24import com.google.common.annotations.GwtCompatible;
25import com.google.common.annotations.GwtIncompatible;
26import com.google.common.collect.testing.AbstractCollectionTester;
27import com.google.common.collect.testing.Helpers;
28import com.google.common.collect.testing.IteratorFeature;
29import com.google.common.collect.testing.IteratorTester;
30import com.google.common.collect.testing.features.CollectionFeature;
31
32import java.lang.reflect.Method;
33import java.util.ArrayList;
34import java.util.Arrays;
35import java.util.Iterator;
36import java.util.List;
37import java.util.NoSuchElementException;
38import java.util.Set;
39import java.util.concurrent.CopyOnWriteArrayList;
40import java.util.concurrent.CopyOnWriteArraySet;
41
42/**
43 * A generic JUnit test which tests {@code iterator} operations on a collection.
44 * Can't be invoked directly; please see
45 * {@link com.google.common.collect.testing.CollectionTestSuiteBuilder}.
46 *
47 * <p>This class is GWT compatible.
48 *
49 * @author Chris Povirk
50 */
51@GwtCompatible(emulated = true)
52public class CollectionIteratorTester<E> extends AbstractCollectionTester<E> {
53  public void testIterator() {
54    List<E> iteratorElements = new ArrayList<E>();
55    for (E element : collection) { // uses iterator()
56      iteratorElements.add(element);
57    }
58    Helpers.assertEqualIgnoringOrder(
59        Arrays.asList(createSamplesArray()), iteratorElements);
60  }
61
62  @CollectionFeature.Require(KNOWN_ORDER)
63  public void testIterationOrdering() {
64    List<E> iteratorElements = new ArrayList<E>();
65    for (E element : collection) { // uses iterator()
66      iteratorElements.add(element);
67    }
68    List<E> expected = Helpers.copyToList(getOrderedElements());
69    assertEquals("Different ordered iteration", expected, iteratorElements);
70  }
71
72  // TODO: switch to DerivedIteratorTestSuiteBuilder
73
74  @CollectionFeature.Require({KNOWN_ORDER, SUPPORTS_REMOVE})
75  public void testIterator_knownOrderRemoveSupported() {
76    runIteratorTest(MODIFIABLE, IteratorTester.KnownOrder.KNOWN_ORDER,
77        getOrderedElements());
78  }
79
80  @CollectionFeature.Require(value = KNOWN_ORDER, absent = SUPPORTS_REMOVE)
81  public void testIterator_knownOrderRemoveUnsupported() {
82    runIteratorTest(UNMODIFIABLE, IteratorTester.KnownOrder.KNOWN_ORDER,
83        getOrderedElements());
84  }
85
86  @CollectionFeature.Require(absent = KNOWN_ORDER, value = SUPPORTS_REMOVE)
87  public void testIterator_unknownOrderRemoveSupported() {
88    runIteratorTest(MODIFIABLE, IteratorTester.KnownOrder.UNKNOWN_ORDER,
89        getSampleElements());
90  }
91
92  @CollectionFeature.Require(absent = {KNOWN_ORDER, SUPPORTS_REMOVE})
93  public void testIterator_unknownOrderRemoveUnsupported() {
94    runIteratorTest(UNMODIFIABLE, IteratorTester.KnownOrder.UNKNOWN_ORDER,
95        getSampleElements());
96  }
97
98  private void runIteratorTest(Set<IteratorFeature> features,
99      IteratorTester.KnownOrder knownOrder, Iterable<E> elements) {
100    new IteratorTester<E>(Platform.collectionIteratorTesterNumIterations(), features, elements,
101        knownOrder) {
102      {
103        // TODO: don't set this universally
104        ignoreSunJavaBug6529795();
105      }
106
107      @Override protected Iterator<E> newTargetIterator() {
108        resetCollection();
109        return collection.iterator();
110      }
111
112      @Override protected void verify(List<E> elements) {
113        expectContents(elements);
114      }
115    }.test();
116  }
117
118  /**
119   * Returns the {@link Method} instance for
120   * {@link #testIterator_knownOrderRemoveSupported()} so that tests of
121   * {@link CopyOnWriteArraySet} and {@link CopyOnWriteArrayList} can suppress
122   * it with {@code FeatureSpecificTestSuiteBuilder.suppressing()} until <a
123   * href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6570575">Sun bug
124   * 6570575</a> is fixed.
125   */
126  @GwtIncompatible("reflection")
127  public static Method getIteratorKnownOrderRemoveSupportedMethod() {
128    return Helpers.getMethod(
129          CollectionIteratorTester.class, "testIterator_knownOrderRemoveSupported");
130  }
131
132  /**
133   * Returns the {@link Method} instance for
134   * {@link #testIterator_unknownOrderRemoveSupported()} so that tests of
135   * classes with unmodifiable iterators can suppress it.
136   */
137  @GwtIncompatible("reflection")
138  public static Method getIteratorUnknownOrderRemoveSupportedMethod() {
139    return Helpers.getMethod(
140        CollectionIteratorTester.class, "testIterator_unknownOrderRemoveSupported");
141  }
142
143  public void testIteratorNoSuchElementException() {
144    Iterator<E> iterator = collection.iterator();
145    while (iterator.hasNext()) {
146      iterator.next();
147    }
148
149    try {
150      iterator.next();
151      fail("iterator.next() should throw NoSuchElementException");
152    } catch (NoSuchElementException expected) {}
153  }
154
155  /**
156   * Returns the {@link Method} instance for
157   * {@link #testIterator_knownOrderRemoveUnsupported()} so that tests of
158   * {@code ArrayStack} can suppress it with
159   * {@code FeatureSpecificTestSuiteBuilder.suppressing()}. {@code ArrayStack}
160   * supports {@code remove()} on only the first element, and the iterator
161   * tester can't handle that.
162   */
163  @GwtIncompatible("reflection")
164  public static Method getIteratorKnownOrderRemoveUnsupportedMethod() {
165    return Helpers.getMethod(
166        CollectionIteratorTester.class, "testIterator_knownOrderRemoveUnsupported");
167  }
168}
169