1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.commons.collections.iterators;
18
19 import java.util.Iterator;
20 import java.util.NoSuchElementException;
21
22 import org.apache.commons.collections.AbstractTestObject;
23
24 /**
25 * Abstract class for testing the Iterator interface.
26 * <p>
27 * This class provides a framework for testing an implementation of Iterator.
28 * Concrete subclasses must provide the iterator to be tested.
29 * They must also specify certain details of how the iterator operates by
30 * overriding the supportsXxx() methods if necessary.
31 *
32 * @since Commons Collections 3.0
33 * @version $Revision: 646780 $ $Date: 2008-04-10 13:48:07 +0100 (Thu, 10 Apr 2008) $
34 *
35 * @author Morgan Delagrange
36 * @author Stephen Colebourne
37 */
38 public abstract class AbstractTestIterator extends AbstractTestObject {
39
40 /**
41 * JUnit constructor.
42 *
43 * @param testName the test class name
44 */
45 public AbstractTestIterator(String testName) {
46 super(testName);
47 }
48
49 //-----------------------------------------------------------------------
50 /**
51 * Implement this method to return an iterator over an empty collection.
52 *
53 * @return an empty iterator
54 */
55 public abstract Iterator makeEmptyIterator();
56
57 /**
58 * Implement this method to return an iterator over a collection with elements.
59 *
60 * @return a full iterator
61 */
62 public abstract Iterator makeFullIterator();
63
64 /**
65 * Implements the abstract superclass method to return the full iterator.
66 *
67 * @return a full iterator
68 */
69 public Object makeObject() {
70 return makeFullIterator();
71 }
72
73 /**
74 * Whether or not we are testing an iterator that can be empty.
75 * Default is true.
76 *
77 * @return true if Iterator can be empty
78 */
79 public boolean supportsEmptyIterator() {
80 return true;
81 }
82
83 /**
84 * Whether or not we are testing an iterator that can contain elements.
85 * Default is true.
86 *
87 * @return true if Iterator can be full
88 */
89 public boolean supportsFullIterator() {
90 return true;
91 }
92
93 /**
94 * Whether or not we are testing an iterator that supports remove().
95 * Default is true.
96 *
97 * @return true if Iterator supports remove
98 */
99 public boolean supportsRemove() {
100 return true;
101 }
102
103 /**
104 * Allows subclasses to add complex cross verification
105 */
106 public void verify() {
107 // do nothing
108 }
109
110 //-----------------------------------------------------------------------
111 /**
112 * Test the empty iterator.
113 */
114 public void testEmptyIterator() {
115 if (supportsEmptyIterator() == false) {
116 return;
117 }
118
119 Iterator it = makeEmptyIterator();
120
121 // hasNext() should return false
122 assertEquals("hasNext() should return false for empty iterators", false, it.hasNext());
123
124 // next() should throw a NoSuchElementException
125 try {
126 it.next();
127 fail("NoSuchElementException must be thrown when Iterator is exhausted");
128 } catch (NoSuchElementException e) {
129 }
130 verify();
131
132 assertNotNull(it.toString());
133 }
134
135 /**
136 * Test normal iteration behaviour.
137 */
138 public void testFullIterator() {
139 if (supportsFullIterator() == false) {
140 return;
141 }
142
143 Iterator it = makeFullIterator();
144
145 // hasNext() must be true (ensure makeFullIterator is correct!)
146 assertEquals("hasNext() should return true for at least one element", true, it.hasNext());
147
148 // next() must not throw exception (ensure makeFullIterator is correct!)
149 try {
150 it.next();
151 } catch (NoSuchElementException e) {
152 fail("Full iterators must have at least one element");
153 }
154
155 // iterate through
156 while (it.hasNext()) {
157 it.next();
158 verify();
159 }
160
161 // next() must throw NoSuchElementException now
162 try {
163 it.next();
164 fail("NoSuchElementException must be thrown when Iterator is exhausted");
165 } catch (NoSuchElementException e) {
166 }
167
168 assertNotNull(it.toString());
169 }
170
171 /**
172 * Test remove behaviour.
173 */
174 public void testRemove() {
175 Iterator it = makeFullIterator();
176
177 if (supportsRemove() == false) {
178 // check for UnsupportedOperationException if not supported
179 try {
180 it.remove();
181 } catch (UnsupportedOperationException ex) {}
182 return;
183 }
184
185 // should throw IllegalStateException before next() called
186 try {
187 it.remove();
188 fail();
189 } catch (IllegalStateException ex) {}
190 verify();
191
192 // remove after next should be fine
193 it.next();
194 it.remove();
195
196 // should throw IllegalStateException for second remove()
197 try {
198 it.remove();
199 fail();
200 } catch (IllegalStateException ex) {}
201 }
202
203 }