001: /*
002: * Copyright 2001-2004 The Apache Software Foundation
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.apache.commons.collections.iterators;
017:
018: import java.util.ArrayList;
019: import java.util.Iterator;
020: import java.util.ListIterator;
021: import java.util.NoSuchElementException;
022:
023: /**
024: * Abstract class for testing the ListIterator interface.
025: * <p>
026: * This class provides a framework for testing an implementation of ListIterator.
027: * Concrete subclasses must provide the list iterator to be tested.
028: * They must also specify certain details of how the list iterator operates by
029: * overriding the supportsXxx() methods if necessary.
030: *
031: * @since Commons Collections 3.0
032: * @version $Revision: 155406 $ $Date: 2005-02-26 12:55:26 +0000 (Sat, 26 Feb 2005) $
033: *
034: * @author Rodney Waldhoff
035: * @author Stephen Colebourne
036: */
037: public abstract class AbstractTestListIterator extends
038: AbstractTestIterator {
039:
040: /**
041: * JUnit constructor.
042: *
043: * @param testName the test class name
044: */
045: public AbstractTestListIterator(String testName) {
046: super (testName);
047: }
048:
049: //-----------------------------------------------------------------------
050: /**
051: * Implement this method to return a list iterator over an empty collection.
052: *
053: * @return an empty iterator
054: */
055: public abstract ListIterator makeEmptyListIterator();
056:
057: /**
058: * Implement this method to return a list iterator over a collection with elements.
059: *
060: * @return a full iterator
061: */
062: public abstract ListIterator makeFullListIterator();
063:
064: /**
065: * Implements the abstract superclass method to return the list iterator.
066: *
067: * @return an empty iterator
068: */
069: public Iterator makeEmptyIterator() {
070: return makeEmptyListIterator();
071: }
072:
073: /**
074: * Implements the abstract superclass method to return the list iterator.
075: *
076: * @return a full iterator
077: */
078: public Iterator makeFullIterator() {
079: return makeFullListIterator();
080: }
081:
082: /**
083: * Whether or not we are testing an iterator that supports add().
084: * Default is true.
085: *
086: * @return true if Iterator supports add
087: */
088: public boolean supportsAdd() {
089: return true;
090: }
091:
092: /**
093: * Whether or not we are testing an iterator that supports set().
094: * Default is true.
095: *
096: * @return true if Iterator supports set
097: */
098: public boolean supportsSet() {
099: return true;
100: }
101:
102: /**
103: * The value to be used in the add and set tests.
104: * Default is null.
105: */
106: public Object addSetValue() {
107: return null;
108: }
109:
110: //-----------------------------------------------------------------------
111: /**
112: * Test that the empty list iterator contract is correct.
113: */
114: public void testEmptyListIteratorIsIndeedEmpty() {
115: if (supportsEmptyIterator() == false) {
116: return;
117: }
118:
119: ListIterator it = makeEmptyListIterator();
120:
121: assertEquals(false, it.hasNext());
122: assertEquals(0, it.nextIndex());
123: assertEquals(false, it.hasPrevious());
124: assertEquals(-1, it.previousIndex());
125:
126: // next() should throw a NoSuchElementException
127: try {
128: it.next();
129: fail("NoSuchElementException must be thrown from empty ListIterator");
130: } catch (NoSuchElementException e) {
131: }
132:
133: // previous() should throw a NoSuchElementException
134: try {
135: it.previous();
136: fail("NoSuchElementException must be thrown from empty ListIterator");
137: } catch (NoSuchElementException e) {
138: }
139: }
140:
141: /**
142: * Test navigation through the iterator.
143: */
144: public void testWalkForwardAndBack() {
145: ArrayList list = new ArrayList();
146: ListIterator it = makeFullListIterator();
147: while (it.hasNext()) {
148: list.add(it.next());
149: }
150:
151: // check state at end
152: assertEquals(false, it.hasNext());
153: assertEquals(true, it.hasPrevious());
154: try {
155: it.next();
156: fail("NoSuchElementException must be thrown from next at end of ListIterator");
157: } catch (NoSuchElementException e) {
158: }
159:
160: // loop back through comparing
161: for (int i = list.size() - 1; i >= 0; i--) {
162: assertEquals(i + 1, it.nextIndex());
163: assertEquals(i, it.previousIndex());
164:
165: Object obj = list.get(i);
166: assertEquals(obj, it.previous());
167: }
168:
169: // check state at start
170: assertEquals(true, it.hasNext());
171: assertEquals(false, it.hasPrevious());
172: try {
173: it.previous();
174: fail("NoSuchElementException must be thrown from previous at start of ListIterator");
175: } catch (NoSuchElementException e) {
176: }
177: }
178:
179: /**
180: * Test add behaviour.
181: */
182: public void testAdd() {
183: ListIterator it = makeFullListIterator();
184:
185: Object addValue = addSetValue();
186: if (supportsAdd() == false) {
187: // check for UnsupportedOperationException if not supported
188: try {
189: it.add(addValue);
190: } catch (UnsupportedOperationException ex) {
191: }
192: return;
193: }
194:
195: // add at start should be OK, added should be previous
196: it = makeFullListIterator();
197: it.add(addValue);
198: assertEquals(addValue, it.previous());
199:
200: // add at start should be OK, added should not be next
201: it = makeFullListIterator();
202: it.add(addValue);
203: assertTrue(addValue != it.next());
204:
205: // add in middle and at end should be OK
206: it = makeFullListIterator();
207: while (it.hasNext()) {
208: it.next();
209: it.add(addValue);
210: // check add OK
211: assertEquals(addValue, it.previous());
212: it.next();
213: }
214: }
215:
216: /**
217: * Test set behaviour.
218: */
219: public void testSet() {
220: ListIterator it = makeFullListIterator();
221:
222: if (supportsSet() == false) {
223: // check for UnsupportedOperationException if not supported
224: try {
225: it.set(addSetValue());
226: } catch (UnsupportedOperationException ex) {
227: }
228: return;
229: }
230:
231: // should throw IllegalStateException before next() called
232: try {
233: it.set(addSetValue());
234: fail();
235: } catch (IllegalStateException ex) {
236: }
237:
238: // set after next should be fine
239: it.next();
240: it.set(addSetValue());
241:
242: // repeated set calls should be fine
243: it.set(addSetValue());
244:
245: }
246:
247: public void testRemoveThenSet() {
248: ListIterator it = makeFullListIterator();
249: if (supportsRemove() && supportsSet()) {
250: it.next();
251: it.remove();
252: try {
253: it.set(addSetValue());
254: fail("IllegalStateException must be thrown from set after remove");
255: } catch (IllegalStateException e) {
256: }
257: }
258: }
259:
260: public void testAddThenSet() {
261: ListIterator it = makeFullListIterator();
262: // add then set
263: if (supportsAdd() && supportsSet()) {
264: it.next();
265: it.add(addSetValue());
266: try {
267: it.set(addSetValue());
268: fail("IllegalStateException must be thrown from set after add");
269: } catch (IllegalStateException e) {
270: }
271: }
272: }
273:
274: /**
275: * Test remove after add behaviour.
276: */
277: public void testAddThenRemove() {
278: ListIterator it = makeFullListIterator();
279:
280: // add then remove
281: if (supportsAdd() && supportsRemove()) {
282: it.next();
283: it.add(addSetValue());
284: try {
285: it.remove();
286: fail("IllegalStateException must be thrown from remove after add");
287: } catch (IllegalStateException e) {
288: }
289: }
290: }
291:
292: }
|