The Commons Collections AbstractTestList.java source code
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections.list;
import java.io.IOException;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.AbstractCollection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.NoSuchElementException;
import org.apache.commons.collections.BulkTest;
import org.apache.commons.collections.collection.AbstractTestCollection;
import org.apache.commons.collections.iterators.AbstractTestListIterator;
/**
* Abstract test class for {@link java.util.List} methods and contracts.
* <p>
* To use, simply extend this class, and implement
* the {@link #makeEmptyList} method.
* <p>
* If your {@link List} fails one of these tests by design,
* you may still use this base set of cases. Simply override the
* test case (method) your {@link List} fails or override one of the
* protected methods from AbstractTestCollection.
*
* @version $Revision: 646780 $ $Date: 2008-04-10 13:48:07 +0100 (Thu, 10 Apr 2008) $
*
* @author Rodney Waldhoff
* @author Paul Jack
* @author Stephen Colebourne
* @author Neil O'Toole
*/
public abstract class AbstractTestList extends AbstractTestCollection {
/**
* JUnit constructor.
*
* @param testName the test class name
*/
public AbstractTestList(String testName) {
super(testName);
}
//-----------------------------------------------------------------------
/**
* Returns true if the collections produced by
* {@link #makeCollection()} and {@link #makeFullCollection()}
* support the <code>set operation.
* Default implementation returns true. Override if your collection
* class does not support set.
*/
public boolean isSetSupported() {
return true;
}
//-----------------------------------------------------------------------
/**
* Verifies that the test list implementation matches the confirmed list
* implementation.
*/
public void verify() {
super.verify();
List list1 = getList();
List list2 = getConfirmedList();
assertEquals("List should equal confirmed", list1, list2);
assertEquals("Confirmed should equal list", list2, list1);
assertEquals("Hash codes should be equal", list1.hashCode(), list2.hashCode());
int i = 0;
Iterator iterator1 = list1.iterator();
Iterator iterator2 = list2.iterator();
Object[] array = list1.toArray();
while (iterator2.hasNext()) {
assertTrue("List iterator should have next", iterator1.hasNext());
Object o1 = iterator1.next();
Object o2 = iterator2.next();
assertEquals("Iterator elements should be equal", o1, o2);
o2 = list1.get(i);
assertEquals("get should return correct element", o1, o2);
o2 = array[i];
assertEquals("toArray should have correct element", o1, o2);
i++;
}
}
//-----------------------------------------------------------------------
/**
* List equals method is defined.
*/
public boolean isEqualsCheckable() {
return true;
}
/**
* Returns an empty {@link ArrayList}.
*/
public Collection makeConfirmedCollection() {
ArrayList list = new ArrayList();
return list;
}
/**
* Returns a full {@link ArrayList}.
*/
public Collection makeConfirmedFullCollection() {
ArrayList list = new ArrayList();
list.addAll(Arrays.asList(getFullElements()));
return list;
}
/**
* Return a new, empty {@link List} to be used for testing.
*
* @return an empty list for testing.
*/
public abstract List makeEmptyList();
/**
* Return a new, full {@link List} to be used for testing.
*
* @return a full list for testing
*/
public List makeFullList() {
// only works if list supports optional "addAll(Collection)"
List list = makeEmptyList();
list.addAll(Arrays.asList(getFullElements()));
return list;
}
/**
* Returns {@link #makeEmptyList()}.
*
* @return an empty list to be used for testing
*/
public final Collection makeCollection() {
return makeEmptyList();
}
/**
* Returns {@link #makeFullList()}.
*
* @return a full list to be used for testing
*/
public final Collection makeFullCollection() {
return makeFullList();
}
//-----------------------------------------------------------------------
/**
* Returns the {@link #collection} field cast to a {@link List}.
*
* @return the collection field as a List
*/
public List getList() {
return (List) collection;
}
/**
* Returns the {@link #confirmed} field cast to a {@link List}.
*
* @return the confirmed field as a List
*/
public List getConfirmedList() {
return (List) confirmed;
}
//-----------------------------------------------------------------------
/**
* Tests bounds checking for {@link List#add(int, Object)} on an
* empty list.
*/
public void testListAddByIndexBoundsChecking() {
if (!isAddSupported()) {
return;
}
List list;
Object element = getOtherElements()[0];
try {
list = makeEmptyList();
list.add(Integer.MIN_VALUE, element);
fail("List.add should throw IndexOutOfBoundsException [Integer.MIN_VALUE]");
} catch (IndexOutOfBoundsException e) {
// expected
}
try {
list = makeEmptyList();
list.add(-1, element);
fail("List.add should throw IndexOutOfBoundsException [-1]");
} catch (IndexOutOfBoundsException e) {
// expected
}
try {
list = makeEmptyList();
list.add(1, element);
fail("List.add should throw IndexOutOfBoundsException [1]");
} catch (IndexOutOfBoundsException e) {
// expected
}
try {
list = makeEmptyList();
list.add(Integer.MAX_VALUE, element);
fail("List.add should throw IndexOutOfBoundsException [Integer.MAX_VALUE]");
} catch (IndexOutOfBoundsException e) {
// expected
}
}
/**
* Tests bounds checking for {@link List#add(int, Object)} on a
* full list.
*/
public void testListAddByIndexBoundsChecking2() {
if (!isAddSupported()) {
return;
}
List list;
Object element = getOtherElements()[0];
try {
list = makeFullList();
list.add(Integer.MIN_VALUE, element);
fail("List.add should throw IndexOutOfBoundsException [Integer.MIN_VALUE]");
} catch (IndexOutOfBoundsException e) {
// expected
}
try {
list = makeFullList();
list.add(-1, element);
fail("List.add should throw IndexOutOfBoundsException [-1]");
} catch (IndexOutOfBoundsException e) {
// expected
}
try {
list = makeFullList();
list.add(list.size() + 1, element);
fail("List.add should throw IndexOutOfBoundsException [size + 1]");
} catch (IndexOutOfBoundsException e) {
// expected
}
try {
list = makeFullList();
list.add(Integer.MAX_VALUE, element);
fail("List.add should throw IndexOutOfBoundsException [Integer.MAX_VALUE]");
} catch (IndexOutOfBoundsException e) {
// expected
}
}
/**
* Tests {@link List#add(int,Object)}.
*/
public void testListAddByIndex() {
if (!isAddSupported()) {
return;
}
Object element = getOtherElements()[0];
int max = getFullElements().length;
for (int i = 0; i <= max; i++) {
resetFull();
((List) collection).add(i, element);
((List) confirmed).add(i, element);
verify();
}
}
/**
* Tests {@link List#equals(Object)}.
*/
public void testListEquals() {
resetEmpty();
List list = getList();
assertEquals("Empty lists should be equal", true, list.equals(confirmed));
verify();
assertEquals("Empty list should equal self", true, list.equals(list));
verify();
List list2 = Arrays.asList(getFullElements());
assertEquals("Empty list shouldn't equal full", false, list.equals(list2));
verify();
list2 = Arrays.asList(getOtherElements());
assertEquals("Empty list shouldn't equal other", false, list.equals(list2));
verify();
resetFull();
list = getList();
assertEquals("Full lists should be equal", true, list.equals(confirmed));
verify();
assertEquals("Full list should equal self", true, list.equals(list));
verify();
list2 = makeEmptyList();
assertEquals("Full list shouldn't equal empty", false, list.equals(list2));
verify();
list2 = Arrays.asList(getOtherElements());
assertEquals("Full list shouldn't equal other", false, list.equals(list2));
verify();
list2 = Arrays.asList(getFullElements());
if (list2.size() < 2 && isAddSupported()) {
// main list is only size 1, so lets add other elements to get a better list
list.addAll(Arrays.asList(getOtherElements()));
confirmed.addAll(Arrays.asList(getOtherElements()));
list2 = new ArrayList(list2);
list2.addAll(Arrays.asList(getOtherElements()));
}
if (list2.size() > 1) {
Collections.reverse(list2);
assertEquals(
"Full list shouldn't equal full list with same elements but different order",
false, list.equals(list2));
verify();
}
resetFull();
list = getList();
assertEquals("List shouldn't equal String", false, list.equals(""));
verify();
final List listForC = Arrays.asList(getFullElements());
Collection c = new AbstractCollection() {
public int size() {
return listForC.size();
}
public Iterator iterator() {
return listForC.iterator();
}
};
assertEquals("List shouldn't equal nonlist with same elements in same order", false, list.equals(c));
verify();
}
/**
* Tests {@link List#hashCode()}.
*/
public void testListHashCode() {
resetEmpty();
int hash1 = collection.hashCode();
int hash2 = confirmed.hashCode();
assertEquals("Empty lists should have equal hashCodes", hash1, hash2);
verify();
resetFull();
hash1 = collection.hashCode();
hash2 = confirmed.hashCode();
assertEquals("Full lists should have equal hashCodes", hash1, hash2);
verify();
}
/**
* Tests {@link List#get(int)}.
*/
public void testListGetByIndex() {
resetFull();
List list = getList();
Object[] elements = getFullElements();
for (int i = 0; i < elements.length; i++) {
assertEquals("List should contain correct elements", elements[i], list.get(i));
verify();
}
}
/**
* Tests bounds checking for {@link List#get(int)} on an
* empty list.
*/
public void testListGetByIndexBoundsChecking() {
List list = makeEmptyList();
try {
list.get(Integer.MIN_VALUE);
fail("List.get should throw IndexOutOfBoundsException [Integer.MIN_VALUE]");
} catch (IndexOutOfBoundsException e) {
// expected
}
try {
list.get(-1);
fail("List.get should throw IndexOutOfBoundsException [-1]");
} catch (IndexOutOfBoundsException e) {
// expected
}
try {
list.get(0);
fail("List.get should throw IndexOutOfBoundsException [0]");
} catch (IndexOutOfBoundsException e) {
// expected
}
try {
list.get(1);
fail("List.get should throw IndexOutOfBoundsException [1]");
} catch (IndexOutOfBoundsException e) {
// expected
}
try {
list.get(Integer.MAX_VALUE);
fail("List.get should throw IndexOutOfBoundsException [Integer.MAX_VALUE]");
} catch (IndexOutOfBoundsException e) {
// expected
}
}
/**
* Tests bounds checking for {@link List#get(int)} on a
* full list.
*/
public void testListGetByIndexBoundsChecking2() {
List list = makeFullList();
try {
list.get(Integer.MIN_VALUE);
fail("List.get should throw IndexOutOfBoundsException [Integer.MIN_VALUE]");
} catch (IndexOutOfBoundsException e) {
// expected
}
try {
list.get(-1);
fail("List.get should throw IndexOutOfBoundsException [-1]");
} catch (IndexOutOfBoundsException e) {
// expected
}
try {
list.get(getFullElements().length);
fail("List.get should throw IndexOutOfBoundsException [size]");
} catch (IndexOutOfBoundsException e) {
// expected
}
try {
list.get(Integer.MAX_VALUE);
fail("List.get should throw IndexOutOfBoundsException [Integer.MAX_VALUE]");
} catch (IndexOutOfBoundsException e) {
// expected
}
}
/**
* Tests {@link List#indexOf}.
*/
public void testListIndexOf() {
resetFull();
List list1 = getList();
List list2 = getConfirmedList();
Iterator iterator = list2.iterator();
while (iterator.hasNext()) {
Object element = iterator.next();
assertEquals("indexOf should return correct result",
list1.indexOf(element), list2.indexOf(element));
verify();
}
Object[] other = getOtherElements();
for (int i = 0; i < other.length; i++) {
assertEquals("indexOf should return -1 for nonexistent element",
list1.indexOf(other[i]), -1);
verify();
}
}
/**
* Tests {@link List#lastIndexOf}.
*/
public void testListLastIndexOf() {
resetFull();
List list1 = getList();
List list2 = getConfirmedList();
Iterator iterator = list2.iterator();
while (iterator.hasNext()) {
Object element = iterator.next();
assertEquals("lastIndexOf should return correct result",
list1.lastIndexOf(element), list2.lastIndexOf(element));
verify();
}
Object[] other = getOtherElements();
for (int i = 0; i < other.length; i++) {
assertEquals("lastIndexOf should return -1 for nonexistent " +
"element", list1.lastIndexOf(other[i]), -1);
verify();
}
}
/**
* Tests bounds checking for {@link List#set(int,Object)} on an
* empty list.
*/
public void testListSetByIndexBoundsChecking() {
if (!isSetSupported()) {
return;
}
List list = makeEmptyList();
Object element = getOtherElements()[0];
try {
list.set(Integer.MIN_VALUE, element);
fail("List.set should throw IndexOutOfBoundsException [Integer.MIN_VALUE]");
} catch (IndexOutOfBoundsException e) {
// expected
}
try {
list.set(-1, element);
fail("List.set should throw IndexOutOfBoundsException [-1]");
} catch (IndexOutOfBoundsException e) {
// expected
}
try {
list.set(0, element);
fail("List.set should throw IndexOutOfBoundsException [0]");
} catch (IndexOutOfBoundsException e) {
// expected
}
try {
list.set(1, element);
fail("List.set should throw IndexOutOfBoundsException [1]");
} catch (IndexOutOfBoundsException e) {
// expected
}
try {
list.set(Integer.MAX_VALUE, element);
fail("List.set should throw IndexOutOfBoundsException [Integer.MAX_VALUE]");
} catch (IndexOutOfBoundsException e) {
// expected
}
}
/**
* Tests bounds checking for {@link List#set(int,Object)} on a
* full list.
*/
public void testListSetByIndexBoundsChecking2() {
if (!isSetSupported()) return;
List list = makeFullList();
Object element = getOtherElements()[0];
try {
list.set(Integer.MIN_VALUE, element);
fail("List.set should throw IndexOutOfBoundsException " +
"[Integer.MIN_VALUE]");
} catch(IndexOutOfBoundsException e) {
// expected
}
try {
list.set(-1, element);
fail("List.set should throw IndexOutOfBoundsException [-1]");
} catch(IndexOutOfBoundsException e) {
// expected
}
try {
list.set(getFullElements().length, element);
fail("List.set should throw IndexOutOfBoundsException [size]");
} catch(IndexOutOfBoundsException e) {
// expected
}
try {
list.set(Integer.MAX_VALUE, element);
fail("List.set should throw IndexOutOfBoundsException " +
"[Integer.MAX_VALUE]");
} catch(IndexOutOfBoundsException e) {
// expected
}
}
/**
* Test {@link List#set(int,Object)}.
*/
public void testListSetByIndex() {
if (!isSetSupported()) return;
resetFull();
Object[] elements = getFullElements();
Object[] other = getOtherElements();
for (int i = 0; i < elements.length; i++) {
Object n = other[i % other.length];
Object v = ((List)collection).set(i, n);
assertEquals("Set should return correct element", elements[i], v);
((List)confirmed).set(i, n);
verify();
}
}
/**
* If {@link #isSetSupported()} returns false, tests that set operation
* raises <Code>UnsupportedOperationException.
*/
public void testUnsupportedSet() {
if (isSetSupported()) return;
resetFull();
try {
((List) collection).set(0, new Object());
fail("Emtpy collection should not support set.");
} catch (UnsupportedOperationException e) {
// expected
}
// make sure things didn't change even if the expected exception was
// thrown.
verify();
}
/**
* Tests bounds checking for {@link List#remove(int)} on an
* empty list.
*/
public void testListRemoveByIndexBoundsChecking() {
if (!isRemoveSupported()) return;
List list = makeEmptyList();
try {
list.remove(Integer.MIN_VALUE);
fail("List.remove should throw IndexOutOfBoundsException " +
"[Integer.MIN_VALUE]");
} catch(IndexOutOfBoundsException e) {
// expected
}
try {
list.remove(-1);
fail("List.remove should throw IndexOutOfBoundsException [-1]");
} catch(IndexOutOfBoundsException e) {
// expected
}
try {
list.remove(0);
fail("List.remove should throw IndexOutOfBoundsException [0]");
} catch(IndexOutOfBoundsException e) {
// expected
}
try {
list.remove(1);
fail("List.remove should throw IndexOutOfBoundsException [1]");
} catch(IndexOutOfBoundsException e) {
// expected
}
try {
list.remove(Integer.MAX_VALUE);
fail("List.remove should throw IndexOutOfBoundsException " +
"[Integer.MAX_VALUE]");
} catch(IndexOutOfBoundsException e) {
// expected
}
}
/**
* Tests bounds checking for {@link List#remove(int)} on a
* full list.
*/
public void testListRemoveByIndexBoundsChecking2() {
if (!isRemoveSupported()) return;
List list = makeFullList();
try {
list.remove(Integer.MIN_VALUE);
fail("List.remove should throw IndexOutOfBoundsException " +
"[Integer.MIN_VALUE]");
} catch(IndexOutOfBoundsException e) {
// expected
}
try {
list.remove(-1);
fail("List.remove should throw IndexOutOfBoundsException [-1]");
} catch(IndexOutOfBoundsException e) {
// expected
}
try {
list.remove(getFullElements().length);
fail("List.remove should throw IndexOutOfBoundsException [size]");
} catch(IndexOutOfBoundsException e) {
// expected
}
try {
list.remove(Integer.MAX_VALUE);
fail("List.remove should throw IndexOutOfBoundsException " +
"[Integer.MAX_VALUE]");
} catch(IndexOutOfBoundsException e) {
// expected
}
}
/**
* Tests {@link List#remove(int)}.
*/
public void testListRemoveByIndex() {
if (!isRemoveSupported()) return;
int max = getFullElements().length;
for (int i = 0; i < max; i++) {
resetFull();
Object o1 = ((List)collection).remove(i);
Object o2 = ((List)confirmed).remove(i);
assertEquals("remove should return correct element", o1, o2);
verify();
}
}
/**
* Tests the read-only bits of {@link List#listIterator()}.
*/
public void testListListIterator() {
resetFull();
forwardTest(getList().listIterator(), 0);
backwardTest(getList().listIterator(), 0);
}
/**
* Tests the read-only bits of {@link List#listIterator(int)}.
*/
public void testListListIteratorByIndex() {
resetFull();
try {
getList().listIterator(-1);
} catch (IndexOutOfBoundsException ex) {}
resetFull();
try {
getList().listIterator(getList().size() + 1);
} catch (IndexOutOfBoundsException ex) {}
resetFull();
for (int i = 0; i <= confirmed.size(); i++) {
forwardTest(getList().listIterator(i), i);
backwardTest(getList().listIterator(i), i);
}
resetFull();
for (int i = 0; i <= confirmed.size(); i++) {
backwardTest(getList().listIterator(i), i);
}
}
//-----------------------------------------------------------------------
/**
* Tests remove on list iterator is correct.
*/
public void testListListIteratorPreviousRemoveNext() {
if (isRemoveSupported() == false) return;
resetFull();
if (collection.size() < 4) return;
ListIterator it = getList().listIterator();
Object zero = it.next();
Object one = it.next();
Object two = it.next();
Object two2 = it.previous();
Object one2 = it.previous();
assertEquals(one, one2);
assertEquals(two, two2);
assertEquals(zero, getList().get(0));
assertEquals(one, getList().get(1));
assertEquals(two, getList().get(2));
it.remove(); // removed element at index 1 (one)
assertEquals(zero, getList().get(0));
assertEquals(two, getList().get(1));
Object two3 = it.next(); // do next after remove
assertEquals(two, two3);
assertEquals(collection.size() > 2, it.hasNext());
assertEquals(true, it.hasPrevious());
}
/**
* Tests remove on list iterator is correct.
*/
public void testListListIteratorPreviousRemovePrevious() {
if (isRemoveSupported() == false) return;
resetFull();
if (collection.size() < 4) return;
ListIterator it = getList().listIterator();
Object zero = it.next();
Object one = it.next();
Object two = it.next();
Object two2 = it.previous();
Object one2 = it.previous();
assertEquals(one, one2);
assertEquals(two, two2);
assertEquals(zero, getList().get(0));
assertEquals(one, getList().get(1));
assertEquals(two, getList().get(2));
it.remove(); // removed element at index 1 (one)
assertEquals(zero, getList().get(0));
assertEquals(two, getList().get(1));
Object zero3 = it.previous(); // do previous after remove
assertEquals(zero, zero3);
assertEquals(false, it.hasPrevious());
assertEquals(collection.size() > 2, it.hasNext());
}
/**
* Tests remove on list iterator is correct.
*/
public void testListListIteratorNextRemoveNext() {
if (isRemoveSupported() == false) return;
resetFull();
if (collection.size() < 4) return;
ListIterator it = getList().listIterator();
Object zero = it.next();
Object one = it.next();
Object two = it.next();
assertEquals(zero, getList().get(0));
assertEquals(one, getList().get(1));
assertEquals(two, getList().get(2));
Object three = getList().get(3);
it.remove(); // removed element at index 2 (two)
assertEquals(zero, getList().get(0));
assertEquals(one, getList().get(1));
Object three2 = it.next(); // do next after remove
assertEquals(three, three2);
assertEquals(collection.size() > 3, it.hasNext());
assertEquals(true, it.hasPrevious());
}
/**
* Tests remove on list iterator is correct.
*/
public void testListListIteratorNextRemovePrevious() {
if (isRemoveSupported() == false) return;
resetFull();
if (collection.size() < 4) return;
ListIterator it = getList().listIterator();
Object zero = it.next();
Object one = it.next();
Object two = it.next();
assertEquals(zero, getList().get(0));
assertEquals(one, getList().get(1));
assertEquals(two, getList().get(2));
it.remove(); // removed element at index 2 (two)
assertEquals(zero, getList().get(0));
assertEquals(one, getList().get(1));
Object one2 = it.previous(); // do previous after remove
assertEquals(one, one2);
assertEquals(true, it.hasNext());
assertEquals(true, it.hasPrevious());
}
//-----------------------------------------------------------------------
/**
* Traverses to the end of the given iterator.
*
* @param iter the iterator to traverse
* @param i the starting index
*/
private void forwardTest(ListIterator iter, int i) {
List list = getList();
int max = getFullElements().length;
while (i < max) {
assertTrue("Iterator should have next", iter.hasNext());
assertEquals("Iterator.nextIndex should work",
iter.nextIndex(), i);
assertEquals("Iterator.previousIndex should work",
iter.previousIndex(), i - 1);
Object o = iter.next();
assertEquals("Iterator returned correct element", list.get(i), o);
i++;
}
assertTrue("Iterator shouldn't have next", !iter.hasNext());
assertEquals("nextIndex should be size", iter.nextIndex(), max);
assertEquals("previousIndex should be size - 1",
iter.previousIndex(), max - 1);
try {
iter.next();
fail("Exhausted iterator should raise NoSuchElement");
} catch (NoSuchElementException e) {
// expected
}
}
/**
* Traverses to the beginning of the given iterator.
*
* @param iter the iterator to traverse
* @param i the starting index
*/
private void backwardTest(ListIterator iter, int i) {
List list = getList();
while (i > 0) {
assertTrue("Iterator should have previous, i:" + i, iter.hasPrevious());
assertEquals("Iterator.nextIndex should work, i:" + i, iter.nextIndex(), i);
assertEquals("Iterator.previousIndex should work, i:" + i, iter.previousIndex(), i - 1);
Object o = iter.previous();
assertEquals("Iterator returned correct element", list.get(i - 1), o);
i--;
}
assertTrue("Iterator shouldn't have previous", !iter.hasPrevious());
int nextIndex = iter.nextIndex();
assertEquals("nextIndex should be 0, actual value: " + nextIndex, nextIndex, 0);
int prevIndex = iter.previousIndex();
assertEquals("previousIndex should be -1, actual value: " + prevIndex, prevIndex, -1);
try {
iter.previous();
fail("Exhausted iterator should raise NoSuchElement");
} catch (NoSuchElementException e) {
// expected
}
}
/**
* Tests the {@link ListIterator#add(Object)} method of the list
* iterator.
*/
public void testListIteratorAdd() {
if (!isAddSupported()) return;
resetEmpty();
List list1 = getList();
List list2 = getConfirmedList();
Object[] elements = getFullElements();
ListIterator iter1 = list1.listIterator();
ListIterator iter2 = list2.listIterator();
for (int i = 0; i < elements.length; i++) {
iter1.add(elements[i]);
iter2.add(elements[i]);
verify();
}
resetFull();
iter1 = getList().listIterator();
iter2 = getConfirmedList().listIterator();
for (int i = 0; i < elements.length; i++) {
iter1.next();
iter2.next();
iter1.add(elements[i]);
iter2.add(elements[i]);
verify();
}
}
/**
* Tests the {@link ListIterator#set(Object)} method of the list
* iterator.
*/
public void testListIteratorSet() {
if (!isSetSupported()) return;
Object[] elements = getFullElements();
resetFull();
ListIterator iter1 = getList().listIterator();
ListIterator iter2 = getConfirmedList().listIterator();
for (int i = 0; i < elements.length; i++) {
iter1.next();
iter2.next();
iter1.set(elements[i]);
iter2.set(elements[i]);
verify();
}
}
public void testEmptyListSerialization()
throws IOException, ClassNotFoundException {
List list = makeEmptyList();
if (!(list instanceof Serializable && isTestSerialization())) return;
byte[] objekt = writeExternalFormToBytes((Serializable) list);
List list2 = (List) readExternalFormFromBytes(objekt);
assertTrue("Both lists are empty",list.size() == 0);
assertTrue("Both lists are empty",list2.size() == 0);
}
public void testFullListSerialization()
throws IOException, ClassNotFoundException {
List list = makeFullList();
int size = getFullElements().length;
if (!(list instanceof Serializable && isTestSerialization())) return;
byte[] objekt = writeExternalFormToBytes((Serializable) list);
List list2 = (List) readExternalFormFromBytes(objekt);
assertEquals("Both lists are same size",list.size(), size);
assertEquals("Both lists are same size",list2.size(), size);
}
/**
* Compare the current serialized form of the List
* against the canonical version in CVS.
*/
public void testEmptyListCompatibility() throws IOException, ClassNotFoundException {
/**
* Create canonical objects with this code
List list = makeEmptyList();
if (!(list instanceof Serializable)) return;
writeExternalFormToDisk((Serializable) list, getCanonicalEmptyCollectionName(list));
*/
// test to make sure the canonical form has been preserved
List list = makeEmptyList();
if(list instanceof Serializable && !skipSerializedCanonicalTests() && isTestSerialization()) {
List list2 = (List) readExternalFormFromDisk(getCanonicalEmptyCollectionName(list));
assertTrue("List is empty",list2.size() == 0);
assertEquals(list, list2);
}
}
/**
* Compare the current serialized form of the List
* against the canonical version in CVS.
*/
public void testFullListCompatibility() throws IOException, ClassNotFoundException {
/**
* Create canonical objects with this code
List list = makeFullList();
if (!(list instanceof Serializable)) return;
writeExternalFormToDisk((Serializable) list, getCanonicalFullCollectionName(list));
*/
// test to make sure the canonical form has been preserved
List list = makeFullList();
if(list instanceof Serializable && !skipSerializedCanonicalTests() && isTestSerialization()) {
List list2 = (List) readExternalFormFromDisk(getCanonicalFullCollectionName(list));
if (list2.size() == 4) {
// old serialized tests
return;
}
assertEquals("List is the right size",list.size(), list2.size());
assertEquals(list, list2);
}
}
//-----------------------------------------------------------------------
/**
* Returns a {@link BulkTest} for testing {@link List#subList(int,int)}.
* The returned bulk test will run through every <code>TestList
* method, <i>including another bulkTestSubList
.
* Sublists are tested until the size of the sublist is less than 10.
* Each sublist is 6 elements smaller than its parent list.
* (By default this means that two rounds of sublists will be tested).
* The verify() method is overloaded to test that the original list is
* modified when the sublist is.
*/
public BulkTest bulkTestSubList() {
if (getFullElements().length - 6 < 10) return null;
return new BulkTestSubList(this);
}
public static class BulkTestSubList extends AbstractTestList {
private AbstractTestList outer;
public BulkTestSubList(AbstractTestList outer) {
super("");
this.outer = outer;
}
public Object[] getFullElements() {
List l = Arrays.asList(outer.getFullElements());
return l.subList(3, l.size() - 3).toArray();
}
public Object[] getOtherElements() {
return outer.getOtherElements();
}
public boolean isAddSupported() {
return outer.isAddSupported();
}
public boolean isSetSupported() {
return outer.isSetSupported();
}
public boolean isRemoveSupported() {
return outer.isRemoveSupported();
}
public List makeEmptyList() {
return outer.makeFullList().subList(4, 4);
}
public List makeFullList() {
int size = getFullElements().length;
return outer.makeFullList().subList(3, size - 3);
}
public void resetEmpty() {
outer.resetFull();
this.collection = outer.getList().subList(4, 4);
this.confirmed = outer.getConfirmedList().subList(4, 4);
}
public void resetFull() {
outer.resetFull();
int size = outer.confirmed.size();
this.collection = outer.getList().subList(3, size - 3);
this.confirmed = outer.getConfirmedList().subList(3, size - 3);
}
public void verify() {
super.verify();
outer.verify();
}
public boolean isTestSerialization() {
return false;
}
}
/**
* Tests that a sublist raises a {@link java.util.ConcurrentModificationException ConcurrentModificationException}
* if elements are added to the original list.
*/
public void testListSubListFailFastOnAdd() {
if (!isFailFastSupported()) return;
if (!isAddSupported()) return;
resetFull();
int size = collection.size();
List sub = getList().subList(1, size);
getList().add(getOtherElements()[0]);
failFastAll(sub);
resetFull();
sub = getList().subList(1, size);
getList().add(0, getOtherElements()[0]);
failFastAll(sub);
resetFull();
sub = getList().subList(1, size);
getList().addAll(Arrays.asList(getOtherElements()));
failFastAll(sub);
resetFull();
sub = getList().subList(1, size);
getList().addAll(0, Arrays.asList(getOtherElements()));
failFastAll(sub);
}
/**
* Tests that a sublist raises a {@link java.util.ConcurrentModificationException ConcurrentModificationException}
* if elements are removed from the original list.
*/
public void testListSubListFailFastOnRemove() {
if (!isFailFastSupported()) return;
if (!isRemoveSupported()) return;
resetFull();
int size = collection.size();
List sub = getList().subList(1, size);
getList().remove(0);
failFastAll(sub);
resetFull();
sub = getList().subList(1, size);
getList().remove(getFullElements()[2]);
failFastAll(sub);
resetFull();
sub = getList().subList(1, size);
getList().removeAll(Arrays.asList(getFullElements()));
failFastAll(sub);
resetFull();
sub = getList().subList(1, size);
getList().retainAll(Arrays.asList(getOtherElements()));
failFastAll(sub);
resetFull();
sub = getList().subList(1, size);
getList().clear();
failFastAll(sub);
}
/**
* Invokes all the methods on the given sublist to make sure they raise
* a {@link java.util.ConcurrentModificationException ConcurrentModificationException}.
*/
protected void failFastAll(List list) {
Method[] methods = List.class.getMethods();
for (int i = 0; i < methods.length; i++) {
failFastMethod(list, methods[i]);
}
}
/**
* Invokes the given method on the given sublist to make sure it raises
* a {@link java.util.ConcurrentModificationException ConcurrentModificationException}.
*
* Unless the method happens to be the equals() method, in which case
* the test is skipped. There seems to be a bug in
* java.util.AbstractList.subList(int,int).equals(Object) -- it never
* raises a ConcurrentModificationException.
*
* @param list the sublist to test
* @param m the method to invoke
*/
protected void failFastMethod(List list, Method m) {
if (m.getName().equals("equals")) return;
Object element = getOtherElements()[0];
Collection c = Collections.singleton(element);
Class[] types = m.getParameterTypes();
Object[] params = new Object[types.length];
for (int i = 0; i < params.length; i++) {
if (types[i] == Integer.TYPE) params[i] = new Integer(0);
else if (types[i] == Collection.class) params[i] = c;
else if (types[i] == Object.class) params[i] = element;
else if (types[i] == Object[].class) params[i] = new Object[0];
}
try {
m.invoke(list, params);
fail(m.getName() + " should raise ConcurrentModification");
} catch (IllegalAccessException e) {
// impossible
} catch (InvocationTargetException e) {
Throwable t = e.getTargetException();
if (t instanceof ConcurrentModificationException) {
// expected
return;
} else {
fail(m.getName() + " raised unexpected " + e);
}
}
}
//-----------------------------------------------------------------------
public BulkTest bulkTestListIterator() {
return new TestListIterator();
}
public class TestListIterator extends AbstractTestListIterator {
public TestListIterator() {
super("TestListIterator");
}
public Object addSetValue() {
return AbstractTestList.this.getOtherElements()[0];
}
public boolean supportsRemove() {
return AbstractTestList.this.isRemoveSupported();
}
public boolean supportsAdd() {
return AbstractTestList.this.isAddSupported();
}
public boolean supportsSet() {
return AbstractTestList.this.isSetSupported();
}
public ListIterator makeEmptyListIterator() {
resetEmpty();
return ((List) AbstractTestList.this.collection).listIterator();
}
public ListIterator makeFullListIterator() {
resetFull();
return ((List) AbstractTestList.this.collection).listIterator();
}
}
}
Other Commons Collections examples (source code examples)
Here is a short list of links related to this Commons Collections AbstractTestList.java source code file: