0001: /*
0002: * Copyright 2001-2005 The Apache Software Foundation
0003: *
0004: * Licensed under the Apache License, Version 2.0 (the "License");
0005: * you may not use this file except in compliance with the License.
0006: * You may obtain a copy of the License at
0007: *
0008: * http://www.apache.org/licenses/LICENSE-2.0
0009: *
0010: * Unless required by applicable law or agreed to in writing, software
0011: * distributed under the License is distributed on an "AS IS" BASIS,
0012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013: * See the License for the specific language governing permissions and
0014: * limitations under the License.
0015: */
0016: package org.apache.commons.collections.list;
0017:
0018: import java.io.IOException;
0019: import java.io.Serializable;
0020: import java.lang.reflect.InvocationTargetException;
0021: import java.lang.reflect.Method;
0022: import java.util.AbstractCollection;
0023: import java.util.ArrayList;
0024: import java.util.Arrays;
0025: import java.util.Collection;
0026: import java.util.Collections;
0027: import java.util.ConcurrentModificationException;
0028: import java.util.Iterator;
0029: import java.util.List;
0030: import java.util.ListIterator;
0031: import java.util.NoSuchElementException;
0032:
0033: import org.apache.commons.collections.BulkTest;
0034: import org.apache.commons.collections.collection.AbstractTestCollection;
0035: import org.apache.commons.collections.iterators.AbstractTestListIterator;
0036:
0037: /**
0038: * Abstract test class for {@link java.util.List} methods and contracts.
0039: * <p>
0040: * To use, simply extend this class, and implement
0041: * the {@link #makeEmptyList} method.
0042: * <p>
0043: * If your {@link List} fails one of these tests by design,
0044: * you may still use this base set of cases. Simply override the
0045: * test case (method) your {@link List} fails or override one of the
0046: * protected methods from AbstractTestCollection.
0047: *
0048: * @version $Revision: 224666 $ $Date: 2005-07-25 00:01:40 +0100 (Mon, 25 Jul 2005) $
0049: *
0050: * @author Rodney Waldhoff
0051: * @author Paul Jack
0052: * @author Stephen Colebourne
0053: * @author Neil O'Toole
0054: */
0055: public abstract class AbstractTestList extends AbstractTestCollection {
0056:
0057: /**
0058: * JUnit constructor.
0059: *
0060: * @param testName the test class name
0061: */
0062: public AbstractTestList(String testName) {
0063: super (testName);
0064: }
0065:
0066: //-----------------------------------------------------------------------
0067: /**
0068: * Returns true if the collections produced by
0069: * {@link #makeCollection()} and {@link #makeFullCollection()}
0070: * support the <code>set operation.<p>
0071: * Default implementation returns true. Override if your collection
0072: * class does not support set.
0073: */
0074: public boolean isSetSupported() {
0075: return true;
0076: }
0077:
0078: //-----------------------------------------------------------------------
0079: /**
0080: * Verifies that the test list implementation matches the confirmed list
0081: * implementation.
0082: */
0083: public void verify() {
0084: super .verify();
0085:
0086: List list1 = getList();
0087: List list2 = getConfirmedList();
0088:
0089: assertEquals("List should equal confirmed", list1, list2);
0090: assertEquals("Confirmed should equal list", list2, list1);
0091:
0092: assertEquals("Hash codes should be equal", list1.hashCode(),
0093: list2.hashCode());
0094:
0095: int i = 0;
0096: Iterator iterator1 = list1.iterator();
0097: Iterator iterator2 = list2.iterator();
0098: Object[] array = list1.toArray();
0099: while (iterator2.hasNext()) {
0100: assertTrue("List iterator should have next", iterator1
0101: .hasNext());
0102: Object o1 = iterator1.next();
0103: Object o2 = iterator2.next();
0104: assertEquals("Iterator elements should be equal", o1, o2);
0105: o2 = list1.get(i);
0106: assertEquals("get should return correct element", o1, o2);
0107: o2 = array[i];
0108: assertEquals("toArray should have correct element", o1, o2);
0109: i++;
0110: }
0111: }
0112:
0113: //-----------------------------------------------------------------------
0114: /**
0115: * List equals method is defined.
0116: */
0117: public boolean isEqualsCheckable() {
0118: return true;
0119: }
0120:
0121: /**
0122: * Returns an empty {@link ArrayList}.
0123: */
0124: public Collection makeConfirmedCollection() {
0125: ArrayList list = new ArrayList();
0126: return list;
0127: }
0128:
0129: /**
0130: * Returns a full {@link ArrayList}.
0131: */
0132: public Collection makeConfirmedFullCollection() {
0133: ArrayList list = new ArrayList();
0134: list.addAll(Arrays.asList(getFullElements()));
0135: return list;
0136: }
0137:
0138: /**
0139: * Return a new, empty {@link List} to be used for testing.
0140: *
0141: * @return an empty list for testing.
0142: */
0143: public abstract List makeEmptyList();
0144:
0145: /**
0146: * Return a new, full {@link List} to be used for testing.
0147: *
0148: * @return a full list for testing
0149: */
0150: public List makeFullList() {
0151: // only works if list supports optional "addAll(Collection)"
0152: List list = makeEmptyList();
0153: list.addAll(Arrays.asList(getFullElements()));
0154: return list;
0155: }
0156:
0157: /**
0158: * Returns {@link #makeEmptyList()}.
0159: *
0160: * @return an empty list to be used for testing
0161: */
0162: public final Collection makeCollection() {
0163: return makeEmptyList();
0164: }
0165:
0166: /**
0167: * Returns {@link #makeFullList()}.
0168: *
0169: * @return a full list to be used for testing
0170: */
0171: public final Collection makeFullCollection() {
0172: return makeFullList();
0173: }
0174:
0175: //-----------------------------------------------------------------------
0176: /**
0177: * Returns the {@link #collection} field cast to a {@link List}.
0178: *
0179: * @return the collection field as a List
0180: */
0181: public List getList() {
0182: return (List) collection;
0183: }
0184:
0185: /**
0186: * Returns the {@link #confirmed} field cast to a {@link List}.
0187: *
0188: * @return the confirmed field as a List
0189: */
0190: public List getConfirmedList() {
0191: return (List) confirmed;
0192: }
0193:
0194: //-----------------------------------------------------------------------
0195: /**
0196: * Tests bounds checking for {@link List#add(int, Object)} on an
0197: * empty list.
0198: */
0199: public void testListAddByIndexBoundsChecking() {
0200: if (!isAddSupported()) {
0201: return;
0202: }
0203:
0204: List list;
0205: Object element = getOtherElements()[0];
0206:
0207: try {
0208: list = makeEmptyList();
0209: list.add(Integer.MIN_VALUE, element);
0210: fail("List.add should throw IndexOutOfBoundsException [Integer.MIN_VALUE]");
0211: } catch (IndexOutOfBoundsException e) {
0212: // expected
0213: }
0214:
0215: try {
0216: list = makeEmptyList();
0217: list.add(-1, element);
0218: fail("List.add should throw IndexOutOfBoundsException [-1]");
0219: } catch (IndexOutOfBoundsException e) {
0220: // expected
0221: }
0222:
0223: try {
0224: list = makeEmptyList();
0225: list.add(1, element);
0226: fail("List.add should throw IndexOutOfBoundsException [1]");
0227: } catch (IndexOutOfBoundsException e) {
0228: // expected
0229: }
0230:
0231: try {
0232: list = makeEmptyList();
0233: list.add(Integer.MAX_VALUE, element);
0234: fail("List.add should throw IndexOutOfBoundsException [Integer.MAX_VALUE]");
0235: } catch (IndexOutOfBoundsException e) {
0236: // expected
0237: }
0238: }
0239:
0240: /**
0241: * Tests bounds checking for {@link List#add(int, Object)} on a
0242: * full list.
0243: */
0244: public void testListAddByIndexBoundsChecking2() {
0245: if (!isAddSupported()) {
0246: return;
0247: }
0248:
0249: List list;
0250: Object element = getOtherElements()[0];
0251:
0252: try {
0253: list = makeFullList();
0254: list.add(Integer.MIN_VALUE, element);
0255: fail("List.add should throw IndexOutOfBoundsException [Integer.MIN_VALUE]");
0256: } catch (IndexOutOfBoundsException e) {
0257: // expected
0258: }
0259:
0260: try {
0261: list = makeFullList();
0262: list.add(-1, element);
0263: fail("List.add should throw IndexOutOfBoundsException [-1]");
0264: } catch (IndexOutOfBoundsException e) {
0265: // expected
0266: }
0267:
0268: try {
0269: list = makeFullList();
0270: list.add(list.size() + 1, element);
0271: fail("List.add should throw IndexOutOfBoundsException [size + 1]");
0272: } catch (IndexOutOfBoundsException e) {
0273: // expected
0274: }
0275:
0276: try {
0277: list = makeFullList();
0278: list.add(Integer.MAX_VALUE, element);
0279: fail("List.add should throw IndexOutOfBoundsException [Integer.MAX_VALUE]");
0280: } catch (IndexOutOfBoundsException e) {
0281: // expected
0282: }
0283: }
0284:
0285: /**
0286: * Tests {@link List#add(int,Object)}.
0287: */
0288: public void testListAddByIndex() {
0289: if (!isAddSupported()) {
0290: return;
0291: }
0292:
0293: Object element = getOtherElements()[0];
0294: int max = getFullElements().length;
0295:
0296: for (int i = 0; i <= max; i++) {
0297: resetFull();
0298: ((List) collection).add(i, element);
0299: ((List) confirmed).add(i, element);
0300: verify();
0301: }
0302: }
0303:
0304: /**
0305: * Tests {@link List#equals(Object)}.
0306: */
0307: public void testListEquals() {
0308: resetEmpty();
0309: List list = getList();
0310: assertEquals("Empty lists should be equal", true, list
0311: .equals(confirmed));
0312: verify();
0313: assertEquals("Empty list should equal self", true, list
0314: .equals(list));
0315: verify();
0316:
0317: List list2 = Arrays.asList(getFullElements());
0318: assertEquals("Empty list shouldn't equal full", false, list
0319: .equals(list2));
0320: verify();
0321:
0322: list2 = Arrays.asList(getOtherElements());
0323: assertEquals("Empty list shouldn't equal other", false, list
0324: .equals(list2));
0325: verify();
0326:
0327: resetFull();
0328: list = getList();
0329: assertEquals("Full lists should be equal", true, list
0330: .equals(confirmed));
0331: verify();
0332: assertEquals("Full list should equal self", true, list
0333: .equals(list));
0334: verify();
0335:
0336: list2 = makeEmptyList();
0337: assertEquals("Full list shouldn't equal empty", false, list
0338: .equals(list2));
0339: verify();
0340:
0341: list2 = Arrays.asList(getOtherElements());
0342: assertEquals("Full list shouldn't equal other", false, list
0343: .equals(list2));
0344: verify();
0345:
0346: list2 = Arrays.asList(getFullElements());
0347: if (list2.size() < 2 && isAddSupported()) {
0348: // main list is only size 1, so lets add other elements to get a better list
0349: list.addAll(Arrays.asList(getOtherElements()));
0350: confirmed.addAll(Arrays.asList(getOtherElements()));
0351: list2 = new ArrayList(list2);
0352: list2.addAll(Arrays.asList(getOtherElements()));
0353: }
0354: if (list2.size() > 1) {
0355: Collections.reverse(list2);
0356: assertEquals(
0357: "Full list shouldn't equal full list with same elements but different order",
0358: false, list.equals(list2));
0359: verify();
0360: }
0361:
0362: resetFull();
0363: list = getList();
0364: assertEquals("List shouldn't equal String", false, list
0365: .equals(""));
0366: verify();
0367:
0368: final List listForC = Arrays.asList(getFullElements());
0369: Collection c = new AbstractCollection() {
0370: public int size() {
0371: return listForC.size();
0372: }
0373:
0374: public Iterator iterator() {
0375: return listForC.iterator();
0376: }
0377: };
0378:
0379: assertEquals(
0380: "List shouldn't equal nonlist with same elements in same order",
0381: false, list.equals(c));
0382: verify();
0383: }
0384:
0385: /**
0386: * Tests {@link List#hashCode()}.
0387: */
0388: public void testListHashCode() {
0389: resetEmpty();
0390: int hash1 = collection.hashCode();
0391: int hash2 = confirmed.hashCode();
0392: assertEquals("Empty lists should have equal hashCodes", hash1,
0393: hash2);
0394: verify();
0395:
0396: resetFull();
0397: hash1 = collection.hashCode();
0398: hash2 = confirmed.hashCode();
0399: assertEquals("Full lists should have equal hashCodes", hash1,
0400: hash2);
0401: verify();
0402: }
0403:
0404: /**
0405: * Tests {@link List#get(int)}.
0406: */
0407: public void testListGetByIndex() {
0408: resetFull();
0409: List list = getList();
0410: Object[] elements = getFullElements();
0411: for (int i = 0; i < elements.length; i++) {
0412: assertEquals("List should contain correct elements",
0413: elements[i], list.get(i));
0414: verify();
0415: }
0416: }
0417:
0418: /**
0419: * Tests bounds checking for {@link List#get(int)} on an
0420: * empty list.
0421: */
0422: public void testListGetByIndexBoundsChecking() {
0423: List list = makeEmptyList();
0424:
0425: try {
0426: list.get(Integer.MIN_VALUE);
0427: fail("List.get should throw IndexOutOfBoundsException [Integer.MIN_VALUE]");
0428: } catch (IndexOutOfBoundsException e) {
0429: // expected
0430: }
0431:
0432: try {
0433: list.get(-1);
0434: fail("List.get should throw IndexOutOfBoundsException [-1]");
0435: } catch (IndexOutOfBoundsException e) {
0436: // expected
0437: }
0438:
0439: try {
0440: list.get(0);
0441: fail("List.get should throw IndexOutOfBoundsException [0]");
0442: } catch (IndexOutOfBoundsException e) {
0443: // expected
0444: }
0445:
0446: try {
0447: list.get(1);
0448: fail("List.get should throw IndexOutOfBoundsException [1]");
0449: } catch (IndexOutOfBoundsException e) {
0450: // expected
0451: }
0452:
0453: try {
0454: list.get(Integer.MAX_VALUE);
0455: fail("List.get should throw IndexOutOfBoundsException [Integer.MAX_VALUE]");
0456: } catch (IndexOutOfBoundsException e) {
0457: // expected
0458: }
0459: }
0460:
0461: /**
0462: * Tests bounds checking for {@link List#get(int)} on a
0463: * full list.
0464: */
0465: public void testListGetByIndexBoundsChecking2() {
0466: List list = makeFullList();
0467:
0468: try {
0469: list.get(Integer.MIN_VALUE);
0470: fail("List.get should throw IndexOutOfBoundsException [Integer.MIN_VALUE]");
0471: } catch (IndexOutOfBoundsException e) {
0472: // expected
0473: }
0474:
0475: try {
0476: list.get(-1);
0477: fail("List.get should throw IndexOutOfBoundsException [-1]");
0478: } catch (IndexOutOfBoundsException e) {
0479: // expected
0480: }
0481:
0482: try {
0483: list.get(getFullElements().length);
0484: fail("List.get should throw IndexOutOfBoundsException [size]");
0485: } catch (IndexOutOfBoundsException e) {
0486: // expected
0487: }
0488:
0489: try {
0490: list.get(Integer.MAX_VALUE);
0491: fail("List.get should throw IndexOutOfBoundsException [Integer.MAX_VALUE]");
0492: } catch (IndexOutOfBoundsException e) {
0493: // expected
0494: }
0495: }
0496:
0497: /**
0498: * Tests {@link List#indexOf}.
0499: */
0500: public void testListIndexOf() {
0501: resetFull();
0502: List list1 = getList();
0503: List list2 = getConfirmedList();
0504:
0505: Iterator iterator = list2.iterator();
0506: while (iterator.hasNext()) {
0507: Object element = iterator.next();
0508: assertEquals("indexOf should return correct result", list1
0509: .indexOf(element), list2.indexOf(element));
0510: verify();
0511: }
0512:
0513: Object[] other = getOtherElements();
0514: for (int i = 0; i < other.length; i++) {
0515: assertEquals(
0516: "indexOf should return -1 for nonexistent element",
0517: list1.indexOf(other[i]), -1);
0518: verify();
0519: }
0520: }
0521:
0522: /**
0523: * Tests {@link List#lastIndexOf}.
0524: */
0525: public void testListLastIndexOf() {
0526: resetFull();
0527: List list1 = getList();
0528: List list2 = getConfirmedList();
0529:
0530: Iterator iterator = list2.iterator();
0531: while (iterator.hasNext()) {
0532: Object element = iterator.next();
0533: assertEquals("lastIndexOf should return correct result",
0534: list1.lastIndexOf(element), list2
0535: .lastIndexOf(element));
0536: verify();
0537: }
0538:
0539: Object[] other = getOtherElements();
0540: for (int i = 0; i < other.length; i++) {
0541: assertEquals(
0542: "lastIndexOf should return -1 for nonexistent "
0543: + "element", list1.lastIndexOf(other[i]),
0544: -1);
0545: verify();
0546: }
0547: }
0548:
0549: /**
0550: * Tests bounds checking for {@link List#set(int,Object)} on an
0551: * empty list.
0552: */
0553: public void testListSetByIndexBoundsChecking() {
0554: if (!isSetSupported()) {
0555: return;
0556: }
0557:
0558: List list = makeEmptyList();
0559: Object element = getOtherElements()[0];
0560:
0561: try {
0562: list.set(Integer.MIN_VALUE, element);
0563: fail("List.set should throw IndexOutOfBoundsException [Integer.MIN_VALUE]");
0564: } catch (IndexOutOfBoundsException e) {
0565: // expected
0566: }
0567:
0568: try {
0569: list.set(-1, element);
0570: fail("List.set should throw IndexOutOfBoundsException [-1]");
0571: } catch (IndexOutOfBoundsException e) {
0572: // expected
0573: }
0574:
0575: try {
0576: list.set(0, element);
0577: fail("List.set should throw IndexOutOfBoundsException [0]");
0578: } catch (IndexOutOfBoundsException e) {
0579: // expected
0580: }
0581:
0582: try {
0583: list.set(1, element);
0584: fail("List.set should throw IndexOutOfBoundsException [1]");
0585: } catch (IndexOutOfBoundsException e) {
0586: // expected
0587: }
0588:
0589: try {
0590: list.set(Integer.MAX_VALUE, element);
0591: fail("List.set should throw IndexOutOfBoundsException [Integer.MAX_VALUE]");
0592: } catch (IndexOutOfBoundsException e) {
0593: // expected
0594: }
0595: }
0596:
0597: /**
0598: * Tests bounds checking for {@link List#set(int,Object)} on a
0599: * full list.
0600: */
0601: public void testListSetByIndexBoundsChecking2() {
0602: if (!isSetSupported())
0603: return;
0604:
0605: List list = makeFullList();
0606: Object element = getOtherElements()[0];
0607:
0608: try {
0609: list.set(Integer.MIN_VALUE, element);
0610: fail("List.set should throw IndexOutOfBoundsException "
0611: + "[Integer.MIN_VALUE]");
0612: } catch (IndexOutOfBoundsException e) {
0613: // expected
0614: }
0615:
0616: try {
0617: list.set(-1, element);
0618: fail("List.set should throw IndexOutOfBoundsException [-1]");
0619: } catch (IndexOutOfBoundsException e) {
0620: // expected
0621: }
0622:
0623: try {
0624: list.set(getFullElements().length, element);
0625: fail("List.set should throw IndexOutOfBoundsException [size]");
0626: } catch (IndexOutOfBoundsException e) {
0627: // expected
0628: }
0629:
0630: try {
0631: list.set(Integer.MAX_VALUE, element);
0632: fail("List.set should throw IndexOutOfBoundsException "
0633: + "[Integer.MAX_VALUE]");
0634: } catch (IndexOutOfBoundsException e) {
0635: // expected
0636: }
0637: }
0638:
0639: /**
0640: * Test {@link List#set(int,Object)}.
0641: */
0642: public void testListSetByIndex() {
0643: if (!isSetSupported())
0644: return;
0645:
0646: resetFull();
0647: Object[] elements = getFullElements();
0648: Object[] other = getOtherElements();
0649:
0650: for (int i = 0; i < elements.length; i++) {
0651: Object n = other[i % other.length];
0652: Object v = ((List) collection).set(i, n);
0653: assertEquals("Set should return correct element",
0654: elements[i], v);
0655: ((List) confirmed).set(i, n);
0656: verify();
0657: }
0658: }
0659:
0660: /**
0661: * If {@link #isSetSupported()} returns false, tests that set operation
0662: * raises <Code>UnsupportedOperationException.
0663: */
0664: public void testUnsupportedSet() {
0665: if (isSetSupported())
0666: return;
0667:
0668: resetFull();
0669: try {
0670: ((List) collection).set(0, new Object());
0671: fail("Emtpy collection should not support set.");
0672: } catch (UnsupportedOperationException e) {
0673: // expected
0674: }
0675: // make sure things didn't change even if the expected exception was
0676: // thrown.
0677: verify();
0678: }
0679:
0680: /**
0681: * Tests bounds checking for {@link List#remove(int)} on an
0682: * empty list.
0683: */
0684: public void testListRemoveByIndexBoundsChecking() {
0685: if (!isRemoveSupported())
0686: return;
0687:
0688: List list = makeEmptyList();
0689:
0690: try {
0691: list.remove(Integer.MIN_VALUE);
0692: fail("List.remove should throw IndexOutOfBoundsException "
0693: + "[Integer.MIN_VALUE]");
0694: } catch (IndexOutOfBoundsException e) {
0695: // expected
0696: }
0697:
0698: try {
0699: list.remove(-1);
0700: fail("List.remove should throw IndexOutOfBoundsException [-1]");
0701: } catch (IndexOutOfBoundsException e) {
0702: // expected
0703: }
0704:
0705: try {
0706: list.remove(0);
0707: fail("List.remove should throw IndexOutOfBoundsException [0]");
0708: } catch (IndexOutOfBoundsException e) {
0709: // expected
0710: }
0711:
0712: try {
0713: list.remove(1);
0714: fail("List.remove should throw IndexOutOfBoundsException [1]");
0715: } catch (IndexOutOfBoundsException e) {
0716: // expected
0717: }
0718:
0719: try {
0720: list.remove(Integer.MAX_VALUE);
0721: fail("List.remove should throw IndexOutOfBoundsException "
0722: + "[Integer.MAX_VALUE]");
0723: } catch (IndexOutOfBoundsException e) {
0724: // expected
0725: }
0726: }
0727:
0728: /**
0729: * Tests bounds checking for {@link List#remove(int)} on a
0730: * full list.
0731: */
0732: public void testListRemoveByIndexBoundsChecking2() {
0733: if (!isRemoveSupported())
0734: return;
0735:
0736: List list = makeFullList();
0737:
0738: try {
0739: list.remove(Integer.MIN_VALUE);
0740: fail("List.remove should throw IndexOutOfBoundsException "
0741: + "[Integer.MIN_VALUE]");
0742: } catch (IndexOutOfBoundsException e) {
0743: // expected
0744: }
0745:
0746: try {
0747: list.remove(-1);
0748: fail("List.remove should throw IndexOutOfBoundsException [-1]");
0749: } catch (IndexOutOfBoundsException e) {
0750: // expected
0751: }
0752:
0753: try {
0754: list.remove(getFullElements().length);
0755: fail("List.remove should throw IndexOutOfBoundsException [size]");
0756: } catch (IndexOutOfBoundsException e) {
0757: // expected
0758: }
0759:
0760: try {
0761: list.remove(Integer.MAX_VALUE);
0762: fail("List.remove should throw IndexOutOfBoundsException "
0763: + "[Integer.MAX_VALUE]");
0764: } catch (IndexOutOfBoundsException e) {
0765: // expected
0766: }
0767: }
0768:
0769: /**
0770: * Tests {@link List#remove(int)}.
0771: */
0772: public void testListRemoveByIndex() {
0773: if (!isRemoveSupported())
0774: return;
0775:
0776: int max = getFullElements().length;
0777: for (int i = 0; i < max; i++) {
0778: resetFull();
0779: Object o1 = ((List) collection).remove(i);
0780: Object o2 = ((List) confirmed).remove(i);
0781: assertEquals("remove should return correct element", o1, o2);
0782: verify();
0783: }
0784: }
0785:
0786: /**
0787: * Tests the read-only bits of {@link List#listIterator()}.
0788: */
0789: public void testListListIterator() {
0790: resetFull();
0791: forwardTest(getList().listIterator(), 0);
0792: backwardTest(getList().listIterator(), 0);
0793: }
0794:
0795: /**
0796: * Tests the read-only bits of {@link List#listIterator(int)}.
0797: */
0798: public void testListListIteratorByIndex() {
0799: resetFull();
0800: try {
0801: getList().listIterator(-1);
0802: } catch (IndexOutOfBoundsException ex) {
0803: }
0804: resetFull();
0805: try {
0806: getList().listIterator(getList().size() + 1);
0807: } catch (IndexOutOfBoundsException ex) {
0808: }
0809: resetFull();
0810: for (int i = 0; i <= confirmed.size(); i++) {
0811: forwardTest(getList().listIterator(i), i);
0812: backwardTest(getList().listIterator(i), i);
0813: }
0814: resetFull();
0815: for (int i = 0; i <= confirmed.size(); i++) {
0816: backwardTest(getList().listIterator(i), i);
0817: }
0818: }
0819:
0820: //-----------------------------------------------------------------------
0821: /**
0822: * Tests remove on list iterator is correct.
0823: */
0824: public void testListListIteratorPreviousRemoveNext() {
0825: if (isRemoveSupported() == false)
0826: return;
0827: resetFull();
0828: if (collection.size() < 4)
0829: return;
0830: ListIterator it = getList().listIterator();
0831: Object zero = it.next();
0832: Object one = it.next();
0833: Object two = it.next();
0834: Object two2 = it.previous();
0835: Object one2 = it.previous();
0836: assertEquals(one, one2);
0837: assertEquals(two, two2);
0838: assertEquals(zero, getList().get(0));
0839: assertEquals(one, getList().get(1));
0840: assertEquals(two, getList().get(2));
0841:
0842: it.remove(); // removed element at index 1 (one)
0843: assertEquals(zero, getList().get(0));
0844: assertEquals(two, getList().get(1));
0845: Object two3 = it.next(); // do next after remove
0846: assertEquals(two, two3);
0847: assertEquals(collection.size() > 2, it.hasNext());
0848: assertEquals(true, it.hasPrevious());
0849: }
0850:
0851: /**
0852: * Tests remove on list iterator is correct.
0853: */
0854: public void testListListIteratorPreviousRemovePrevious() {
0855: if (isRemoveSupported() == false)
0856: return;
0857: resetFull();
0858: if (collection.size() < 4)
0859: return;
0860: ListIterator it = getList().listIterator();
0861: Object zero = it.next();
0862: Object one = it.next();
0863: Object two = it.next();
0864: Object two2 = it.previous();
0865: Object one2 = it.previous();
0866: assertEquals(one, one2);
0867: assertEquals(two, two2);
0868: assertEquals(zero, getList().get(0));
0869: assertEquals(one, getList().get(1));
0870: assertEquals(two, getList().get(2));
0871:
0872: it.remove(); // removed element at index 1 (one)
0873: assertEquals(zero, getList().get(0));
0874: assertEquals(two, getList().get(1));
0875: Object zero3 = it.previous(); // do previous after remove
0876: assertEquals(zero, zero3);
0877: assertEquals(false, it.hasPrevious());
0878: assertEquals(collection.size() > 2, it.hasNext());
0879: }
0880:
0881: /**
0882: * Tests remove on list iterator is correct.
0883: */
0884: public void testListListIteratorNextRemoveNext() {
0885: if (isRemoveSupported() == false)
0886: return;
0887: resetFull();
0888: if (collection.size() < 4)
0889: return;
0890: ListIterator it = getList().listIterator();
0891: Object zero = it.next();
0892: Object one = it.next();
0893: Object two = it.next();
0894: assertEquals(zero, getList().get(0));
0895: assertEquals(one, getList().get(1));
0896: assertEquals(two, getList().get(2));
0897: Object three = getList().get(3);
0898:
0899: it.remove(); // removed element at index 2 (two)
0900: assertEquals(zero, getList().get(0));
0901: assertEquals(one, getList().get(1));
0902: Object three2 = it.next(); // do next after remove
0903: assertEquals(three, three2);
0904: assertEquals(collection.size() > 3, it.hasNext());
0905: assertEquals(true, it.hasPrevious());
0906: }
0907:
0908: /**
0909: * Tests remove on list iterator is correct.
0910: */
0911: public void testListListIteratorNextRemovePrevious() {
0912: if (isRemoveSupported() == false)
0913: return;
0914: resetFull();
0915: if (collection.size() < 4)
0916: return;
0917: ListIterator it = getList().listIterator();
0918: Object zero = it.next();
0919: Object one = it.next();
0920: Object two = it.next();
0921: assertEquals(zero, getList().get(0));
0922: assertEquals(one, getList().get(1));
0923: assertEquals(two, getList().get(2));
0924:
0925: it.remove(); // removed element at index 2 (two)
0926: assertEquals(zero, getList().get(0));
0927: assertEquals(one, getList().get(1));
0928: Object one2 = it.previous(); // do previous after remove
0929: assertEquals(one, one2);
0930: assertEquals(true, it.hasNext());
0931: assertEquals(true, it.hasPrevious());
0932: }
0933:
0934: //-----------------------------------------------------------------------
0935: /**
0936: * Traverses to the end of the given iterator.
0937: *
0938: * @param iter the iterator to traverse
0939: * @param i the starting index
0940: */
0941: private void forwardTest(ListIterator iter, int i) {
0942: List list = getList();
0943: int max = getFullElements().length;
0944:
0945: while (i < max) {
0946: assertTrue("Iterator should have next", iter.hasNext());
0947: assertEquals("Iterator.nextIndex should work", iter
0948: .nextIndex(), i);
0949: assertEquals("Iterator.previousIndex should work", iter
0950: .previousIndex(), i - 1);
0951: Object o = iter.next();
0952: assertEquals("Iterator returned correct element", list
0953: .get(i), o);
0954: i++;
0955: }
0956:
0957: assertTrue("Iterator shouldn't have next", !iter.hasNext());
0958: assertEquals("nextIndex should be size", iter.nextIndex(), max);
0959: assertEquals("previousIndex should be size - 1", iter
0960: .previousIndex(), max - 1);
0961:
0962: try {
0963: iter.next();
0964: fail("Exhausted iterator should raise NoSuchElement");
0965: } catch (NoSuchElementException e) {
0966: // expected
0967: }
0968: }
0969:
0970: /**
0971: * Traverses to the beginning of the given iterator.
0972: *
0973: * @param iter the iterator to traverse
0974: * @param i the starting index
0975: */
0976: private void backwardTest(ListIterator iter, int i) {
0977: List list = getList();
0978:
0979: while (i > 0) {
0980: assertTrue("Iterator should have previous, i:" + i, iter
0981: .hasPrevious());
0982: assertEquals("Iterator.nextIndex should work, i:" + i, iter
0983: .nextIndex(), i);
0984: assertEquals("Iterator.previousIndex should work, i:" + i,
0985: iter.previousIndex(), i - 1);
0986: Object o = iter.previous();
0987: assertEquals("Iterator returned correct element", list
0988: .get(i - 1), o);
0989: i--;
0990: }
0991:
0992: assertTrue("Iterator shouldn't have previous", !iter
0993: .hasPrevious());
0994: int nextIndex = iter.nextIndex();
0995: assertEquals("nextIndex should be 0, actual value: "
0996: + nextIndex, nextIndex, 0);
0997: int prevIndex = iter.previousIndex();
0998: assertEquals("previousIndex should be -1, actual value: "
0999: + prevIndex, prevIndex, -1);
1000:
1001: try {
1002: iter.previous();
1003: fail("Exhausted iterator should raise NoSuchElement");
1004: } catch (NoSuchElementException e) {
1005: // expected
1006: }
1007:
1008: }
1009:
1010: /**
1011: * Tests the {@link ListIterator#add(Object)} method of the list
1012: * iterator.
1013: */
1014: public void testListIteratorAdd() {
1015: if (!isAddSupported())
1016: return;
1017:
1018: resetEmpty();
1019: List list1 = getList();
1020: List list2 = getConfirmedList();
1021:
1022: Object[] elements = getFullElements();
1023: ListIterator iter1 = list1.listIterator();
1024: ListIterator iter2 = list2.listIterator();
1025:
1026: for (int i = 0; i < elements.length; i++) {
1027: iter1.add(elements[i]);
1028: iter2.add(elements[i]);
1029: verify();
1030: }
1031:
1032: resetFull();
1033: iter1 = getList().listIterator();
1034: iter2 = getConfirmedList().listIterator();
1035: for (int i = 0; i < elements.length; i++) {
1036: iter1.next();
1037: iter2.next();
1038: iter1.add(elements[i]);
1039: iter2.add(elements[i]);
1040: verify();
1041: }
1042: }
1043:
1044: /**
1045: * Tests the {@link ListIterator#set(Object)} method of the list
1046: * iterator.
1047: */
1048: public void testListIteratorSet() {
1049: if (!isSetSupported())
1050: return;
1051:
1052: Object[] elements = getFullElements();
1053:
1054: resetFull();
1055: ListIterator iter1 = getList().listIterator();
1056: ListIterator iter2 = getConfirmedList().listIterator();
1057: for (int i = 0; i < elements.length; i++) {
1058: iter1.next();
1059: iter2.next();
1060: iter1.set(elements[i]);
1061: iter2.set(elements[i]);
1062: verify();
1063: }
1064: }
1065:
1066: public void testEmptyListSerialization() throws IOException,
1067: ClassNotFoundException {
1068: List list = makeEmptyList();
1069: if (!(list instanceof Serializable && isTestSerialization()))
1070: return;
1071:
1072: byte[] objekt = writeExternalFormToBytes((Serializable) list);
1073: List list2 = (List) readExternalFormFromBytes(objekt);
1074:
1075: assertTrue("Both lists are empty", list.size() == 0);
1076: assertTrue("Both lists are empty", list2.size() == 0);
1077: }
1078:
1079: public void testFullListSerialization() throws IOException,
1080: ClassNotFoundException {
1081: List list = makeFullList();
1082: int size = getFullElements().length;
1083: if (!(list instanceof Serializable && isTestSerialization()))
1084: return;
1085:
1086: byte[] objekt = writeExternalFormToBytes((Serializable) list);
1087: List list2 = (List) readExternalFormFromBytes(objekt);
1088:
1089: assertEquals("Both lists are same size", list.size(), size);
1090: assertEquals("Both lists are same size", list2.size(), size);
1091: }
1092:
1093: /**
1094: * Compare the current serialized form of the List
1095: * against the canonical version in CVS.
1096: */
1097: public void testEmptyListCompatibility() throws IOException,
1098: ClassNotFoundException {
1099: /**
1100: * Create canonical objects with this code
1101: List list = makeEmptyList();
1102: if (!(list instanceof Serializable)) return;
1103:
1104: writeExternalFormToDisk((Serializable) list, getCanonicalEmptyCollectionName(list));
1105: */
1106:
1107: // test to make sure the canonical form has been preserved
1108: List list = makeEmptyList();
1109: if (list instanceof Serializable
1110: && !skipSerializedCanonicalTests()
1111: && isTestSerialization()) {
1112: List list2 = (List) readExternalFormFromDisk(getCanonicalEmptyCollectionName(list));
1113: assertTrue("List is empty", list2.size() == 0);
1114: assertEquals(list, list2);
1115: }
1116: }
1117:
1118: /**
1119: * Compare the current serialized form of the List
1120: * against the canonical version in CVS.
1121: */
1122: public void testFullListCompatibility() throws IOException,
1123: ClassNotFoundException {
1124: /**
1125: * Create canonical objects with this code
1126: List list = makeFullList();
1127: if (!(list instanceof Serializable)) return;
1128:
1129: writeExternalFormToDisk((Serializable) list, getCanonicalFullCollectionName(list));
1130: */
1131:
1132: // test to make sure the canonical form has been preserved
1133: List list = makeFullList();
1134: if (list instanceof Serializable
1135: && !skipSerializedCanonicalTests()
1136: && isTestSerialization()) {
1137: List list2 = (List) readExternalFormFromDisk(getCanonicalFullCollectionName(list));
1138: if (list2.size() == 4) {
1139: // old serialized tests
1140: return;
1141: }
1142: assertEquals("List is the right size", list.size(), list2
1143: .size());
1144: assertEquals(list, list2);
1145: }
1146: }
1147:
1148: //-----------------------------------------------------------------------
1149: /**
1150: * Returns a {@link BulkTest} for testing {@link List#subList(int,int)}.
1151: * The returned bulk test will run through every <code>TestList</code>
1152: * method, <i>including</i> another <code>bulkTestSubList</code>.
1153: * Sublists are tested until the size of the sublist is less than 10.
1154: * Each sublist is 6 elements smaller than its parent list.
1155: * (By default this means that two rounds of sublists will be tested).
1156: * The verify() method is overloaded to test that the original list is
1157: * modified when the sublist is.
1158: */
1159: public BulkTest bulkTestSubList() {
1160: if (getFullElements().length - 6 < 10)
1161: return null;
1162: return new BulkTestSubList(this );
1163: }
1164:
1165: public static class BulkTestSubList extends AbstractTestList {
1166:
1167: private AbstractTestList outer;
1168:
1169: public BulkTestSubList(AbstractTestList outer) {
1170: super ("");
1171: this .outer = outer;
1172: }
1173:
1174: public Object[] getFullElements() {
1175: List l = Arrays.asList(outer.getFullElements());
1176: return l.subList(3, l.size() - 3).toArray();
1177: }
1178:
1179: public Object[] getOtherElements() {
1180: return outer.getOtherElements();
1181: }
1182:
1183: public boolean isAddSupported() {
1184: return outer.isAddSupported();
1185: }
1186:
1187: public boolean isSetSupported() {
1188: return outer.isSetSupported();
1189: }
1190:
1191: public boolean isRemoveSupported() {
1192: return outer.isRemoveSupported();
1193: }
1194:
1195: public List makeEmptyList() {
1196: return outer.makeFullList().subList(4, 4);
1197: }
1198:
1199: public List makeFullList() {
1200: int size = getFullElements().length;
1201: return outer.makeFullList().subList(3, size - 3);
1202: }
1203:
1204: public void resetEmpty() {
1205: outer.resetFull();
1206: this .collection = outer.getList().subList(4, 4);
1207: this .confirmed = outer.getConfirmedList().subList(4, 4);
1208: }
1209:
1210: public void resetFull() {
1211: outer.resetFull();
1212: int size = outer.confirmed.size();
1213: this .collection = outer.getList().subList(3, size - 3);
1214: this .confirmed = outer.getConfirmedList().subList(3,
1215: size - 3);
1216: }
1217:
1218: public void verify() {
1219: super .verify();
1220: outer.verify();
1221: }
1222:
1223: public boolean isTestSerialization() {
1224: return false;
1225: }
1226: }
1227:
1228: /**
1229: * Tests that a sublist raises a {@link java.util.ConcurrentModificationException ConcurrentModificationException}
1230: * if elements are added to the original list.
1231: */
1232: public void testListSubListFailFastOnAdd() {
1233: if (!isFailFastSupported())
1234: return;
1235: if (!isAddSupported())
1236: return;
1237:
1238: resetFull();
1239: int size = collection.size();
1240: List sub = getList().subList(1, size);
1241: getList().add(getOtherElements()[0]);
1242: failFastAll(sub);
1243:
1244: resetFull();
1245: sub = getList().subList(1, size);
1246: getList().add(0, getOtherElements()[0]);
1247: failFastAll(sub);
1248:
1249: resetFull();
1250: sub = getList().subList(1, size);
1251: getList().addAll(Arrays.asList(getOtherElements()));
1252: failFastAll(sub);
1253:
1254: resetFull();
1255: sub = getList().subList(1, size);
1256: getList().addAll(0, Arrays.asList(getOtherElements()));
1257: failFastAll(sub);
1258:
1259: }
1260:
1261: /**
1262: * Tests that a sublist raises a {@link java.util.ConcurrentModificationException ConcurrentModificationException}
1263: * if elements are removed from the original list.
1264: */
1265: public void testListSubListFailFastOnRemove() {
1266: if (!isFailFastSupported())
1267: return;
1268: if (!isRemoveSupported())
1269: return;
1270:
1271: resetFull();
1272: int size = collection.size();
1273: List sub = getList().subList(1, size);
1274: getList().remove(0);
1275: failFastAll(sub);
1276:
1277: resetFull();
1278: sub = getList().subList(1, size);
1279: getList().remove(getFullElements()[2]);
1280: failFastAll(sub);
1281:
1282: resetFull();
1283: sub = getList().subList(1, size);
1284: getList().removeAll(Arrays.asList(getFullElements()));
1285: failFastAll(sub);
1286:
1287: resetFull();
1288: sub = getList().subList(1, size);
1289: getList().retainAll(Arrays.asList(getOtherElements()));
1290: failFastAll(sub);
1291:
1292: resetFull();
1293: sub = getList().subList(1, size);
1294: getList().clear();
1295: failFastAll(sub);
1296: }
1297:
1298: /**
1299: * Invokes all the methods on the given sublist to make sure they raise
1300: * a {@link java.util.ConcurrentModificationException ConcurrentModificationException}.
1301: */
1302: protected void failFastAll(List list) {
1303: Method[] methods = List.class.getMethods();
1304: for (int i = 0; i < methods.length; i++) {
1305: failFastMethod(list, methods[i]);
1306: }
1307: }
1308:
1309: /**
1310: * Invokes the given method on the given sublist to make sure it raises
1311: * a {@link java.util.ConcurrentModificationException ConcurrentModificationException}.
1312: *
1313: * Unless the method happens to be the equals() method, in which case
1314: * the test is skipped. There seems to be a bug in
1315: * java.util.AbstractList.subList(int,int).equals(Object) -- it never
1316: * raises a ConcurrentModificationException.
1317: *
1318: * @param list the sublist to test
1319: * @param m the method to invoke
1320: */
1321: protected void failFastMethod(List list, Method m) {
1322: if (m.getName().equals("equals"))
1323: return;
1324:
1325: Object element = getOtherElements()[0];
1326: Collection c = Collections.singleton(element);
1327:
1328: Class[] types = m.getParameterTypes();
1329: Object[] params = new Object[types.length];
1330: for (int i = 0; i < params.length; i++) {
1331: if (types[i] == Integer.TYPE)
1332: params[i] = new Integer(0);
1333: else if (types[i] == Collection.class)
1334: params[i] = c;
1335: else if (types[i] == Object.class)
1336: params[i] = element;
1337: else if (types[i] == Object[].class)
1338: params[i] = new Object[0];
1339: }
1340:
1341: try {
1342: m.invoke(list, params);
1343: fail(m.getName() + " should raise ConcurrentModification");
1344: } catch (IllegalAccessException e) {
1345: // impossible
1346: } catch (InvocationTargetException e) {
1347: Throwable t = e.getTargetException();
1348: if (t instanceof ConcurrentModificationException) {
1349: // expected
1350: return;
1351: } else {
1352: fail(m.getName() + " raised unexpected " + e);
1353: }
1354: }
1355: }
1356:
1357: //-----------------------------------------------------------------------
1358: public BulkTest bulkTestListIterator() {
1359: return new TestListIterator();
1360: }
1361:
1362: public class TestListIterator extends AbstractTestListIterator {
1363: public TestListIterator() {
1364: super ("TestListIterator");
1365: }
1366:
1367: public Object addSetValue() {
1368: return AbstractTestList.this .getOtherElements()[0];
1369: }
1370:
1371: public boolean supportsRemove() {
1372: return AbstractTestList.this .isRemoveSupported();
1373: }
1374:
1375: public boolean supportsAdd() {
1376: return AbstractTestList.this .isAddSupported();
1377: }
1378:
1379: public boolean supportsSet() {
1380: return AbstractTestList.this .isSetSupported();
1381: }
1382:
1383: public ListIterator makeEmptyListIterator() {
1384: resetEmpty();
1385: return ((List) AbstractTestList.this .collection)
1386: .listIterator();
1387: }
1388:
1389: public ListIterator makeFullListIterator() {
1390: resetFull();
1391: return ((List) AbstractTestList.this.collection)
1392: .listIterator();
1393: }
1394: }
1395:
1396: }
|