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()