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.HashSet;
019: import java.util.Iterator;
020: import java.util.Map;
021: import java.util.NoSuchElementException;
022: import java.util.Set;
023:
024: import org.apache.commons.collections.MapIterator;
025:
026: /**
027: * Abstract class for testing the MapIterator interface.
028: * <p>
029: * This class provides a framework for testing an implementation of MapIterator.
030: * Concrete subclasses must provide the list iterator to be tested.
031: * They must also specify certain details of how the list iterator operates by
032: * overriding the supportsXxx() methods if necessary.
033: *
034: * @since Commons Collections 3.0
035: * @version $Revision: 155406 $ $Date: 2005-02-26 12:55:26 +0000 (Sat, 26 Feb 2005) $
036: *
037: * @author Stephen Colebourne
038: */
039: public abstract class AbstractTestMapIterator extends
040: AbstractTestIterator {
041:
042: /**
043: * JUnit constructor.
044: *
045: * @param testName the test class name
046: */
047: public AbstractTestMapIterator(String testName) {
048: super (testName);
049: }
050:
051: //-----------------------------------------------------------------------
052: /**
053: * Implement this method to return a map iterator over an empty map.
054: *
055: * @return an empty iterator
056: */
057: public abstract MapIterator makeEmptyMapIterator();
058:
059: /**
060: * Implement this method to return a map iterator over a map with elements.
061: *
062: * @return a full iterator
063: */
064: public abstract MapIterator makeFullMapIterator();
065:
066: /**
067: * Implement this method to return the map which contains the same data as the
068: * iterator.
069: *
070: * @return a full map which can be updated
071: */
072: public abstract Map getMap();
073:
074: /**
075: * Implement this method to return the confirmed map which contains the same
076: * data as the iterator.
077: *
078: * @return a full map which can be updated
079: */
080: public abstract Map getConfirmedMap();
081:
082: /**
083: * Implements the abstract superclass method to return the list iterator.
084: *
085: * @return an empty iterator
086: */
087: public final Iterator makeEmptyIterator() {
088: return makeEmptyMapIterator();
089: }
090:
091: /**
092: * Implements the abstract superclass method to return the list iterator.
093: *
094: * @return a full iterator
095: */
096: public final Iterator makeFullIterator() {
097: return makeFullMapIterator();
098: }
099:
100: /**
101: * Whether or not we are testing an iterator that supports setValue().
102: * Default is true.
103: *
104: * @return true if Iterator supports set
105: */
106: public boolean supportsSetValue() {
107: return true;
108: }
109:
110: /**
111: * Whether the get operation on the map structurally modifies the map,
112: * such as with LRUMap. Default is false.
113: *
114: * @return true if the get method structurally modifies the map
115: */
116: public boolean isGetStructuralModify() {
117: return false;
118: }
119:
120: /**
121: * The values to be used in the add and set tests.
122: * Default is two strings.
123: */
124: public Object[] addSetValues() {
125: return new Object[] { "A", "B" };
126: }
127:
128: //-----------------------------------------------------------------------
129: /**
130: * Test that the empty list iterator contract is correct.
131: */
132: public void testEmptyMapIterator() {
133: if (supportsEmptyIterator() == false) {
134: return;
135: }
136:
137: MapIterator it = makeEmptyMapIterator();
138: Map map = getMap();
139: assertEquals(false, it.hasNext());
140:
141: // next() should throw a NoSuchElementException
142: try {
143: it.next();
144: fail();
145: } catch (NoSuchElementException ex) {
146: }
147:
148: // getKey() should throw an IllegalStateException
149: try {
150: it.getKey();
151: fail();
152: } catch (IllegalStateException ex) {
153: }
154:
155: // getValue() should throw an IllegalStateException
156: try {
157: it.getValue();
158: fail();
159: } catch (IllegalStateException ex) {
160: }
161:
162: if (supportsSetValue() == false) {
163: // setValue() should throw an UnsupportedOperationException/IllegalStateException
164: try {
165: it.setValue(addSetValues()[0]);
166: fail();
167: } catch (UnsupportedOperationException ex) {
168: } catch (IllegalStateException ex) {
169: }
170: } else {
171: // setValue() should throw an IllegalStateException
172: try {
173: it.setValue(addSetValues()[0]);
174: fail();
175: } catch (IllegalStateException ex) {
176: }
177: }
178: }
179:
180: //-----------------------------------------------------------------------
181: /**
182: * Test that the full list iterator contract is correct.
183: */
184: public void testFullMapIterator() {
185: if (supportsFullIterator() == false) {
186: return;
187: }
188:
189: MapIterator it = makeFullMapIterator();
190: Map map = getMap();
191: assertEquals(true, it.hasNext());
192:
193: assertEquals(true, it.hasNext());
194: Set set = new HashSet();
195: while (it.hasNext()) {
196: // getKey
197: Object key = it.next();
198: assertSame("it.next() should equals getKey()", key, it
199: .getKey());
200: assertTrue("Key must be in map", map.containsKey(key));
201: assertTrue("Key must be unique", set.add(key));
202:
203: // getValue
204: Object value = it.getValue();
205: if (isGetStructuralModify() == false) {
206: assertSame("Value must be mapped to key", map.get(key),
207: value);
208: }
209: assertTrue("Value must be in map", map.containsValue(value));
210:
211: verify();
212: }
213: }
214:
215: //-----------------------------------------------------------------------
216: public void testMapIteratorSet() {
217: if (supportsFullIterator() == false) {
218: return;
219: }
220:
221: Object newValue = addSetValues()[0];
222: Object newValue2 = (addSetValues().length == 1 ? addSetValues()[0]
223: : addSetValues()[1]);
224: MapIterator it = makeFullMapIterator();
225: Map map = getMap();
226: Map confirmed = getConfirmedMap();
227: assertEquals(true, it.hasNext());
228: Object key = it.next();
229: Object value = it.getValue();
230:
231: if (supportsSetValue() == false) {
232: try {
233: it.setValue(newValue);
234: fail();
235: } catch (UnsupportedOperationException ex) {
236: }
237: return;
238: }
239: Object old = it.setValue(newValue);
240: confirmed.put(key, newValue);
241: assertSame("Key must not change after setValue", key, it
242: .getKey());
243: assertSame("Value must be changed after setValue", newValue, it
244: .getValue());
245: assertSame("setValue must return old value", value, old);
246: assertEquals("Map must contain key", true, map.containsKey(key));
247: // test against confirmed, as map may contain value twice
248: assertEquals("Map must not contain old value", confirmed
249: .containsValue(old), map.containsValue(old));
250: assertEquals("Map must contain new value", true, map
251: .containsValue(newValue));
252: verify();
253:
254: it.setValue(newValue); // same value - should be OK
255: confirmed.put(key, newValue);
256: assertSame("Key must not change after setValue", key, it
257: .getKey());
258: assertSame("Value must be changed after setValue", newValue, it
259: .getValue());
260: verify();
261:
262: it.setValue(newValue2); // new value
263: confirmed.put(key, newValue2);
264: assertSame("Key must not change after setValue", key, it
265: .getKey());
266: assertSame("Value must be changed after setValue", newValue2,
267: it.getValue());
268: verify();
269: }
270:
271: //-----------------------------------------------------------------------
272: public void testRemove() { // override
273: MapIterator it = makeFullMapIterator();
274: Map map = getMap();
275: Map confirmed = getConfirmedMap();
276: assertEquals(true, it.hasNext());
277: Object key = it.next();
278:
279: if (supportsRemove() == false) {
280: try {
281: it.remove();
282: fail();
283: } catch (UnsupportedOperationException ex) {
284: }
285: return;
286: }
287:
288: it.remove();
289: confirmed.remove(key);
290: assertEquals(false, map.containsKey(key));
291: verify();
292:
293: try {
294: it.remove(); // second remove fails
295: } catch (IllegalStateException ex) {
296: }
297: verify();
298: }
299:
300: //-----------------------------------------------------------------------
301: public void testMapIteratorSetRemoveSet() {
302: if (supportsSetValue() == false || supportsRemove() == false) {
303: return;
304: }
305: Object newValue = addSetValues()[0];
306: MapIterator it = makeFullMapIterator();
307: Map map = getMap();
308: Map confirmed = getConfirmedMap();
309:
310: assertEquals(true, it.hasNext());
311: Object key = it.next();
312:
313: it.setValue(newValue);
314: it.remove();
315: confirmed.remove(key);
316: verify();
317:
318: try {
319: it.setValue(newValue);
320: fail();
321: } catch (IllegalStateException ex) {
322: }
323: verify();
324: }
325:
326: //-----------------------------------------------------------------------
327: public void testMapIteratorRemoveGetKey() {
328: if (supportsRemove() == false) {
329: return;
330: }
331: MapIterator it = makeFullMapIterator();
332: Map map = getMap();
333: Map confirmed = getConfirmedMap();
334:
335: assertEquals(true, it.hasNext());
336: Object key = it.next();
337:
338: it.remove();
339: confirmed.remove(key);
340: verify();
341:
342: try {
343: it.getKey();
344: fail();
345: } catch (IllegalStateException ex) {
346: }
347: verify();
348: }
349:
350: //-----------------------------------------------------------------------
351: public void testMapIteratorRemoveGetValue() {
352: if (supportsRemove() == false) {
353: return;
354: }
355: MapIterator it = makeFullMapIterator();
356: Map map = getMap();
357: Map confirmed = getConfirmedMap();
358:
359: assertEquals(true, it.hasNext());
360: Object key = it.next();
361:
362: it.remove();
363: confirmed.remove(key);
364: verify();
365:
366: try {
367: it.getValue();
368: fail();
369: } catch (IllegalStateException ex) {
370: }
371: verify();
372: }
373:
374: }
|