--- jsr166/src/test/tck/CopyOnWriteArrayListTest.java 2015/01/17 22:55:06 1.32 +++ jsr166/src/test/tck/CopyOnWriteArrayListTest.java 2018/03/26 21:28:22 1.47 @@ -9,30 +9,42 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; -import java.util.Collections; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.ListIterator; import java.util.NoSuchElementException; -import java.util.Vector; import java.util.concurrent.CopyOnWriteArrayList; import junit.framework.Test; -import junit.framework.TestSuite; public class CopyOnWriteArrayListTest extends JSR166TestCase { public static void main(String[] args) { - junit.textui.TestRunner.run(suite()); + main(suite(), args); } public static Test suite() { - return new TestSuite(CopyOnWriteArrayListTest.class); + class Implementation implements CollectionImplementation { + public Class klazz() { return CopyOnWriteArrayList.class; } + public List emptyCollection() { return new CopyOnWriteArrayList(); } + public Object makeElement(int i) { return i; } + public boolean isConcurrent() { return true; } + public boolean permitsNulls() { return true; } + } + class SubListImplementation extends Implementation { + public List emptyCollection() { + return super.emptyCollection().subList(0, 0); + } + } + return newTestSuite( + CopyOnWriteArrayListTest.class, + CollectionTest.testSuite(new Implementation()), + CollectionTest.testSuite(new SubListImplementation())); } static CopyOnWriteArrayList populatedArray(int n) { - CopyOnWriteArrayList a = new CopyOnWriteArrayList(); + CopyOnWriteArrayList a = new CopyOnWriteArrayList<>(); assertTrue(a.isEmpty()); for (int i = 0; i < n; i++) a.add(i); @@ -42,10 +54,10 @@ public class CopyOnWriteArrayListTest ex } static CopyOnWriteArrayList populatedArray(Integer[] elements) { - CopyOnWriteArrayList a = new CopyOnWriteArrayList(); + CopyOnWriteArrayList a = new CopyOnWriteArrayList<>(); assertTrue(a.isEmpty()); - for (int i = 0; i < elements.length; i++) - a.add(elements[i]); + for (Integer element : elements) + a.add(element); assertFalse(a.isEmpty()); assertEquals(elements.length, a.size()); return a; @@ -64,7 +76,7 @@ public class CopyOnWriteArrayListTest ex */ public void testConstructor2() { Integer[] ints = new Integer[SIZE]; - for (int i = 0; i < SIZE-1; ++i) + for (int i = 0; i < SIZE - 1; ++i) ints[i] = new Integer(i); CopyOnWriteArrayList a = new CopyOnWriteArrayList(ints); for (int i = 0; i < SIZE; ++i) @@ -76,7 +88,7 @@ public class CopyOnWriteArrayListTest ex */ public void testConstructor3() { Integer[] ints = new Integer[SIZE]; - for (int i = 0; i < SIZE-1; ++i) + for (int i = 0; i < SIZE - 1; ++i) ints[i] = new Integer(i); CopyOnWriteArrayList a = new CopyOnWriteArrayList(Arrays.asList(ints)); for (int i = 0; i < SIZE; ++i) @@ -84,16 +96,14 @@ public class CopyOnWriteArrayListTest ex } /** - * addAll adds each element from the given collection + * addAll adds each element from the given collection, including duplicates */ public void testAddAll() { CopyOnWriteArrayList full = populatedArray(3); - Vector v = new Vector(); - v.add(three); - v.add(four); - v.add(five); - full.addAll(v); + assertTrue(full.addAll(Arrays.asList(three, four, five))); assertEquals(6, full.size()); + assertTrue(full.addAll(Arrays.asList(three, four, five))); + assertEquals(9, full.size()); } /** @@ -102,11 +112,10 @@ public class CopyOnWriteArrayListTest ex */ public void testAddAllAbsent() { CopyOnWriteArrayList full = populatedArray(3); - Vector v = new Vector(); - v.add(three); - v.add(four); - v.add(one); // will not add this element - full.addAllAbsent(v); + // "one" is duplicate and will not be added + assertEquals(2, full.addAllAbsent(Arrays.asList(three, four, one))); + assertEquals(5, full.size()); + assertEquals(0, full.addAllAbsent(Arrays.asList(three, four, one))); assertEquals(5, full.size()); } @@ -181,27 +190,39 @@ public class CopyOnWriteArrayListTest ex CopyOnWriteArrayList b = populatedArray(3); assertTrue(a.equals(b)); assertTrue(b.equals(a)); + assertTrue(a.containsAll(b)); + assertTrue(b.containsAll(a)); assertEquals(a.hashCode(), b.hashCode()); a.add(m1); assertFalse(a.equals(b)); assertFalse(b.equals(a)); + assertTrue(a.containsAll(b)); + assertFalse(b.containsAll(a)); b.add(m1); assertTrue(a.equals(b)); assertTrue(b.equals(a)); + assertTrue(a.containsAll(b)); + assertTrue(b.containsAll(a)); assertEquals(a.hashCode(), b.hashCode()); + + assertFalse(a.equals(null)); } /** - * containsAll returns true for collection with subset of elements + * containsAll returns true for collections with subset of elements */ public void testContainsAll() { CopyOnWriteArrayList full = populatedArray(3); - Vector v = new Vector(); - v.add(one); - v.add(two); - assertTrue(full.containsAll(v)); - v.add(six); - assertFalse(full.containsAll(v)); + assertTrue(full.containsAll(Arrays.asList())); + assertTrue(full.containsAll(Arrays.asList(one))); + assertTrue(full.containsAll(Arrays.asList(one, two))); + assertFalse(full.containsAll(Arrays.asList(one, two, six))); + assertFalse(full.containsAll(Arrays.asList(six))); + + try { + full.containsAll(null); + shouldThrow(); + } catch (NullPointerException success) {} } /** @@ -213,22 +234,62 @@ public class CopyOnWriteArrayListTest ex } /** - * indexOf gives the index for the given object + * indexOf(Object) returns the index of the first occurrence of the + * specified element in this list, or -1 if this list does not + * contain the element */ public void testIndexOf() { - CopyOnWriteArrayList full = populatedArray(3); - assertEquals(1, full.indexOf(one)); - assertEquals(-1, full.indexOf("puppies")); + CopyOnWriteArrayList list = populatedArray(3); + assertEquals(-1, list.indexOf(-42)); + int size = list.size(); + for (int i = 0; i < size; i++) { + assertEquals(i, list.indexOf(i)); + assertEquals(i, list.subList(0, size).indexOf(i)); + assertEquals(i, list.subList(0, i + 1).indexOf(i)); + assertEquals(-1, list.subList(0, i).indexOf(i)); + assertEquals(0, list.subList(i, size).indexOf(i)); + assertEquals(-1, list.subList(i + 1, size).indexOf(i)); + } + + list.add(1); + assertEquals(1, list.indexOf(1)); + assertEquals(1, list.subList(0, size + 1).indexOf(1)); + assertEquals(0, list.subList(1, size + 1).indexOf(1)); + assertEquals(size - 2, list.subList(2, size + 1).indexOf(1)); + assertEquals(0, list.subList(size, size + 1).indexOf(1)); + assertEquals(-1, list.subList(size + 1, size + 1).indexOf(1)); } /** - * indexOf gives the index based on the given index - * at which to start searching + * indexOf(E, int) returns the index of the first occurrence of the + * specified element in this list, searching forwards from index, + * or returns -1 if the element is not found */ public void testIndexOf2() { - CopyOnWriteArrayList full = populatedArray(3); - assertEquals(1, full.indexOf(one, 0)); - assertEquals(-1, full.indexOf(one, 2)); + CopyOnWriteArrayList list = populatedArray(3); + int size = list.size(); + assertEquals(-1, list.indexOf(-42, 0)); + + // we might expect IOOBE, but spec says otherwise + assertEquals(-1, list.indexOf(0, size)); + assertEquals(-1, list.indexOf(0, Integer.MAX_VALUE)); + + assertThrows( + IndexOutOfBoundsException.class, + () -> list.indexOf(0, -1), + () -> list.indexOf(0, Integer.MIN_VALUE)); + + for (int i = 0; i < size; i++) { + assertEquals(i, list.indexOf(i, 0)); + assertEquals(i, list.indexOf(i, i)); + assertEquals(-1, list.indexOf(i, i + 1)); + } + + list.add(1); + assertEquals(1, list.indexOf(1, 0)); + assertEquals(1, list.indexOf(1, 1)); + assertEquals(size, list.indexOf(1, 2)); + assertEquals(size, list.indexOf(1, size)); } /** @@ -256,7 +317,7 @@ public class CopyOnWriteArrayListTest ex Integer[] elements = new Integer[SIZE]; for (int i = 0; i < SIZE; i++) elements[i] = i; - Collections.shuffle(Arrays.asList(elements)); + shuffle(elements); Collection full = populatedArray(elements); Iterator it = full.iterator(); @@ -302,25 +363,61 @@ public class CopyOnWriteArrayListTest ex } /** - * lastIndexOf returns the index for the given object + * lastIndexOf(Object) returns the index of the last occurrence of + * the specified element in this list, or -1 if this list does not + * contain the element */ public void testLastIndexOf1() { - CopyOnWriteArrayList full = populatedArray(3); - full.add(one); - full.add(three); - assertEquals(3, full.lastIndexOf(one)); - assertEquals(-1, full.lastIndexOf(six)); + CopyOnWriteArrayList list = populatedArray(3); + assertEquals(-1, list.lastIndexOf(-42)); + int size = list.size(); + for (int i = 0; i < size; i++) { + assertEquals(i, list.lastIndexOf(i)); + assertEquals(i, list.subList(0, size).lastIndexOf(i)); + assertEquals(i, list.subList(0, i + 1).lastIndexOf(i)); + assertEquals(-1, list.subList(0, i).lastIndexOf(i)); + assertEquals(0, list.subList(i, size).lastIndexOf(i)); + assertEquals(-1, list.subList(i + 1, size).lastIndexOf(i)); + } + + list.add(1); + assertEquals(size, list.lastIndexOf(1)); + assertEquals(size, list.subList(0, size + 1).lastIndexOf(1)); + assertEquals(1, list.subList(0, size).lastIndexOf(1)); + assertEquals(0, list.subList(1, 2).lastIndexOf(1)); + assertEquals(-1, list.subList(0, 1).indexOf(1)); } /** - * lastIndexOf returns the index from the given starting point + * lastIndexOf(E, int) returns the index of the last occurrence of the + * specified element in this list, searching backwards from index, or + * returns -1 if the element is not found */ public void testLastIndexOf2() { - CopyOnWriteArrayList full = populatedArray(3); - full.add(one); - full.add(three); - assertEquals(3, full.lastIndexOf(one, 4)); - assertEquals(-1, full.lastIndexOf(three, 3)); + CopyOnWriteArrayList list = populatedArray(3); + + // we might expect IOOBE, but spec says otherwise + assertEquals(-1, list.lastIndexOf(0, -1)); + + int size = list.size(); + assertThrows( + IndexOutOfBoundsException.class, + () -> list.lastIndexOf(0, size), + () -> list.lastIndexOf(0, Integer.MAX_VALUE)); + + for (int i = 0; i < size; i++) { + assertEquals(i, list.lastIndexOf(i, i)); + assertEquals(list.indexOf(i), list.lastIndexOf(i, i)); + if (i > 0) + assertEquals(-1, list.lastIndexOf(i, i - 1)); + } + list.add(one); + list.add(three); + assertEquals(1, list.lastIndexOf(one, 1)); + assertEquals(1, list.lastIndexOf(one, 2)); + assertEquals(3, list.lastIndexOf(one, 3)); + assertEquals(3, list.lastIndexOf(one, 4)); + assertEquals(-1, list.lastIndexOf(three, 3)); } /** @@ -343,7 +440,7 @@ public class CopyOnWriteArrayListTest ex ListIterator i = full.listIterator(1); int j; for (j = 0; i.hasNext(); j++) - assertEquals(j+1, i.next()); + assertEquals(j + 1, i.next()); assertEquals(2, j); } @@ -387,10 +484,9 @@ public class CopyOnWriteArrayListTest ex */ public void testRemoveAll() { CopyOnWriteArrayList full = populatedArray(3); - Vector v = new Vector(); - v.add(one); - v.add(two); - full.removeAll(v); + assertTrue(full.removeAll(Arrays.asList(one, two))); + assertEquals(1, full.size()); + assertFalse(full.removeAll(Arrays.asList(one, two))); assertEquals(1, full.size()); } @@ -425,7 +521,7 @@ public class CopyOnWriteArrayListTest ex Integer[] elements = new Integer[SIZE]; for (int i = 0; i < SIZE; i++) elements[i] = i; - Collections.shuffle(Arrays.asList(elements)); + shuffle(elements); Collection full = populatedArray(elements); assertTrue(Arrays.equals(elements, full.toArray())); @@ -443,7 +539,7 @@ public class CopyOnWriteArrayListTest ex a = new Integer[0]; assertSame(a, empty.toArray(a)); - a = new Integer[SIZE/2]; + a = new Integer[SIZE / 2]; Arrays.fill(a, 42); assertSame(a, empty.toArray(a)); assertNull(a[0]); @@ -453,7 +549,7 @@ public class CopyOnWriteArrayListTest ex Integer[] elements = new Integer[SIZE]; for (int i = 0; i < SIZE; i++) elements[i] = i; - Collections.shuffle(Arrays.asList(elements)); + shuffle(elements); Collection full = populatedArray(elements); Arrays.fill(a, 42); @@ -467,7 +563,7 @@ public class CopyOnWriteArrayListTest ex assertSame(a, full.toArray(a)); assertTrue(Arrays.equals(elements, a)); - a = new Integer[2*SIZE]; + a = new Integer[2 * SIZE]; Arrays.fill(a, 42); assertSame(a, full.toArray(a)); assertTrue(Arrays.equals(elements, Arrays.copyOf(a, SIZE))); @@ -497,6 +593,11 @@ public class CopyOnWriteArrayListTest ex assertEquals(a.get(4), m1); s.clear(); assertEquals(7, a.size()); + + assertThrows( + IndexOutOfBoundsException.class, + () -> s.get(0), + () -> s.set(0, 42)); } // Exception tests @@ -727,7 +828,7 @@ public class CopyOnWriteArrayListTest ex } /** - * a deserialized serialized list is equal + * a deserialized/reserialized list equals original */ public void testSerialization() throws Exception { List x = populatedArray(SIZE);