001: //Copyright (c) Corporation for National Research Initiatives
002: package javatests;
003:
004: import java.util.ArrayList;
005: import java.util.Arrays;
006: import java.util.Collection;
007: import java.util.Collections;
008: import java.util.Iterator;
009: import java.util.List;
010: import java.util.ListIterator;
011: import java.util.NoSuchElementException;
012:
013: /**
014: * @author updikca1
015: */
016: public abstract class ListTest {
017:
018: public static ListTest getArrayListTest(final boolean makeReadOnly) {
019: return new ListTest() {
020: public List newInstance(Collection c) {
021: List l = null;
022: if (c == null) {
023: l = new ArrayList();
024: } else {
025: l = new ArrayList(c);
026: }
027: return (makeReadOnly) ? Collections.unmodifiableList(l)
028: : l;
029: }
030:
031: public boolean isReadOnly() {
032: return makeReadOnly;
033: }
034: };
035: }
036:
037: public static void verifyImutability(List l) {
038:
039: String message = "Expected UnsupportedOperationException.";
040:
041: try {
042: l.add(0, new Integer(0));
043: TestSupport.assertThat(false, message);
044: } catch (UnsupportedOperationException e) {
045: }
046:
047: try {
048: l.add(new Integer(0));
049: TestSupport.assertThat(false, message);
050: } catch (UnsupportedOperationException e) {
051: }
052:
053: try {
054: l.addAll(null);
055: TestSupport.assertThat(false, message);
056: } catch (UnsupportedOperationException e) {
057: }
058:
059: try {
060: l.addAll(0, null);
061: TestSupport.assertThat(false, message);
062: } catch (UnsupportedOperationException e) {
063: }
064:
065: try {
066: l.clear();
067: TestSupport.assertThat(false, message);
068: } catch (UnsupportedOperationException e) {
069: }
070:
071: try {
072: l.remove(0);
073: TestSupport.assertThat(false, message);
074: } catch (UnsupportedOperationException e) {
075: }
076:
077: try {
078: l.remove(new Object());
079: TestSupport.assertThat(false, message);
080: } catch (UnsupportedOperationException e) {
081: }
082:
083: try {
084: l.removeAll(null);
085: TestSupport.assertThat(false, message);
086: } catch (UnsupportedOperationException e) {
087: }
088:
089: try {
090: l.retainAll(null);
091: TestSupport.assertThat(false, message);
092: } catch (UnsupportedOperationException e) {
093: }
094: try {
095: l.set(0, new Integer(0));
096: TestSupport.assertThat(false, message);
097: } catch (UnsupportedOperationException e) {
098: }
099: }
100:
101: private final List nullList;
102:
103: protected List defaultList() {
104: List l = new ArrayList();
105: for (int i = 0; i < 4; i++) {
106: l.add(new Integer(i));
107: }
108: return newInstance(l);
109: }
110:
111: /**
112: * Implementations must supply an empty list if the collection is null.
113: * @param c Initial collection or null for empty.
114: * @return the List instance
115: */
116: public List newInstance(Collection c) {
117: throw new UnsupportedOperationException(
118: "This method must be overridden");
119: }
120:
121: /**
122: * @return true if the list is read-only (like PyTuple)
123: */
124: public boolean isReadOnly() {
125: throw new UnsupportedOperationException(
126: "This method must be overridden");
127: }
128:
129: {
130: nullList = newInstance(Arrays.asList(new Object[] { null }));
131: }
132:
133: public void testAll() {
134:
135: test_get();
136: test_equals();
137: test_size();
138: test_contains();
139: test_containsAll();
140:
141: try {
142: defaultList().hashCode();
143: test_hashCode();
144: } catch (Exception e) {
145: // skip unhashable types
146: }
147:
148: test_subList();
149: test_lastIndexOf();
150: test_listIterator();
151: test_toArray();
152: test_toArray_typed();
153:
154: if (!isReadOnly()) {
155: test_add();
156: test_add_index();
157: test_set();
158: test_clear();
159: test_addAll();
160: test_addAll_index();
161: test_remove();
162: test_remove_index();
163: test_removeAll();
164: test_retainAll();
165: } else {
166: verifyImutability(newInstance(null));
167: }
168: }
169:
170: /** Tests get(int index) */
171: public void test_get() {
172: TestSupport.assertThat(defaultList().get(0).equals(
173: new Integer(0)),
174: "get() did not return expected value of Integer(0)");
175: try {
176: defaultList().get(-1);
177: TestSupport
178: .assertThat(false,
179: "get(<negative index>) did not throw IndexOutOfBoundsException");
180: } catch (IndexOutOfBoundsException e) {
181: }
182:
183: try {
184: defaultList().get(-1);
185: TestSupport
186: .assertThat(false,
187: "get(<index too big>) did not throw IndexOutOfBoundsException");
188: } catch (IndexOutOfBoundsException e) {
189: }
190: }
191:
192: /** Tests set(int index, Object element) */
193: public void test_set() {
194:
195: try {
196: newInstance(null).set(-1, "spam");
197: TestSupport
198: .assertThat(false,
199: "get(<negative index>) did not throw IndexOutOfBoundsException");
200: } catch (IndexOutOfBoundsException e) {
201: }
202:
203: try {
204: newInstance(null).set(0, "spam");
205: TestSupport
206: .assertThat(false,
207: "set(<index too big>) did not throw IndexOutOfBoundsException");
208: } catch (IndexOutOfBoundsException e) {
209: }
210:
211: List a = defaultList();
212: a.set(a.size() - 1, "spam");
213: TestSupport.assertThat(a.get(a.size() - 1).equals("spam"),
214: "set() object was not retrieved via get()");
215: }
216:
217: /** Tests add(Object o) */
218: public void test_add() {
219: List a = newInstance(null);
220: for (int i = 0; i < 4; i++) {
221: a.add(new Integer(i));
222: }
223: TestSupport.assertEquals(a, defaultList(),
224: "add(Object o) failed");
225: }
226:
227: /** Tests isEmpty() */
228: public void test_isEmpty() {
229: List a = newInstance(null);
230: TestSupport.assertThat(a.isEmpty(),
231: "isEmpty() is false on an emtpy List");
232: a.addAll(defaultList());
233: TestSupport.assertThat(!a.isEmpty(),
234: "isEmpty() is true on a non-empty List)");
235: a.clear();
236: TestSupport.assertThat(a.isEmpty(),
237: "isEmpty() is false on an emtpy List");
238: }
239:
240: /** Tests size() */
241: public void test_size() {
242: List b = newInstance(null);
243: TestSupport.assertThat(b.size() == 0,
244: "empty list size was not 0");
245: TestSupport.assertThat(defaultList().size() == 4,
246: "default list did not have a size of 4");
247: }
248:
249: /** Tests add(int index, Object element) */
250: public void test_add_index() {
251: List a = newInstance(null);
252: List b = defaultList();
253: for (int i = 0; i < b.size(); i++) {
254: a.add(i, b.get(i));
255: }
256:
257: try {
258: a.add(a.size() + 1, new Integer(a.size() + 1));
259: TestSupport.assertThat(false,
260: "expected IndexOutOfBoundsException");
261: } catch (IndexOutOfBoundsException e) {
262: }
263:
264: try {
265: a.add(-1, new Integer(-1));
266: TestSupport.assertThat(false,
267: "expected IndexOutOfBoundsException");
268: } catch (IndexOutOfBoundsException e) {
269: }
270: }
271:
272: /** Tests equals(Object o)*/
273: public void test_equals() {
274: TestSupport.assertEquals(defaultList(), defaultList(),
275: "Identical lists weren't equal()");
276: TestSupport.assertNotEquals(newInstance(null), defaultList(),
277: "Different lists were equal()");
278: TestSupport.assertNotEquals(newInstance(null), new Object(),
279: "List was equal to a non-List type");
280: }
281:
282: /** Tests addAll(Collection c) */
283: public void test_addAll() {
284: List a = defaultList();
285: List b = defaultList();
286:
287: TestSupport.assertThat(a.addAll(b) == true,
288: "Mutating addAll(Collection) returned false");
289: TestSupport.assertThat(a.addAll(newInstance(null)) == false,
290: "Idempotent addAll(Collection) returned true");
291: TestSupport.assertThat(b.addAll(b) == true,
292: "Mutating addAll(Collection) returned false");
293: TestSupport.assertEquals(a, b,
294: "Expected equal objects from addAll(collection)");
295: TestSupport
296: .assertThat(a.size() == 8,
297: "Expected List to have size 8 after addAll(Collection)");
298: }
299:
300: /** Tests indexOf(Object o) */
301: public void indexOf() {
302: TestSupport.assertThat(
303: defaultList().indexOf(new Integer(3)) == 3,
304: "indexOf(3) did not return 3");
305: TestSupport.assertThat(
306: defaultList().indexOf(new Integer(42)) == -1,
307: "indexOf() non-existing entry did not return -1");
308: TestSupport.assertThat(defaultList().indexOf(null) == -1,
309: "indexOf() non-existing null did not return -1");
310:
311: }
312:
313: /** Tests contains(Object o) */
314: public void test_contains() {
315: TestSupport.assertThat(
316: defaultList().contains(new Integer(42)) == false,
317: "contains() returned true for non-existing entry");
318: TestSupport.assertThat(
319: defaultList().contains(new Integer(0)) == true,
320: "contains() returned false for existing entry");
321: TestSupport.assertThat(nullList.contains(null) == true,
322: "contains() returned false for existing null entry");
323: TestSupport.assertThat(defaultList().contains(null) == false,
324: "contains() returned true for non-existing null entry");
325: }
326:
327: /** Tests remove(Object o) */
328: public void test_remove() {
329: List a = defaultList();
330: a.add(null);
331: TestSupport.assertThat(a.remove(null) == true,
332: "remove() existing null entry returned false");
333: TestSupport.assertThat(a.remove(null) == false,
334: "remove() non-existing null entry returned false");
335: a.add("spam");
336: TestSupport.assertThat(a.remove("spam") == true,
337: "remove() existing entry returned false");
338: TestSupport.assertThat(a.remove("spam") == false,
339: "remove() non-existing entry returned true");
340: }
341:
342: /** Tests remove(int index) */
343: public void test_remove_index() {
344:
345: List a = defaultList();
346: for (int i = 0, n = a.size(); i < n; i++) {
347: a.remove(0);
348: }
349: TestSupport.assertThat(a.size() == 0,
350: "remove()-d all entries but size() not 0");
351:
352: try {
353: a.remove(0);
354: TestSupport
355: .assertThat(false,
356: "removing a non-existing index did not throw exception");
357: } catch (IndexOutOfBoundsException e) {
358: }
359: }
360:
361: /** Tests lastIndexOf(Object o) */
362: public void test_lastIndexOf() {
363: // avoid calling any mutable methods
364: List l = new ArrayList(defaultList());
365: l.add(new Integer(0));
366:
367: // now get the immutable version
368: List a = newInstance(l);
369:
370: TestSupport.assertThat(a.lastIndexOf(new Integer(0)) == 4,
371: "lastIndexOf() did not return 4");
372: TestSupport.assertThat(a.lastIndexOf(new Integer(42)) == -1,
373: "lastIndexOf() non-existing value did not return -1");
374: }
375:
376: /** Tests removeAll(Collection c) */
377: public void test_removeAll() {
378: List a = defaultList();
379: TestSupport.assertThat(a.removeAll(a) == true,
380: "mutating removeAll() did not return true");
381: TestSupport.assertThat(a.removeAll(a) == false,
382: "idempotent removeAll did not return false");
383: TestSupport.assertThat(a.removeAll(nullList) == false,
384: "idempotent removeAll did not return false");
385:
386: List yanl = newInstance(null);
387: yanl.addAll(nullList);
388: TestSupport.assertThat(yanl.removeAll(nullList) == true,
389: "mutating removeAll() did not return true");
390: TestSupport.assertThat(yanl.size() == 0,
391: "empty list had non-zero size");
392: TestSupport.assertThat(
393: yanl.removeAll(newInstance(null)) == false,
394: "idempotent removeAll did not return false");
395:
396: }
397:
398: /** Tests addAll(int index, Collection c) */
399: public void test_addAll_index() {
400: List a = defaultList();
401: List b = newInstance(null);
402: TestSupport
403: .assertThat(b.addAll(0, a) == true,
404: "mutating addAll(index, Collection) did not return true");
405: TestSupport
406: .assertEquals(a, b,
407: "addAll(index, Collection) instances failed equals test");
408: TestSupport
409: .assertThat(a.addAll(0, newInstance(null)) == false,
410: "idempotent addAll(index, Collection) did not return false");
411: TestSupport
412: .assertThat(b.addAll(0, b) == true,
413: "mutating addAll(index, Collection) did not return true");
414:
415: // Since PyObjectList has some specific handling when it detects
416: // addAll on a PySequenceList, make sure the general case works.
417: b = newInstance(null);
418: b.addAll(new ArrayList(defaultList()));
419: TestSupport.assertEquals(defaultList(), b,
420: "addAll(index, <ArrayList>) failed equals test");
421: }
422:
423: /** Tests hashCode() */
424: public void test_hashCode() {
425: List a = defaultList();
426: TestSupport
427: .assertThat(a.hashCode() == defaultList().hashCode(),
428: "Instances with same internal state have different hashcode");
429: TestSupport
430: .assertThat(a.hashCode() != newInstance(null)
431: .hashCode(),
432: "Instances with different internal state have the same hashcode");
433:
434: if (isReadOnly() == false) {
435: List b = newInstance(null);
436: b.addAll(a);
437: b.remove(0);
438: TestSupport
439: .assertThat(a.hashCode() != b.hashCode(),
440: "Instances with different internal state have the same hashcode");
441: }
442:
443: }
444:
445: /** Tests clear() */
446: public void test_clear() {
447: List a = defaultList();
448: a.clear();
449: TestSupport.assertThat(a.size() == 0,
450: "clear()-ed list did not have size of 0");
451: }
452:
453: /** Tests subList(int fromIndex, int toIndex) */
454: public void test_subList() {
455: List a = defaultList();
456: TestSupport.assertThat((a.subList(0, a.size()) != a),
457: "subList() returned the same instance");
458: TestSupport.assertEquals(a.subList(0, a.size()), a,
459: "Complete subList() did not equal original List");
460: TestSupport.assertThat(a.subList(0, 0).size() == 0,
461: "empty subList had non-zero size");
462:
463: try {
464: a.subList(-1, 1);
465: TestSupport.assertThat(false,
466: "Expected IndexOutOfBoundsException");
467: } catch (IndexOutOfBoundsException e) {
468: }
469:
470: try {
471: a.subList(1, 0);
472: TestSupport.assertThat(false,
473: "Expected IllegalArgumentException");
474: } catch (IllegalArgumentException e) {
475: }
476:
477: try {
478: a.subList(0, a.size() + 1);
479: TestSupport.assertThat(false,
480: "Expected IndexOutOfBoundsException");
481: } catch (IndexOutOfBoundsException e) {
482: }
483:
484: if (!isReadOnly()) {
485:
486: a.subList(0, a.size()).clear();
487: TestSupport.assertThat(a.size() == 0,
488: "clear()-ed sublist did not have zero size");
489: List c = newInstance(null);
490: c.addAll(defaultList());
491: List d = c.subList(1, 3);
492: TestSupport.assertThat(d.size() == 2,
493: "Expected subList to have size of 2");
494: TestSupport.assertThat(c.set(1, "canned").equals(
495: new Integer(1)),
496: "subList.set() did not return Integer(1) from index 1"
497: + " of defaultList");
498: TestSupport.assertThat(d.get(0).equals("canned"),
499: "subList does not update with changes to parent");
500: d.set(0, "spam");
501: TestSupport
502: .assertThat(c.get(1).equals("spam"),
503: "parent does not update with changes to subList child");
504: } else {
505: List b = a.subList(0, a.size());
506: verifyImutability(b);
507: }
508:
509: }
510:
511: /** Tests retainAll(Collection c) */
512: public void test_retainAll() {
513: List a = defaultList();
514: a.retainAll(defaultList());
515: TestSupport.assertEquals(a, defaultList(),
516: "retainAll(<equal List>) does not equal original list");
517: a = defaultList();
518: a.retainAll(newInstance(null));
519: TestSupport.assertThat(a.size() == 0,
520: "retainAll(<empty List>))does not have size of zero");
521:
522: a = defaultList();
523: a.remove(0);
524: a.remove(0);
525: a.add(new Integer(4));
526: a.add(new Integer(5));
527: List b = newInstance(null);
528: b.add(new Integer(2));
529: b.add(new Integer(3));
530: a.retainAll(b);
531: TestSupport
532: .assertEquals(a, b,
533: "retainAll() on overlap of indices [2,3] did not return that List");
534: }
535:
536: /** Tests containsAll(Collection c) */
537: public void test_containsAll() {
538: TestSupport.assertThat(
539: defaultList().containsAll(defaultList()),
540: "containsAll(<identical List> was false");
541: TestSupport.assertThat(defaultList().containsAll(
542: newInstance(null)),
543: "containsAll(<empty List>) was false");
544: TestSupport.assertThat(newInstance(null).containsAll(
545: defaultList()) == false,
546: "containsAll(<disjoint List>) returned true");
547: TestSupport.assertThat(defaultList().containsAll(
548: defaultList().subList(1, 3)),
549: "containsAll(<subList>) was false");
550: }
551:
552: /** Tests iterator() */
553: public void test_iterator() {
554:
555: TestSupport.assertThat(
556: newInstance(null).iterator().hasNext() == false,
557: "Iterator for empty list thinks it hasNext()");
558: try {
559: newInstance(null).iterator().next();
560: TestSupport.assertThat(false,
561: "expected NoSuchElementException");
562: } catch (NoSuchElementException e) {
563: }
564:
565: List a = defaultList();
566: int i = 0;
567: for (Iterator iter = a.iterator(); iter.hasNext();) {
568: TestSupport.assertThat(iter.next() == a.get(i++),
569: "Iterator next() failed identity test");
570: }
571: TestSupport.assertThat(i == a.size(),
572: "Iterator did not iterator over entire list");
573: }
574:
575: public void test_listIterator() {
576:
577: ListIterator li = newInstance(null).listIterator();
578: TestSupport.assertThat(li.hasNext() == false,
579: "ListIterator.hasNext() is true for empty List");
580:
581: TestSupport.assertThat(li.hasPrevious() == false,
582: "ListIterator.hasPrevious() is true for empty List");
583:
584: try {
585: li.next();
586: TestSupport.assertThat(false,
587: "expected NoSuchElementException");
588: } catch (NoSuchElementException e) {
589: }
590:
591: try {
592: li.previous();
593: TestSupport.assertThat(false,
594: "expected NoSuchElementException");
595: } catch (NoSuchElementException e) {
596: }
597:
598: // Appears bug was fixed from 1.3 to 1.4. Code it to pass either way.
599: int nextIndex = li.nextIndex();
600: TestSupport.assertThat(nextIndex == -1 || nextIndex == 0,
601: "ListIterator.nextIndex() on empty List did not return 0 "
602: + "(java 1.4) or did not return -1 (java 1.3)");
603:
604: // Likewise...
605: int prevIndex = li.previousIndex();
606: TestSupport.assertThat(prevIndex == -1 || prevIndex == -2,
607: "ListIterator.previousIndex() on empty List did not return -1 "
608: + "(java 1.4) or -2 (java 1.3)");
609:
610: List l = new ArrayList();
611: l.add(new Integer(1));
612: li = newInstance(l).listIterator();
613: TestSupport
614: .assertThat(li.hasPrevious() == false,
615: "ListIterator.hasPrevious() is true with nothing previous");
616:
617: TestSupport.assertThat(li.hasNext() == true,
618: "ListIterator.hasNext() is false with next present");
619: TestSupport
620: .assertThat(li.next().equals(new Integer(1)),
621: "ListIterator.next() did not return expected Integer(1)");
622:
623: if (!isReadOnly()) {
624: li.remove();
625: TestSupport.assertThat(li.hasNext() == false,
626: "ListIterator.hasNext() is true for empty List");
627:
628: TestSupport
629: .assertThat(li.hasPrevious() == false,
630: "ListIterator.hasPrevious() is true for empty List");
631: try {
632: li.set(new Integer(42));
633: TestSupport.assertThat(false,
634: "expected IllegalStateException");
635: } catch (IllegalStateException e) {
636: }
637:
638: try {
639: li.remove();
640: TestSupport.assertThat(false,
641: "expected IllegalStateException");
642: } catch (IllegalStateException e) {
643: }
644: }
645:
646: l = new ArrayList();
647: l.add(new Integer(0));
648: l.add(new Integer(1));
649: l.add(new Integer(2));
650:
651: li = newInstance(l).listIterator();
652:
653: for (int i = 0, n = l.size(); i < n; i++) {
654: TestSupport
655: .assertThat(li.next().equals(new Integer(i)),
656: "ListIterator.previous did not return expected value");
657: }
658:
659: while (!isReadOnly() && li.hasNext()) {
660: li.next();
661: li.set(new Integer(42));
662: TestSupport
663: .assertThat(li.previous().equals(new Integer(42)),
664: "ListIterator.previous() did not return the value that was set()");
665: li.remove();
666: }
667:
668: if (isReadOnly()) {
669: li = newInstance(null).listIterator();
670: }
671:
672: li = defaultList().listIterator(2);
673: TestSupport
674: .assertThat(li.next().equals(new Integer(2)),
675: "List.listIteraor(index) did not return expected value");
676: TestSupport
677: .assertThat(li.next().equals(new Integer(3)),
678: "List.listIteraor(index) did not return expected value");
679: TestSupport.assertThat(li.hasNext() == false,
680: "listIterator.hasNext() at end of list returned true");
681:
682: }
683:
684: /** Tests toArray() */
685: public void test_toArray() {
686: Object[] intObjArray = new Integer[] { new Integer(0),
687: new Integer(1), new Integer(2), new Integer(3) };
688: TestSupport
689: .assertThat(Arrays.equals(defaultList().toArray(),
690: intObjArray),
691: "toArray() did not return the expected Integer[] array");
692: }
693:
694: /** Tests toArray(Object[] a) */
695: public void test_toArray_typed() {
696: Object[] intObjArray = new Integer[] { new Integer(0),
697: new Integer(1), new Integer(2), new Integer(3) };
698: TestSupport
699: .assertThat(Arrays.equals(defaultList().toArray(
700: new Integer[] {}), intObjArray),
701: "toArray(Integer[]) did not return the expected Integer[] array");
702: }
703:
704: // Can't test clone since it's not visible, but it is from jython.
705: // /** Tests clone() */
706: // public void test_clone() {
707: // List a = defaultList();
708: // TestSupport.assertEquals(((Object)a).clone(), a,
709: // "clone() was not equal to original");
710: // TestSupport.assertThat(a.clone() != a,
711: // "clone() returned same instance");
712: // }
713: }
|