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.List;
020: import java.util.ListIterator;
021: import java.util.Random;
022:
023: import junit.framework.Test;
024: import junit.framework.TestCase;
025: import junit.framework.TestSuite;
026:
027: import org.apache.commons.collections.Predicate;
028:
029: /**
030: * Tests the FilterListIterator class.
031: *
032: * @version $Revision: 155406 $ $Date: 2005-02-26 12:55:26 +0000 (Sat, 26 Feb 2005) $
033: *
034: * @author Rodney Waldhoff
035: */
036: public class TestFilterListIterator extends TestCase {
037: public TestFilterListIterator(String testName) {
038: super (testName);
039: }
040:
041: public static Test suite() {
042: return new TestSuite(TestFilterListIterator.class);
043: }
044:
045: public static void main(String args[]) {
046: String[] testCaseName = { TestFilterListIterator.class
047: .getName() };
048: junit.textui.TestRunner.main(testCaseName);
049: }
050:
051: private ArrayList list = null;
052: private ArrayList odds = null;
053: private ArrayList evens = null;
054: private ArrayList threes = null;
055: private ArrayList fours = null;
056: private ArrayList sixes = null;
057: private Predicate truePred = null;
058: private Predicate falsePred = null;
059: private Predicate evenPred = null;
060: private Predicate oddPred = null;
061: private Predicate threePred = null;
062: private Predicate fourPred = null;
063: private Random random = new Random();
064:
065: public void setUp() {
066: list = new ArrayList();
067: odds = new ArrayList();
068: evens = new ArrayList();
069: threes = new ArrayList();
070: fours = new ArrayList();
071: sixes = new ArrayList();
072: for (int i = 0; i < 20; i++) {
073: list.add(new Integer(i));
074: if (i % 2 == 0) {
075: evens.add(new Integer(i));
076: }
077: if (i % 2 == 1) {
078: odds.add(new Integer(i));
079: }
080: if (i % 3 == 0) {
081: threes.add(new Integer(i));
082: }
083: if (i % 4 == 0) {
084: fours.add(new Integer(i));
085: }
086: if (i % 6 == 0) {
087: sixes.add(new Integer(i));
088: }
089: }
090:
091: truePred = new Predicate() {
092: public boolean evaluate(Object x) {
093: return true;
094: }
095: };
096:
097: falsePred = new Predicate() {
098: public boolean evaluate(Object x) {
099: return true;
100: }
101: };
102:
103: evenPred = new Predicate() {
104: public boolean evaluate(Object x) {
105: return (((Integer) x).intValue() % 2 == 0);
106: }
107: };
108:
109: oddPred = new Predicate() {
110: public boolean evaluate(Object x) {
111: return (((Integer) x).intValue() % 2 == 1);
112: }
113: };
114:
115: threePred = new Predicate() {
116: public boolean evaluate(Object x) {
117: return (((Integer) x).intValue() % 3 == 0);
118: }
119: };
120:
121: fourPred = new Predicate() {
122: public boolean evaluate(Object x) {
123: return (((Integer) x).intValue() % 4 == 0);
124: }
125: };
126:
127: }
128:
129: public void tearDown() throws Exception {
130: list = null;
131: odds = null;
132: evens = null;
133: threes = null;
134: fours = null;
135: sixes = null;
136: truePred = null;
137: falsePred = null;
138: evenPred = null;
139: oddPred = null;
140: threePred = null;
141: fourPred = null;
142: }
143:
144: public void testWalkLists() {
145: // this just confirms that our walkLists method works OK
146: walkLists(list, list.listIterator());
147: }
148:
149: public void testManual() {
150: // do this one "by hand" as a sanity check
151: FilterListIterator filtered = new FilterListIterator(list
152: .listIterator(), threePred);
153:
154: assertEquals(new Integer(0), filtered.next());
155: assertEquals(new Integer(3), filtered.next());
156: assertEquals(new Integer(6), filtered.next());
157: assertEquals(new Integer(9), filtered.next());
158: assertEquals(new Integer(12), filtered.next());
159: assertEquals(new Integer(15), filtered.next());
160: assertEquals(new Integer(18), filtered.next());
161:
162: assertEquals(new Integer(18), filtered.previous());
163: assertEquals(new Integer(15), filtered.previous());
164: assertEquals(new Integer(12), filtered.previous());
165: assertEquals(new Integer(9), filtered.previous());
166: assertEquals(new Integer(6), filtered.previous());
167: assertEquals(new Integer(3), filtered.previous());
168: assertEquals(new Integer(0), filtered.previous());
169:
170: assertTrue(!filtered.hasPrevious());
171:
172: assertEquals(new Integer(0), filtered.next());
173: assertEquals(new Integer(3), filtered.next());
174: assertEquals(new Integer(6), filtered.next());
175: assertEquals(new Integer(9), filtered.next());
176: assertEquals(new Integer(12), filtered.next());
177: assertEquals(new Integer(15), filtered.next());
178: assertEquals(new Integer(18), filtered.next());
179:
180: assertTrue(!filtered.hasNext());
181:
182: assertEquals(new Integer(18), filtered.previous());
183: assertEquals(new Integer(15), filtered.previous());
184: assertEquals(new Integer(12), filtered.previous());
185: assertEquals(new Integer(9), filtered.previous());
186: assertEquals(new Integer(6), filtered.previous());
187: assertEquals(new Integer(3), filtered.previous());
188: assertEquals(new Integer(0), filtered.previous());
189:
190: assertEquals(new Integer(0), filtered.next());
191: assertEquals(new Integer(0), filtered.previous());
192: assertEquals(new Integer(0), filtered.next());
193:
194: assertEquals(new Integer(3), filtered.next());
195: assertEquals(new Integer(6), filtered.next());
196: assertEquals(new Integer(6), filtered.previous());
197: assertEquals(new Integer(3), filtered.previous());
198: assertEquals(new Integer(3), filtered.next());
199: assertEquals(new Integer(6), filtered.next());
200:
201: assertEquals(new Integer(9), filtered.next());
202: assertEquals(new Integer(12), filtered.next());
203: assertEquals(new Integer(15), filtered.next());
204: assertEquals(new Integer(15), filtered.previous());
205: assertEquals(new Integer(12), filtered.previous());
206: assertEquals(new Integer(9), filtered.previous());
207:
208: }
209:
210: public void testTruePredicate() {
211: FilterListIterator filtered = new FilterListIterator(list
212: .listIterator(), truePred);
213: walkLists(list, filtered);
214: }
215:
216: public void testFalsePredicate() {
217: FilterListIterator filtered = new FilterListIterator(list
218: .listIterator(), falsePred);
219: walkLists(new ArrayList(), filtered);
220: }
221:
222: public void testEvens() {
223: FilterListIterator filtered = new FilterListIterator(list
224: .listIterator(), evenPred);
225: walkLists(evens, filtered);
226: }
227:
228: public void testOdds() {
229: FilterListIterator filtered = new FilterListIterator(list
230: .listIterator(), oddPred);
231: walkLists(odds, filtered);
232: }
233:
234: public void testThrees() {
235: FilterListIterator filtered = new FilterListIterator(list
236: .listIterator(), threePred);
237: walkLists(threes, filtered);
238: }
239:
240: public void testFours() {
241: FilterListIterator filtered = new FilterListIterator(list
242: .listIterator(), fourPred);
243: walkLists(fours, filtered);
244: }
245:
246: public void testNestedSixes() {
247: FilterListIterator filtered = new FilterListIterator(
248: new FilterListIterator(list.listIterator(), threePred),
249: evenPred);
250: walkLists(sixes, filtered);
251: }
252:
253: public void testNestedSixes2() {
254: FilterListIterator filtered = new FilterListIterator(
255: new FilterListIterator(list.listIterator(), evenPred),
256: threePred);
257: walkLists(sixes, filtered);
258: }
259:
260: public void testNestedSixes3() {
261: FilterListIterator filtered = new FilterListIterator(
262: new FilterListIterator(list.listIterator(), threePred),
263: evenPred);
264: walkLists(sixes, new FilterListIterator(filtered, truePred));
265: }
266:
267: public void testNextChangesPrevious() {
268: {
269: FilterListIterator filtered = new FilterListIterator(list
270: .listIterator(), threePred);
271: nextNextPrevious(threes.listIterator(), filtered);
272: }
273:
274: {
275: FilterListIterator filtered = new FilterListIterator(list
276: .listIterator(), truePred);
277: nextNextPrevious(list.listIterator(), filtered);
278: }
279: }
280:
281: public void testPreviousChangesNext() {
282: {
283: FilterListIterator filtered = new FilterListIterator(list
284: .listIterator(), threePred);
285: ListIterator expected = threes.listIterator();
286: walkForward(expected, filtered);
287: previousPreviousNext(expected, filtered);
288: }
289: {
290: FilterListIterator filtered = new FilterListIterator(list
291: .listIterator(), truePred);
292: ListIterator expected = list.listIterator();
293: walkForward(expected, filtered);
294: previousPreviousNext(expected, filtered);
295: }
296: }
297:
298: public void testFailingHasNextBug() {
299: FilterListIterator filtered = new FilterListIterator(list
300: .listIterator(), fourPred);
301: ListIterator expected = fours.listIterator();
302: while (expected.hasNext()) {
303: expected.next();
304: filtered.next();
305: }
306: assertTrue(filtered.hasPrevious());
307: assertTrue(!filtered.hasNext());
308: assertEquals(expected.previous(), filtered.previous());
309: }
310:
311: // Utilities
312:
313: private void walkForward(ListIterator expected, ListIterator testing) {
314: while (expected.hasNext()) {
315: assertEquals(expected.nextIndex(), testing.nextIndex());
316: assertEquals(expected.previousIndex(), testing
317: .previousIndex());
318: assertTrue(testing.hasNext());
319: assertEquals(expected.next(), testing.next());
320: }
321: }
322:
323: private void walkBackward(ListIterator expected,
324: ListIterator testing) {
325: while (expected.hasPrevious()) {
326: assertEquals(expected.nextIndex(), testing.nextIndex());
327: assertEquals(expected.previousIndex(), testing
328: .previousIndex());
329: assertTrue(testing.hasPrevious());
330: assertEquals(expected.previous(), testing.previous());
331: }
332: }
333:
334: private void nextNextPrevious(ListIterator expected,
335: ListIterator testing) {
336: // calls to next() should change the value returned by previous()
337: // even after previous() has been set by a call to hasPrevious()
338: assertEquals(expected.next(), testing.next());
339: assertEquals(expected.hasPrevious(), testing.hasPrevious());
340: Object expecteda = expected.next();
341: Object testinga = testing.next();
342: assertEquals(expecteda, testinga);
343: Object expectedb = expected.previous();
344: Object testingb = testing.previous();
345: assertEquals(expecteda, expectedb);
346: assertEquals(testinga, testingb);
347: }
348:
349: private void previousPreviousNext(ListIterator expected,
350: ListIterator testing) {
351: // calls to previous() should change the value returned by next()
352: // even after next() has been set by a call to hasNext()
353: assertEquals(expected.previous(), testing.previous());
354: assertEquals(expected.hasNext(), testing.hasNext());
355: Object expecteda = expected.previous();
356: Object testinga = testing.previous();
357: assertEquals(expecteda, testinga);
358: Object expectedb = expected.next();
359: Object testingb = testing.next();
360: assertEquals(expecteda, testingb);
361: assertEquals(expecteda, expectedb);
362: assertEquals(testinga, testingb);
363: }
364:
365: private void walkLists(List list, ListIterator testing) {
366: ListIterator expected = list.listIterator();
367:
368: // walk all the way forward
369: walkForward(expected, testing);
370:
371: // walk all the way back
372: walkBackward(expected, testing);
373:
374: // forward,back,forward
375: while (expected.hasNext()) {
376: assertEquals(expected.nextIndex(), testing.nextIndex());
377: assertEquals(expected.previousIndex(), testing
378: .previousIndex());
379: assertTrue(testing.hasNext());
380: assertEquals(expected.next(), testing.next());
381: assertTrue(testing.hasPrevious());
382: assertEquals(expected.previous(), testing.previous());
383: assertTrue(testing.hasNext());
384: assertEquals(expected.next(), testing.next());
385: }
386:
387: // walk all the way back
388: walkBackward(expected, testing);
389:
390: for (int i = 0; i < list.size(); i++) {
391: // walk forward i
392: for (int j = 0; j < i; j++) {
393: assertEquals(expected.nextIndex(), testing.nextIndex());
394: assertEquals(expected.previousIndex(), testing
395: .previousIndex());
396: assertTrue(expected.hasNext()); // if this one fails we've got a logic error in the test
397: assertTrue(testing.hasNext());
398: assertEquals(expected.next(), testing.next());
399: }
400: // walk back i/2
401: for (int j = 0; j < i / 2; j++) {
402: assertEquals(expected.nextIndex(), testing.nextIndex());
403: assertEquals(expected.previousIndex(), testing
404: .previousIndex());
405: assertTrue(expected.hasPrevious()); // if this one fails we've got a logic error in the test
406: assertTrue(testing.hasPrevious());
407: assertEquals(expected.previous(), testing.previous());
408: }
409: // walk forward i/2
410: for (int j = 0; j < i / 2; j++) {
411: assertEquals(expected.nextIndex(), testing.nextIndex());
412: assertEquals(expected.previousIndex(), testing
413: .previousIndex());
414: assertTrue(expected.hasNext()); // if this one fails we've got a logic error in the test
415: assertTrue(testing.hasNext());
416: assertEquals(expected.next(), testing.next());
417: }
418: // walk back i
419: for (int j = 0; j < i; j++) {
420: assertEquals(expected.nextIndex(), testing.nextIndex());
421: assertEquals(expected.previousIndex(), testing
422: .previousIndex());
423: assertTrue(expected.hasPrevious()); // if this one fails we've got a logic error in the test
424: assertTrue(testing.hasPrevious());
425: assertEquals(expected.previous(), testing.previous());
426: }
427: }
428:
429: // random walk
430: StringBuffer walkdescr = new StringBuffer(500);
431: for (int i = 0; i < 500; i++) {
432: if (random.nextBoolean()) {
433: // step forward
434: walkdescr.append("+");
435: if (expected.hasNext()) {
436: assertEquals(walkdescr.toString(), expected.next(),
437: testing.next());
438: }
439: } else {
440: // step backward
441: walkdescr.append("-");
442: if (expected.hasPrevious()) {
443: assertEquals(walkdescr.toString(), expected
444: .previous(), testing.previous());
445: }
446: }
447: assertEquals(walkdescr.toString(), expected.nextIndex(),
448: testing.nextIndex());
449: assertEquals(walkdescr.toString(),
450: expected.previousIndex(), testing.previousIndex());
451: }
452:
453: }
454:
455: }
|