| /* |
| * Copyright 1999-2004 The Apache Software Foundation |
| * |
| * Licensed 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; |
| |
| import java.util.AbstractCollection; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.ListIterator; |
| import java.util.NoSuchElementException; |
| |
| /** |
| * Tests base {@link java.util.List} methods and contracts. |
| * <p> |
| * To use, simply extend this class, and implement |
| * the {@link #makeList} 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. |
| * |
| * @author Rodney Waldhoff |
| * @author Paul Jack |
| * @version $Id: TestList.java,v 1.13.2.1 2004/05/22 12:14:05 scolebourne Exp $ |
| */ |
| @SuppressWarnings({"unchecked", "rawtypes"}) |
| public abstract class TestList extends TestCollection { |
| |
| |
| |
| |
| /** |
| * Return a new, empty {@link List} to be used for testing. |
| * |
| * @return an empty list for testing. |
| */ |
| protected abstract List makeEmptyList(); |
| |
| |
| /** |
| * Return a new, full {@link List} to be used for testing. |
| * |
| * @return a full list for testing |
| */ |
| protected 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 |
| */ |
| @Override |
| final protected Collection makeCollection() { |
| return makeEmptyList(); |
| } |
| |
| |
| /** |
| * Returns {@link makeFullList()}. |
| * |
| * @return a full list to be used for testing |
| */ |
| @Override |
| final protected Collection makeFullCollection() { |
| return makeFullList(); |
| } |
| |
| |
| |
| /** |
| * Whether or not we are testing an iterator that can be |
| * empty. Default is true. |
| * |
| * @return true if Iterators can be empty |
| */ |
| public boolean supportsEmptyIterator() { |
| return true; |
| } |
| |
| /** |
| * Whether or not we are testing an list that allows |
| * element set. Default is true. |
| * |
| * @return true if Lists support element set |
| */ |
| public boolean isSetSupported() { |
| return true; |
| } |
| |
| |
| /** |
| * Returns the {@link collection} field cast to a {@link List}. |
| * |
| * @return the collection field as a List |
| */ |
| protected List getList() { |
| return (List)collection; |
| } |
| |
| |
| /** |
| * Returns the {@link confirmed} field cast to a {@link List}. |
| * |
| * @return the confirmed field as a List |
| */ |
| protected List getConfirmedList() { |
| return (List)confirmed; |
| } |
| |
| |
| |
| |
| public class TestListIterator extends AbstractTestListIterator { |
| |
| @Override |
| public Object addSetValue() { |
| return TestList.this.getOtherElements()[0]; |
| } |
| |
| @Override |
| public boolean supportsRemove() { |
| return TestList.this.isRemoveSupported(); |
| } |
| |
| @Override |
| public boolean supportsAdd() { |
| return TestList.this.isAddSupported(); |
| } |
| |
| @Override |
| public boolean supportsSet() { |
| return TestList.this.isSetSupported(); |
| } |
| |
| @Override |
| public ListIterator makeEmptyListIterator() { |
| resetEmpty(); |
| return ((List) TestList.this.collection).listIterator(); |
| } |
| |
| @Override |
| public ListIterator makeFullListIterator() { |
| resetFull(); |
| return ((List) TestList.this.collection).listIterator(); |
| } |
| |
| @Override |
| public Object makeObject() { |
| return ((List) TestList.this.collection).listIterator(); |
| } |
| } |
| |
| /** |
| * 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 f", 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 b", 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, 0, nextIndex); |
| int prevIndex = iter.previousIndex(); |
| assertEquals("previousIndex should be -1, actual value: " + prevIndex, -1, prevIndex); |
| |
| 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(); |
| } |
| } |
| |
| |
| |
| |
| /** |
| * 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(); |
| assertTrue("Empty lists should be equal", list.equals(confirmed)); |
| verify(); |
| assertTrue("Empty list should equal self", list.equals(list)); |
| verify(); |
| |
| List list2 = Arrays.asList(getFullElements()); |
| assertTrue("Empty list shouldn't equal full", !list.equals(list2)); |
| verify(); |
| |
| list2 = Arrays.asList(getOtherElements()); |
| assertTrue("Empty list shouldn't equal other", !list.equals(list2)); |
| verify(); |
| |
| resetFull(); |
| list = getList(); |
| assertTrue("Full lists should be equal", list.equals(confirmed)); |
| verify(); |
| assertTrue("Full list should equal self", list.equals(list)); |
| verify(); |
| |
| list2 = makeEmptyList(); |
| assertTrue("Full list shouldn't equal empty", !list.equals(list2)); |
| verify(); |
| |
| list2 = Arrays.asList(getOtherElements()); |
| assertTrue("Full list shouldn't equal other", !list.equals(list2)); |
| verify(); |
| |
| list2 = Arrays.asList(getFullElements()); |
| Collections.reverse(list2); |
| assertTrue("Full list shouldn't equal full list with same elements" + |
| " but different order", !list.equals(list2)); |
| verify(); |
| |
| assertTrue("List shouldn't equal String", !list.equals("")); |
| verify(); |
| |
| final List listForC = Arrays.asList(getFullElements()); |
| Collection c = new AbstractCollection() { |
| @Override |
| public int size() { |
| return listForC.size(); |
| } |
| |
| @Override |
| public Iterator iterator() { |
| return listForC.iterator(); |
| } |
| }; |
| |
| assertTrue("List shouldn't equal nonlist with same elements " + |
| " in same order", !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 {@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", -1, list1.indexOf(other[i])); |
| 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", |
| -1, |
| list1.lastIndexOf(other[i])); |
| verify(); |
| } |
| } |
| |
| |
| |
| |
| /** |
| * 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(); |
| } |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| /** |
| * Returns an empty {@link ArrayList}. |
| */ |
| @Override |
| protected Collection makeConfirmedCollection() { |
| ArrayList list = new ArrayList(); |
| return list; |
| } |
| |
| |
| /** |
| * Returns a full {@link ArrayList}. |
| */ |
| @Override |
| protected Collection makeConfirmedFullCollection() { |
| ArrayList list = new ArrayList(); |
| list.addAll(Arrays.asList(getFullElements())); |
| return list; |
| } |
| |
| |
| /** |
| * Verifies that the test list implementation matches the confirmed list |
| * implementation. |
| */ |
| @Override |
| protected 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++; |
| } |
| } |
| |
| |
| |
| |
| } |