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