Implemented LinkedList, with test code. Patch by: jat (+me) Review by: me git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@2333 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/super/com/google/gwt/emul/java/util/AbstractList.java b/user/super/com/google/gwt/emul/java/util/AbstractList.java index 78e13a8..4290f58 100644 --- a/user/super/com/google/gwt/emul/java/util/AbstractList.java +++ b/user/super/com/google/gwt/emul/java/util/AbstractList.java
@@ -73,7 +73,7 @@ private ListIteratorImpl(int start) { int size = AbstractList.this.size(); if (start < 0 || start > size) { - AbstractList.this.indexOutOfBounds(start); + indexOutOfBounds(start, size); } i = start; } @@ -110,6 +110,19 @@ } } + protected static void checkIndex(int index, int size) { + if (index < 0 || index >= size) { + indexOutOfBounds(index, size); + } + } + + /** + * Throws an <code>indexOutOfBoundsException</code>. + */ + protected static void indexOutOfBounds(int index, int size) { + throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size); + } + protected AbstractList() { } @@ -225,14 +238,6 @@ throw new UnsupportedOperationException("subList"); } - /** - * Throws an <code>indexOutOfBoundsException</code>. - */ - protected void indexOutOfBounds(int i) { - throw new IndexOutOfBoundsException("Index: " + i + ", Size: " - + this.size()); - } - protected void removeRange(int fromIndex, int endIndex) { ListIterator<E> iter = listIterator(fromIndex); for (int i = fromIndex; i < endIndex; ++i) {
diff --git a/user/super/com/google/gwt/emul/java/util/ArrayList.java b/user/super/com/google/gwt/emul/java/util/ArrayList.java index aaac930..10c2ad8 100644 --- a/user/super/com/google/gwt/emul/java/util/ArrayList.java +++ b/user/super/com/google/gwt/emul/java/util/ArrayList.java
@@ -45,10 +45,6 @@ array.splice(index, 0, o); }-*/; - private static boolean equals(Object a, Object b) { - return a == b || (a != null && a.equals(b)); - } - private static native <E> E getImpl(JavaScriptObject array, int index) /*-{ return array[index]; }-*/; @@ -91,25 +87,26 @@ * There is no speed advantage to pre-allocating array sizes in JavaScript. * This constructor is only present for compatibility with the JRE. */ + @SuppressWarnings("unused") public ArrayList(int ignoredInitialCapacity) { } @Override - public void add(int index, E o) { - if (index < 0 || index > size) { - indexOutOfBounds(index); - } - addImpl(array, index, o); - ++size; - } - - @Override public boolean add(E o) { setImpl(array, size++, o); return true; } @Override + public void add(int index, E o) { + if (index < 0 || index > size) { + indexOutOfBounds(index, size); + } + addImpl(array, index, o); + ++size; + } + + @Override public boolean addAll(Collection<? extends E> c) { Iterator<? extends E> iter = c.iterator(); boolean changed = iter.hasNext(); @@ -135,11 +132,9 @@ @Override public E get(int index) { - if (index < 0 || index >= size) { - indexOutOfBounds(index); - } + checkIndex(index, size); // implicit type arg not inferred (as of JDK 1.5.0_07) - return ArrayList.<E>getImpl(array, index); + return ArrayList.<E> getImpl(array, index); } @Override @@ -187,12 +182,6 @@ return size; } - @Override - public List<E> subList(int fromIndex, int toIndex) { - // TODO(jat): implement - throw new UnsupportedOperationException("subList not implemented"); - } - /* * Faster than the iterator-based implementation in AbstractCollection. */ @@ -203,7 +192,7 @@ } for (int i = 0; i < size; ++i) { // implicit type arg not inferred (as of JDK 1.5.0_07) - a[i] = ArrayList.<T>getImpl(array, i); + a[i] = ArrayList.<T> getImpl(array, i); } if (a.length > size) { a[size] = null; @@ -212,18 +201,17 @@ } /** - * Currently ignored. + * Does nothing. */ public void trimToSize() { - // TODO(jat): implement } protected int indexOf(Object o, int index) { if (index < 0) { - indexOutOfBounds(index); + indexOutOfBounds(index, size); } for (; index < size; ++index) { - if (equals(o, getImpl(array, index))) { + if (Utility.equalsWithNullCheck(o, getImpl(array, index))) { return index; } } @@ -232,10 +220,10 @@ protected int lastIndexOf(Object o, int index) { if (index >= size) { - indexOutOfBounds(index); + indexOutOfBounds(index, size); } for (; index >= 0; --index) { - if (equals(o, getImpl(array, index))) { + if (Utility.equalsWithNullCheck(o, getImpl(array, index))) { return index; } } @@ -244,11 +232,9 @@ @Override protected void removeRange(int fromIndex, int endIndex) { - if (fromIndex < 0 || fromIndex >= size) { - indexOutOfBounds(fromIndex); - } + checkIndex(fromIndex, size); if (endIndex < fromIndex || endIndex > size) { - indexOutOfBounds(endIndex); + indexOutOfBounds(endIndex, size); } int count = endIndex - fromIndex; removeRangeImpl(array, fromIndex, count); @@ -260,7 +246,7 @@ */ protected void setSize(int newSize) { if (newSize < 0) { - indexOutOfBounds(newSize); + indexOutOfBounds(newSize, size); } setSizeImpl(array, newSize); // null fill any new slots if size < newSize @@ -271,6 +257,12 @@ size = newSize; } + @SuppressWarnings("unused") + List<E> subListUnimplemented(int fromIndex, int toIndex) { + // TODO(jat): implement + throw new UnsupportedOperationException("subList not implemented"); + } + private void clearImpl() { array = JavaScriptObject.createArray(); size = 0;
diff --git a/user/super/com/google/gwt/emul/java/util/LinkedList.java b/user/super/com/google/gwt/emul/java/util/LinkedList.java index e0ea1c8..b4d36f3 100644 --- a/user/super/com/google/gwt/emul/java/util/LinkedList.java +++ b/user/super/com/google/gwt/emul/java/util/LinkedList.java
@@ -1,5 +1,5 @@ /* - * Copyright 2007 Google Inc. + * Copyright 2008 Google Inc. * * 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 @@ -25,11 +25,165 @@ * @param <E> element type. */ public class LinkedList<E> extends AbstractSequentialList<E> implements - List<E>, Queue<E>, Cloneable, Serializable { + List<E>, Queue<E>, Serializable { + /* + * This implementation uses a doubly-linked circular list with a header node. + */ + + /** + * Implementation of ListIterator for linked lists. + */ + private final class ListIteratorImpl implements ListIterator<E> { + + /** + * The index to the current position. + */ + protected int currentIndex; + + /** + * Current node, to be returned from next. + */ + protected Node<E> currentNode; + + /** + * The last node returned from next/previous, or null if deleted or never + * called. + */ + protected Node<E> lastNode = null; + + /** + * @param index from the beginning of the list (0 = first node) + * @param startNode the initial current node + */ + public ListIteratorImpl(int index, Node<E> startNode) { + currentNode = startNode; + currentIndex = index; + } + + public void add(E o) { + addBefore(o, currentNode); + ++currentIndex; + lastNode = null; + } + + public boolean hasNext() { + return currentNode != header; + } + + public boolean hasPrevious() { + return currentNode.prev != header; + } + + public E next() { + if (!hasNext()) { + throw new NoSuchElementException(); + } + lastNode = currentNode; + currentNode = currentNode.next; + ++currentIndex; + return lastNode.value; + } + + public int nextIndex() { + return currentIndex; + } + + public E previous() { + if (!hasPrevious()) { + throw new NoSuchElementException(); + } + lastNode = currentNode = currentNode.prev; + --currentIndex; + return lastNode.value; + } + + public int previousIndex() { + return currentIndex - 1; + } + + public void remove() { + verifyCurrentElement(); + if (currentNode == lastNode) { + // We just did a previous(). + currentNode = lastNode.next; + } else { + // We just did a next(). + --currentIndex; + } + lastNode.remove(); + lastNode = null; + --size; + } + + public void set(E o) { + verifyCurrentElement(); + lastNode.value = o; + } + + protected void verifyCurrentElement() { + if (lastNode == null) { + throw new IllegalStateException(); + } + } + } + + /** + * Internal class representing a doubly-linked list node. + * + * @param <E> element type + */ + private static class Node<E> { + public Node<E> next; + public Node<E> prev; + public E value; + + public Node() { + next = prev = this; + } + + public Node(E value) { + this.value = value; + } + + /** + * Construct a node containing a value and add it before the specified node. + * + * @param value + * @param nextNode + */ + public Node(E value, Node<E> nextNode) { + this(value); + this.next = nextNode; + this.prev = nextNode.prev; + nextNode.prev.next = this; + nextNode.prev = this; + } + + /** + * Remove this node from any list it is in, leaving it with circular + * references to itself. + */ + public void remove() { + this.next.prev = this.prev; + this.prev.next = this.next; + this.next = this.prev = this; + } + } + + /** + * Header node - header.next is the first element of the list, and header.prev + * is the last element of the list. If the list is empty, the header node will + * point to itself. + */ + private Node<E> header; + + /** + * Number of nodes currently present in the list. + */ + private int size; public LinkedList() { - // TODO(jat): implement - throw new UnsupportedOperationException("LinkedList unsupported"); + clear(); } public LinkedList(Collection<? extends E> c) { @@ -39,38 +193,24 @@ @Override public boolean add(E o) { - // TODO(jat): implement - return false; - } - - @Override - public boolean addAll(Collection<? extends E> c) { - // TODO(jat): implement - return false; + addLast(o); + return true; } public void addFirst(E o) { - // TODO(jat): implement + new Node<E>(o, header.next); + ++size; } public void addLast(E o) { - // TODO(jat): implement + new Node<E>(o, header); + ++size; } @Override public void clear() { - // TODO(jat): implement - } - - public Object clone() { - // TODO(jat): implement - return null; - } - - @Override - public boolean contains(Object o) { - // TODO(jat): implement - return false; + header = new Node<E>(); + size = 0; } public E element() { @@ -78,31 +218,36 @@ } public E getFirst() { - // TODO(jat): implement - return null; + throwEmptyException(); + return header.next.value; } public E getLast() { - // TODO(jat): implement - return null; + throwEmptyException(); + return header.prev.value; } @Override - public int indexOf(Object o) { - // TODO(jat): implement - return 0; - } + public ListIterator<E> listIterator(final int index) { + if (index < 0 || index > size) { + indexOutOfBounds(index, size); + } - @Override - public int lastIndexOf(Object o) { - // TODO(jat): implement - return 0; - } + Node<E> node; + // start from the nearest end of the list + if (index >= size >> 1) { + node = header; + for (int i = size; i > index; --i) { + node = node.prev; + } + } else { + node = header.next; + for (int i = 0; i < index; ++i) { + node = node.next; + } + } - @Override - public ListIterator<E> listIterator(int index) { - // TODO(jat): implement - return null; + return new ListIteratorImpl(index, node); } public boolean offer(E o) { @@ -110,7 +255,7 @@ } public E peek() { - if (size() == 0) { + if (size == 0) { return null; } else { return getFirst(); @@ -118,7 +263,7 @@ } public E poll() { - if (size() == 0) { + if (size == 0) { return null; } else { return removeFirst(); @@ -130,37 +275,43 @@ } public E removeFirst() { - // TODO(jat): implement - return null; + throwEmptyException(); + --size; + Node<E> node = header.next; + node.remove(); + return node.value; } public E removeLast() { - // TODO(jat): implement - return null; + throwEmptyException(); + --size; + Node<E> node = header.prev; + node.remove(); + return node.value; } @Override public int size() { + return size; + } + + @SuppressWarnings("unused") + List<E> subListUnimplemented(final int fromIndex, final int toIndex) { // TODO(jat): implement - return 0; + throw new UnsupportedOperationException("subList not implemented"); } - @Override - public List<E> subList(int fromIndex, int toIndex) { - // TODO Auto-generated method stub - return null; + private void addBefore(E o, Node<E> target) { + new Node<E>(o, target); + ++size; } - @Override - public Object[] toArray() { - // TODO(jat): implement - return null; + /** + * Throw an exception if the list is empty. + */ + private void throwEmptyException() { + if (size == 0) { + throw new NoSuchElementException(); + } } - - @Override - public <T> T[] toArray(T[] a) { - // TODO(jat): implement - return null; - } - }
diff --git a/user/test/com/google/gwt/emultest/EmulSuite.java b/user/test/com/google/gwt/emultest/EmulSuite.java index 462edbb..1f6ab21 100644 --- a/user/test/com/google/gwt/emultest/EmulSuite.java +++ b/user/test/com/google/gwt/emultest/EmulSuite.java
@@ -39,6 +39,7 @@ import com.google.gwt.emultest.java.util.HashMapTest; import com.google.gwt.emultest.java.util.HashSetTest; import com.google.gwt.emultest.java.util.IdentityHashMapTest; +import com.google.gwt.emultest.java.util.LinkedListTest; import com.google.gwt.emultest.java.util.StackTest; import com.google.gwt.junit.tools.GWTTestSuite; @@ -79,6 +80,7 @@ suite.addTestSuite(HashMapTest.class); suite.addTestSuite(HashSetTest.class); suite.addTestSuite(IdentityHashMapTest.class); + suite.addTestSuite(LinkedListTest.class); suite.addTestSuite(StackTest.class); suite.addTest(TreeMapSuite.suite()); // $JUnit-END$
diff --git a/user/test/com/google/gwt/emultest/java/util/ArrayListTest.java b/user/test/com/google/gwt/emultest/java/util/ArrayListTest.java index 7ab0b19..65fb249 100644 --- a/user/test/com/google/gwt/emultest/java/util/ArrayListTest.java +++ b/user/test/com/google/gwt/emultest/java/util/ArrayListTest.java
@@ -1,221 +1,73 @@ -/* - * Copyright 2006 Google Inc. - * - * 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 com.google.gwt.emultest.java.util; - -import org.apache.commons.collections.TestArrayList; - -import java.util.ArrayList; -import java.util.List; -import java.util.ListIterator; - -/** - * Tests ArrayList, and, by extension AbstractList. Uses inheritance to inherit - * all of Apache's TestList and TestCollection. - */ -public class ArrayListTest extends TestArrayList { - - private static final class ArrayListWithRemoveRange extends ArrayList { - public void removeRange(int fromIndex, int toIndex) { - super.removeRange(fromIndex, toIndex); - } - } - - public ArrayListTest() { - } - - public void testAddWatch() { - ArrayList s = new ArrayList(); - s.add("watch"); - assertEquals(s.get(0), "watch"); - } - - public void testListIteratorAddInSeveralPositions() { - ArrayList l = new ArrayList(); - ListIterator i = l.listIterator(); - l.add(new Integer(0)); - for (int n = 2; n < 5; n += 2) { - l.add(new Integer(n)); - } - i = l.listIterator(); - i.next(); - i.add(new Integer(1)); - i.next(); - i.next(); - i.previous(); - i.add(new Integer(3)); - i.next(); - i.add(new Integer(5)); - i.add(new Integer(6)); - for (int n = 0; n < 6; n++) { - assertEquals(new Integer(n), l.get(n)); - } - } - - public void testListIteratorCreateInvalid() { - ArrayList l = new ArrayList(); - l.add(new Integer(1)); - l.listIterator(0); - try { - l.listIterator(1); - } catch (IndexOutOfBoundsException e) { - // expected - } - try { - l.listIterator(-1); - } catch (IndexOutOfBoundsException e) { - // expected - } - } - - public void testListIteratorHasNextHasPreviousAndIndexes() { - List l = new ArrayList(); - ListIterator i = l.listIterator(); - assertFalse(i.hasNext()); - assertFalse(i.hasPrevious()); - i.add(new Integer(1)); - assertEquals(1, i.nextIndex()); - assertEquals(0, i.previousIndex()); - i = l.listIterator(); - assertEquals(0, i.nextIndex()); - assertEquals(-1, i.previousIndex()); - assertTrue(i.hasNext()); - assertFalse(i.hasPrevious()); - i.next(); - assertEquals(1, i.nextIndex()); - assertEquals(0, i.previousIndex()); - assertFalse(i.hasNext()); - assertTrue(i.hasPrevious()); - } - - public void testListIteratorSetInSeveralPositions() { - ArrayList l = new ArrayList(); - for (int n = 0; n < 5; n += 2) { - l.add(new Integer(n)); - } - l.listIterator(); - for (int n = 0; n < 3; n++) { - l.set(n, new Integer(n)); - } - for (int n = 0; n < 3; n++) { - assertEquals(new Integer(n), l.get(n)); - } - } - - public void testRemoveRange() { - ArrayListWithRemoveRange l = new ArrayListWithRemoveRange(); - for (int i = 0; i < 10; i++) { - l.add(new Integer(i)); - } - try { - l.removeRange(-1, 1); - fail(); - } catch (IndexOutOfBoundsException expected) { - } - - try { - l.removeRange(2, 1); - fail(); - } catch (IndexOutOfBoundsException expected) { - } - - try { - l.removeRange(2, 11); - fail(); - } catch (IndexOutOfBoundsException expected) { - } - - l.removeRange(3, 5); - assertEquals(8, l.size()); - for (int i = 0; i < 3; i++) { - Integer elem = (Integer) l.get(i); - assertEquals(i, elem.intValue()); - } - for (int i = 3; i < 8; i++) { - Integer elem = (Integer) l.get(i); - assertEquals(i + 2, elem.intValue()); - } - } - - public void testToArray() { - ArrayList l = new ArrayList(); - for (int i = 0; i < 10; i++) { - l.add(new Integer(i)); - } - - { - Object[] objArray = l.toArray(); - assertEquals(10, objArray.length); - for (int i = 0; i < 10; i++) { - Integer elem = (Integer) objArray[i]; - assertEquals(i, elem.intValue()); - } - // should not cause ArrayStore - objArray[0] = new Object(); - } - - { - Integer[] firstArray = new Integer[13]; - firstArray[10] = new Integer(10); - firstArray[11] = new Integer(11); - firstArray[12] = new Integer(12); - Integer[] intArray = (Integer[]) l.toArray(firstArray); - assertTrue(firstArray == intArray); - assertEquals(13, intArray.length); - for (int i = 0; i < 13; i++) { - if (i == 10) { - assertNull(intArray[i]); - } else { - Integer elem = intArray[i]; - assertEquals(i, elem.intValue()); - } - } - try { - Object[] objArray = noOptimizeFalse() ? new Object[1] : intArray; - assertTrue(objArray instanceof Integer[]); - objArray[0] = new Object(); - fail("expected ArrayStoreException"); - } catch (ArrayStoreException e) { - } - } - - { - Integer[] firstArray = new Integer[0]; - Integer[] intArray = (Integer[]) l.toArray(firstArray); - assertFalse(firstArray == intArray); - assertEquals(10, intArray.length); - for (int i = 0; i < 10; i++) { - Integer elem = intArray[i]; - assertEquals(i, elem.intValue()); - } - try { - Object[] objArray = noOptimizeFalse() ? new Object[1] : intArray; - assertTrue(objArray instanceof Integer[]); - objArray[0] = new Object(); - fail("expected ArrayStoreException"); - } catch (ArrayStoreException e) { - } - } - } - - protected List makeEmptyList() { - return new ArrayList(); - } - - private static native boolean noOptimizeFalse() /*-{ - return false; - }-*/; -} +/* + * Copyright 2008 Google Inc. + * + * 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 com.google.gwt.emultest.java.util; + +import java.util.ArrayList; +import java.util.List; + +/** + * Tests ArrayList class (and by extension, AbstractList). + */ +@SuppressWarnings("unchecked") +public class ArrayListTest extends ListTestBase { + + private static final class ArrayListWithRemoveRange extends ArrayList { + @Override + public void removeRange(int fromIndex, int toIndex) { + super.removeRange(fromIndex, toIndex); + } + } + + public void testRemoveRange() { + ArrayListWithRemoveRange l = new ArrayListWithRemoveRange(); + for (int i = 0; i < 10; i++) { + l.add(new Integer(i)); + } + try { + l.removeRange(-1, 1); + fail(); + } catch (IndexOutOfBoundsException expected) { + } + + try { + l.removeRange(2, 1); + fail(); + } catch (IndexOutOfBoundsException expected) { + } + + try { + l.removeRange(2, 11); + fail(); + } catch (IndexOutOfBoundsException expected) { + } + + l.removeRange(3, 5); + assertEquals(8, l.size()); + for (int i = 0; i < 3; i++) { + Integer elem = (Integer) l.get(i); + assertEquals(i, elem.intValue()); + } + for (int i = 3; i < 8; i++) { + Integer elem = (Integer) l.get(i); + assertEquals(i + 2, elem.intValue()); + } + } + + @Override + protected List makeEmptyList() { + return new ArrayList(); + } +}
diff --git a/user/test/com/google/gwt/emultest/java/util/LinkedListTest.java b/user/test/com/google/gwt/emultest/java/util/LinkedListTest.java new file mode 100644 index 0000000..8662f09 --- /dev/null +++ b/user/test/com/google/gwt/emultest/java/util/LinkedListTest.java
@@ -0,0 +1,122 @@ +/* + * Copyright 2008 Google Inc. + * + * 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 com.google.gwt.emultest.java.util; + +import java.util.LinkedList; +import java.util.List; +import java.util.NoSuchElementException; + +/** + * Test LinkedList class. + */ +@SuppressWarnings("unchecked") +public class LinkedListTest extends ListTestBase { + + private static final class LinkedListWithRemoveRange extends LinkedList { + @Override + public void removeRange(int fromIndex, int toIndex) { + super.removeRange(fromIndex, toIndex); + } + } + + public void testAddFirst() { + // TODO(jat): implement + } + + public void testAddLast() { + // TODO(jat): implement + } + + public void testElement() { + // TODO(jat): implement + } + + public void testGetFirst() { + // TODO(jat): implement + } + + public void testGetLast() { + // TODO(jat): implement + } + + public void testOffer() { + // TODO(jat): implement + } + + public void testPeek() { + // TODO(jat): implement + } + + public void testPoll() { + // TODO(jat): implement + } + + public void testRemove() { + // TODO(jat): implement + } + + public void testRemoveFirst() { + // TODO(jat): implement + } + + public void testRemoveLast() { + // TODO(jat): implement + } + + public void testRemoveRange() { + LinkedListWithRemoveRange l = new LinkedListWithRemoveRange(); + for (int i = 0; i < 10; i++) { + l.add(new Integer(i)); + } + try { + l.removeRange(-1, 1); + fail(); + } catch (IndexOutOfBoundsException expected) { + } + + try { + l.removeRange(2, 11); + fail(); + } catch (NoSuchElementException expected) { + } + + assertEquals(2, l.size()); + for (int i = 0; i < 2; i++) { + Integer elem = (Integer) l.get(i); + assertEquals(i, elem.intValue()); + } + + for (int i = 2; i < 10; i++) { + l.add(new Integer(i)); + } + + l.removeRange(3, 5); + assertEquals(8, l.size()); + for (int i = 0; i < 3; i++) { + Integer elem = (Integer) l.get(i); + assertEquals(i, elem.intValue()); + } + for (int i = 3; i < 8; i++) { + Integer elem = (Integer) l.get(i); + assertEquals(i + 2, elem.intValue()); + } + } + + @Override + protected List makeEmptyList() { + return new LinkedList(); + } +}
diff --git a/user/test/com/google/gwt/emultest/java/util/ListTestBase.java b/user/test/com/google/gwt/emultest/java/util/ListTestBase.java new file mode 100644 index 0000000..756ca47 --- /dev/null +++ b/user/test/com/google/gwt/emultest/java/util/ListTestBase.java
@@ -0,0 +1,174 @@ +/* + * Copyright 2008 Google Inc. + * + * 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 com.google.gwt.emultest.java.util; + +import org.apache.commons.collections.TestArrayList; + +import java.util.List; +import java.util.ListIterator; + +/** + * Tests List, and, by extension AbstractList. Uses inheritance to inherit all + * of Apache's TestList and TestCollection. + */ +@SuppressWarnings("unchecked") +public abstract class ListTestBase extends TestArrayList { + + private static volatile boolean NO_OPTIMIZE_FALSE = false; + + public void testAddWatch() { + List s = makeEmptyList(); + s.add("watch"); + assertEquals(s.get(0), "watch"); + } + + public void testListIteratorAddInSeveralPositions() { + List l = makeEmptyList(); + ListIterator i = l.listIterator(); + l.add(new Integer(0)); + for (int n = 2; n < 5; n += 2) { + l.add(new Integer(n)); + } + i = l.listIterator(); + i.next(); + i.add(new Integer(1)); + i.next(); + i.next(); + i.previous(); + i.add(new Integer(3)); + i.next(); + i.add(new Integer(5)); + i.add(new Integer(6)); + for (int n = 0; n < 6; n++) { + assertEquals(new Integer(n), l.get(n)); + } + } + + public void testListIteratorCreateInvalid() { + List l = makeEmptyList(); + l.add(new Integer(1)); + l.listIterator(0); + try { + l.listIterator(1); + } catch (IndexOutOfBoundsException e) { + // expected + } + try { + l.listIterator(-1); + } catch (IndexOutOfBoundsException e) { + // expected + } + } + + public void testListIteratorHasNextHasPreviousAndIndexes() { + List l = makeEmptyList(); + ListIterator i = l.listIterator(); + assertFalse(i.hasNext()); + assertFalse(i.hasPrevious()); + i.add(new Integer(1)); + assertEquals(1, i.nextIndex()); + assertEquals(0, i.previousIndex()); + i = l.listIterator(); + assertEquals(0, i.nextIndex()); + assertEquals(-1, i.previousIndex()); + assertTrue(i.hasNext()); + assertFalse(i.hasPrevious()); + i.next(); + assertEquals(1, i.nextIndex()); + assertEquals(0, i.previousIndex()); + assertFalse(i.hasNext()); + assertTrue(i.hasPrevious()); + } + + public void testListIteratorSetInSeveralPositions() { + List l = makeEmptyList(); + for (int n = 0; n < 5; n += 2) { + l.add(new Integer(n)); + } + l.listIterator(); + for (int n = 0; n < 3; n++) { + l.set(n, new Integer(n)); + } + for (int n = 0; n < 3; n++) { + assertEquals(new Integer(n), l.get(n)); + } + } + + public void testListIteratorRemove() { + // TODO(jat): implement + } + + public void testToArray() { + List l = makeEmptyList(); + for (int i = 0; i < 10; i++) { + l.add(new Integer(i)); + } + + { + Object[] objArray = l.toArray(); + assertEquals(10, objArray.length); + for (int i = 0; i < 10; i++) { + Integer elem = (Integer) objArray[i]; + assertEquals(i, elem.intValue()); + } + // should not cause ArrayStore + objArray[0] = new Object(); + } + + { + Integer[] firstArray = new Integer[13]; + firstArray[10] = new Integer(10); + firstArray[11] = new Integer(11); + firstArray[12] = new Integer(12); + Integer[] intArray = (Integer[]) l.toArray(firstArray); + assertTrue(firstArray == intArray); + assertEquals(13, intArray.length); + for (int i = 0; i < 13; i++) { + if (i == 10) { + assertNull(intArray[i]); + } else { + Integer elem = intArray[i]; + assertEquals(i, elem.intValue()); + } + } + try { + Object[] objArray = NO_OPTIMIZE_FALSE ? new Object[1] : intArray; + assertTrue(objArray instanceof Integer[]); + objArray[0] = new Object(); + fail("expected ArrayStoreException"); + } catch (ArrayStoreException e) { + } + } + + { + Integer[] firstArray = new Integer[0]; + Integer[] intArray = (Integer[]) l.toArray(firstArray); + assertFalse(firstArray == intArray); + assertEquals(10, intArray.length); + for (int i = 0; i < 10; i++) { + Integer elem = intArray[i]; + assertEquals(i, elem.intValue()); + } + try { + Object[] objArray = NO_OPTIMIZE_FALSE ? new Object[1] : intArray; + assertTrue(objArray instanceof Integer[]); + objArray[0] = new Object(); + fail("expected ArrayStoreException"); + } catch (ArrayStoreException e) { + } + } + } +}
diff --git a/user/test/org/apache/commons/collections/TestArrayList.java b/user/test/org/apache/commons/collections/TestArrayList.java index 2e3ddb1..07ff0ab 100644 --- a/user/test/org/apache/commons/collections/TestArrayList.java +++ b/user/test/org/apache/commons/collections/TestArrayList.java
@@ -13,8 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +// MODIFIED BY GOOGLE package org.apache.commons.collections; - import java.util.ArrayList; + import java.util.List; /** * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> @@ -24,8 +25,8 @@ { - - protected ArrayList list = (ArrayList)makeEmptyList(); + // GOOGLE + protected List list = makeEmptyList(); public void testNewArrayList()