--- a/jdk/src/share/classes/java/util/Collections.java Fri Sep 13 12:20:53 2013 +0100
+++ b/jdk/src/share/classes/java/util/Collections.java Fri Sep 13 11:18:44 2013 -0700
@@ -3900,6 +3900,7 @@
return batchRemove(c, true);
}
private boolean batchRemove(Collection<?> c, boolean complement) {
+ Objects.requireNonNull(c);
boolean modified = false;
Iterator<Map.Entry<K,V>> it = iterator();
while (it.hasNext()) {
--- a/jdk/src/share/classes/java/util/Hashtable.java Fri Sep 13 12:20:53 2013 +0100
+++ b/jdk/src/share/classes/java/util/Hashtable.java Fri Sep 13 11:18:44 2013 -0700
@@ -957,6 +957,8 @@
@Override
public synchronized boolean replace(K key, V oldValue, V newValue) {
+ Objects.requireNonNull(oldValue);
+ Objects.requireNonNull(newValue);
Entry<?,?> tab[] = table;
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
@@ -977,6 +979,7 @@
@Override
public synchronized V replace(K key, V value) {
+ Objects.requireNonNull(value);
Entry<?,?> tab[] = table;
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
--- a/jdk/src/share/classes/java/util/IdentityHashMap.java Fri Sep 13 12:20:53 2013 +0100
+++ b/jdk/src/share/classes/java/util/IdentityHashMap.java Fri Sep 13 11:18:44 2013 -0700
@@ -997,6 +997,7 @@
* behavior when c is a smaller "normal" (non-identity-based) Set.
*/
public boolean removeAll(Collection<?> c) {
+ Objects.requireNonNull(c);
boolean modified = false;
for (Iterator<K> i = iterator(); i.hasNext(); ) {
if (c.contains(i.next())) {
@@ -1212,6 +1213,7 @@
* behavior when c is a smaller "normal" (non-identity-based) Set.
*/
public boolean removeAll(Collection<?> c) {
+ Objects.requireNonNull(c);
boolean modified = false;
for (Iterator<Map.Entry<K,V>> i = iterator(); i.hasNext(); ) {
if (c.contains(i.next())) {
--- a/jdk/src/share/classes/java/util/Map.java Fri Sep 13 12:20:53 2013 +0100
+++ b/jdk/src/share/classes/java/util/Map.java Fri Sep 13 11:18:44 2013 -0700
@@ -805,6 +805,10 @@
* return false;
* }</pre>
*
+ * The default implementation does not throw NullPointerException
+ * for maps that do not support null values if oldValue is null unless
+ * newValue is also null.
+ *
* @param key key with which the specified value is associated
* @param oldValue value expected to be associated with the specified key
* @param newValue value to be associated with the specified key
@@ -814,8 +818,11 @@
* (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws ClassCastException if the class of a specified key or value
* prevents it from being stored in this map
- * @throws NullPointerException if a specified key or value is null,
+ * @throws NullPointerException if a specified key or newValue is null,
* and this map does not permit null keys or values
+ * @throws NullPointerException if oldValue is null and this map does not
+ * permit null values
+ * (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws IllegalArgumentException if some property of a specified key
* or value prevents it from being stored in this map
* @since 1.8
--- a/jdk/src/share/classes/java/util/TreeMap.java Fri Sep 13 12:20:53 2013 +0100
+++ b/jdk/src/share/classes/java/util/TreeMap.java Fri Sep 13 11:18:44 2013 -0700
@@ -1012,7 +1012,7 @@
int expectedModCount = modCount;
for (Entry<K, V> e = getFirstEntry(); e != null; e = successor(e)) {
- e.value = Objects.requireNonNull(function.apply(e.key, e.value));
+ e.value = function.apply(e.key, e.value);
if (expectedModCount != modCount) {
throw new ConcurrentModificationException();
--- a/jdk/src/share/classes/java/util/concurrent/ConcurrentHashMap.java Fri Sep 13 12:20:53 2013 +0100
+++ b/jdk/src/share/classes/java/util/concurrent/ConcurrentHashMap.java Fri Sep 13 11:18:44 2013 -0700
@@ -49,6 +49,7 @@
import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;
+import java.util.Objects;
import java.util.Set;
import java.util.Spliterator;
import java.util.concurrent.ConcurrentMap;
@@ -4410,6 +4411,7 @@
}
public final boolean removeAll(Collection<?> c) {
+ Objects.requireNonNull(c);
boolean modified = false;
for (Iterator<E> it = iterator(); it.hasNext();) {
if (c.contains(it.next())) {
@@ -4421,6 +4423,7 @@
}
public final boolean retainAll(Collection<?> c) {
+ Objects.requireNonNull(c);
boolean modified = false;
for (Iterator<E> it = iterator(); it.hasNext();) {
if (!c.contains(it.next())) {
--- a/jdk/src/share/classes/javax/security/auth/Subject.java Fri Sep 13 12:20:53 2013 +0100
+++ b/jdk/src/share/classes/javax/security/auth/Subject.java Fri Sep 13 11:18:44 2013 -0700
@@ -1186,7 +1186,7 @@
}
public boolean removeAll(Collection<?> c) {
-
+ Objects.requireNonNull(c);
boolean modified = false;
final Iterator<E> e = iterator();
while (e.hasNext()) {
@@ -1222,7 +1222,7 @@
}
public boolean retainAll(Collection<?> c) {
-
+ Objects.requireNonNull(c);
boolean modified = false;
boolean retain = false;
final Iterator<E> e = iterator();
--- a/jdk/test/java/util/Collection/CollectionDefaults.java Fri Sep 13 12:20:53 2013 +0100
+++ b/jdk/test/java/util/Collection/CollectionDefaults.java Fri Sep 13 11:18:44 2013 -0700
@@ -21,15 +21,19 @@
* questions.
*/
+import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
+import java.util.SortedSet;
+
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
@@ -38,43 +42,68 @@
import java.util.TreeMap;
import java.util.TreeSet;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentSkipListMap;
import java.util.function.Predicate;
+import java.util.function.Supplier;
/**
* @test
+ * @summary Unit tests for extension methods on Collection
* @library testlibrary
- * @build CollectionAsserts CollectionSupplier
+ * @build CollectionAsserts CollectionSupplier ExtendsAbstractSet ExtendsAbstractCollection
* @run testng CollectionDefaults
- * @summary Unit tests for extension methods on Collection
*/
public class CollectionDefaults {
public static final Predicate<Integer> pEven = x -> 0 == x % 2;
public static final Predicate<Integer> pOdd = x -> 1 == x % 2;
- private static final String[] SET_CLASSES = {
- "java.util.HashSet",
- "java.util.LinkedHashSet",
- "java.util.TreeSet"
+ @SuppressWarnings("unchecked")
+ private static final Supplier<?>[] TEST_CLASSES = {
+ // Collection
+ ExtendsAbstractCollection<Integer>::new,
+
+ // Lists
+ java.util.ArrayList<Integer>::new,
+ java.util.LinkedList<Integer>::new,
+ java.util.Vector<Integer>::new,
+ java.util.concurrent.CopyOnWriteArrayList<Integer>::new,
+ ExtendsAbstractList<Integer>::new,
+
+ // Sets
+ java.util.HashSet<Integer>::new,
+ java.util.LinkedHashSet<Integer>::new,
+ java.util.TreeSet<Integer>::new,
+ java.util.concurrent.ConcurrentSkipListSet<Integer>::new,
+ java.util.concurrent.CopyOnWriteArraySet<Integer>::new,
+ ExtendsAbstractSet<Integer>::new
};
private static final int SIZE = 100;
@DataProvider(name="setProvider", parallel=true)
- public static Object[][] setCases() {
+ public static Iterator<Object[]> setCases() {
final List<Object[]> cases = new LinkedList<>();
cases.add(new Object[] { new HashSet<>() });
cases.add(new Object[] { new LinkedHashSet<>() });
cases.add(new Object[] { new TreeSet<>() });
+ cases.add(new Object[] { new java.util.concurrent.ConcurrentSkipListSet<>() });
+ cases.add(new Object[] { new java.util.concurrent.CopyOnWriteArraySet<>() });
+
+ cases.add(new Object[] { new ExtendsAbstractSet<>() });
cases.add(new Object[] { Collections.newSetFromMap(new HashMap<>()) });
cases.add(new Object[] { Collections.newSetFromMap(new LinkedHashMap()) });
cases.add(new Object[] { Collections.newSetFromMap(new TreeMap<>()) });
+ cases.add(new Object[] { Collections.newSetFromMap(new ConcurrentHashMap<>()) });
+ cases.add(new Object[] { Collections.newSetFromMap(new ConcurrentSkipListMap<>()) });
- cases.add(new Object[] { new HashSet(){{add(42);}} });
- cases.add(new Object[] { new LinkedHashSet(){{add(42);}} });
- cases.add(new Object[] { new TreeSet(){{add(42);}} });
- return cases.toArray(new Object[0][cases.size()]);
+ cases.add(new Object[] { new HashSet<Integer>(){{add(42);}} });
+ cases.add(new Object[] { new ExtendsAbstractSet<Integer>(){{add(42);}} });
+ cases.add(new Object[] { new LinkedHashSet<Integer>(){{add(42);}} });
+ cases.add(new Object[] { new TreeSet<Integer>(){{add(42);}} });
+ return cases.iterator();
}
@Test(dataProvider = "setProvider")
@@ -82,57 +111,66 @@
try {
set.forEach(null);
fail("expected NPE not thrown");
- } catch (NullPointerException npe) {}
+ } catch (NullPointerException expected) {
+ ; // expected
+ }
try {
set.removeIf(null);
fail("expected NPE not thrown");
- } catch (NullPointerException npe) {}
+ } catch (NullPointerException expected) {
+ ; // expected
+ }
}
@Test
public void testForEach() throws Exception {
- final CollectionSupplier supplier = new CollectionSupplier(SET_CLASSES, SIZE);
- for (final CollectionSupplier.TestCase test : supplier.get()) {
- final Set<Integer> original = ((Set<Integer>) test.original);
- final Set<Integer> set = ((Set<Integer>) test.collection);
+ final CollectionSupplier<Collection<Integer>> supplier = new CollectionSupplier((Supplier<Collection<Integer>>[]) TEST_CLASSES, SIZE);
+
+ for (final CollectionSupplier.TestCase<Collection<Integer>> test : supplier.get()) {
+ final Collection<Integer> original = test.expected;
+ final Collection<Integer> set = test.collection;
try {
set.forEach(null);
fail("expected NPE not thrown");
- } catch (NullPointerException npe) {}
- if (test.className.equals("java.util.HashSet")) {
- CollectionAsserts.assertContentsUnordered(set, original);
+ } catch (NullPointerException expected) {
+ ; // expected
+ }
+ if (set instanceof Set && !((set instanceof SortedSet) || (set instanceof LinkedHashSet))) {
+ CollectionAsserts.assertContentsUnordered(set, original, test.toString());
} else {
- CollectionAsserts.assertContents(set, original);
+ CollectionAsserts.assertContents(set, original, test.toString());
}
final List<Integer> actual = new LinkedList<>();
set.forEach(actual::add);
- if (test.className.equals("java.util.HashSet")) {
- CollectionAsserts.assertContentsUnordered(actual, set);
- CollectionAsserts.assertContentsUnordered(actual, original);
+ if (set instanceof Set && !((set instanceof SortedSet) || (set instanceof LinkedHashSet))) {
+ CollectionAsserts.assertContentsUnordered(actual, set, test.toString());
+ CollectionAsserts.assertContentsUnordered(actual, original, test.toString());
} else {
- CollectionAsserts.assertContents(actual, set);
- CollectionAsserts.assertContents(actual, original);
+ CollectionAsserts.assertContents(actual, set, test.toString());
+ CollectionAsserts.assertContents(actual, original, test.toString());
}
}
}
@Test
public void testRemoveIf() throws Exception {
- final CollectionSupplier supplier = new CollectionSupplier(SET_CLASSES, SIZE);
- for (final CollectionSupplier.TestCase test : supplier.get()) {
- final Set<Integer> original = ((Set<Integer>) test.original);
- final Set<Integer> set = ((Set<Integer>) test.collection);
+ final CollectionSupplier<Collection<Integer>> supplier = new CollectionSupplier((Supplier<Collection<Integer>>[]) TEST_CLASSES, SIZE);
+ for (final CollectionSupplier.TestCase<Collection<Integer>> test : supplier.get()) {
+ final Collection<Integer> original = test.expected;
+ final Collection<Integer> set = test.collection;
try {
set.removeIf(null);
fail("expected NPE not thrown");
- } catch (NullPointerException npe) {}
- if (test.className.equals("java.util.HashSet")) {
- CollectionAsserts.assertContentsUnordered(set, original);
+ } catch (NullPointerException expected) {
+ ; // expected
+ }
+ if (set instanceof Set && !((set instanceof SortedSet) || (set instanceof LinkedHashSet))) {
+ CollectionAsserts.assertContentsUnordered(set, original, test.toString());
} else {
- CollectionAsserts.assertContents(set, original);
+ CollectionAsserts.assertContents(set, original, test.toString());
}
set.removeIf(pEven);
--- a/jdk/test/java/util/Collection/ListDefaults.java Fri Sep 13 12:20:53 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,536 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import java.util.LinkedList;
-import java.util.Stack;
-import java.util.TreeMap;
-import java.util.TreeSet;
-import java.util.Vector;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.testng.annotations.DataProvider;
-import org.testng.annotations.Test;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertTrue;
-import static org.testng.Assert.fail;
-
-import java.lang.reflect.Constructor;
-import java.util.ConcurrentModificationException;
-import java.util.function.Predicate;
-
-/**
- * @test
- * @bug 8023367
- * @library testlibrary
- * @build CollectionAsserts CollectionSupplier
- * @run testng ListDefaults
- * @summary Unit tests for extension methods on List
- */
-public class ListDefaults {
-
- private static final String[] LIST_CLASSES = {
- "java.util.ArrayList",
- "java.util.LinkedList",
- "java.util.Vector",
- "java.util.concurrent.CopyOnWriteArrayList"
- };
-
- private static final String[] LIST_CME_CLASSES = {
- "java.util.ArrayList",
- "java.util.Vector"
- };
-
- private static final Predicate<Integer> pEven = x -> 0 == x % 2;
- private static final Predicate<Integer> pOdd = x -> 1 == x % 2;
-
- private static final Comparator<Integer> BIT_COUNT_COMPARATOR =
- (x, y) -> Integer.bitCount(x) - Integer.bitCount(y);
-
- private static final Comparator<AtomicInteger> ATOMIC_INTEGER_COMPARATOR =
- (x, y) -> x.intValue() - y.intValue();
-
- private static final int SIZE = 100;
- private static final int SUBLIST_FROM = 20;
- private static final int SUBLIST_TO = SIZE - 5;
- private static final int SUBLIST_SIZE = SUBLIST_TO - SUBLIST_FROM;
-
- private static interface Callback {
- void call(List<Integer> list);
- }
-
- // call the callback for each recursive subList
- private void trimmedSubList(final List<Integer> list, final Callback callback) {
- int size = list.size();
- if (size > 1) {
- // trim 1 element from both ends
- final List<Integer> subList = list.subList(1, size - 1);
- callback.call(subList);
- trimmedSubList(subList, callback);
- }
- }
-
- @DataProvider(name="listProvider", parallel=true)
- public static Object[][] listCases() {
- final List<Object[]> cases = new LinkedList<>();
- cases.add(new Object[] { Collections.emptyList() });
- cases.add(new Object[] { new ArrayList<>() });
- cases.add(new Object[] { new LinkedList<>() });
- cases.add(new Object[] { new Vector<>() });
- cases.add(new Object[] { new Stack<>() });
- cases.add(new Object[] { new CopyOnWriteArrayList<>() });
-
- cases.add(new Object[] { new ArrayList(){{add(42);}} });
- cases.add(new Object[] { new LinkedList(){{add(42);}} });
- cases.add(new Object[] { new Vector(){{add(42);}} });
- cases.add(new Object[] { new Stack(){{add(42);}} });
- cases.add(new Object[] { new CopyOnWriteArrayList(){{add(42);}} });
- return cases.toArray(new Object[0][cases.size()]);
- }
-
- @Test(dataProvider = "listProvider")
- public void testProvidedWithNull(final List<Integer> list) throws Exception {
- try {
- list.forEach(null);
- fail("expected NPE not thrown");
- } catch (NullPointerException npe) {}
- try {
- list.replaceAll(null);
- fail("expected NPE not thrown");
- } catch (NullPointerException npe) {}
- try {
- list.removeIf(null);
- fail("expected NPE not thrown");
- } catch (NullPointerException npe) {}
- try {
- list.sort(null);
- } catch (Throwable t) {
- fail("Exception not expected: " + t);
- }
- }
-
- @Test
- public void testForEach() throws Exception {
- final CollectionSupplier supplier = new CollectionSupplier(LIST_CLASSES, SIZE);
- for (final CollectionSupplier.TestCase test : supplier.get()) {
- final List<Integer> original = ((List<Integer>) test.original);
- final List<Integer> list = ((List<Integer>) test.collection);
- }
- for (final CollectionSupplier.TestCase test : supplier.get()) {
- final List<Integer> original = ((List<Integer>) test.original);
- final List<Integer> list = ((List<Integer>) test.collection);
-
- try {
- list.forEach(null);
- fail("expected NPE not thrown");
- } catch (NullPointerException npe) {}
- CollectionAsserts.assertContents(list, original);
-
- final List<Integer> actual = new LinkedList<>();
- list.forEach(actual::add);
- CollectionAsserts.assertContents(actual, list);
- CollectionAsserts.assertContents(actual, original);
-
- if (original.size() > SUBLIST_SIZE) {
- final List<Integer> subList = original.subList(SUBLIST_FROM, SUBLIST_TO);
- final List<Integer> actualSubList = new LinkedList<>();
- subList.forEach(actualSubList::add);
- assertEquals(actualSubList.size(), SUBLIST_SIZE);
- for (int i = 0; i < SUBLIST_SIZE; i++) {
- assertEquals(actualSubList.get(i), original.get(i + SUBLIST_FROM));
- }
- }
-
- trimmedSubList(list, new Callback() {
- @Override
- public void call(final List<Integer> list) {
- final List<Integer> actual = new LinkedList<>();
- list.forEach(actual::add);
- CollectionAsserts.assertContents(actual, list);
- }
- });
- }
- }
-
- @Test
- public void testRemoveIf() throws Exception {
- final CollectionSupplier supplier = new CollectionSupplier(LIST_CLASSES, SIZE);
-
- for (final CollectionSupplier.TestCase test : supplier.get()) {
- final List<Integer> original = ((List<Integer>) test.original);
- final List<Integer> list = ((List<Integer>) test.collection);
-
- try {
- list.removeIf(null);
- fail("expected NPE not thrown");
- } catch (NullPointerException npe) {}
- CollectionAsserts.assertContents(list, original);
-
- final AtomicInteger offset = new AtomicInteger(1);
- while (list.size() > 0) {
- removeFirst(original, list, offset);
- }
- }
-
- for (final CollectionSupplier.TestCase test : supplier.get()) {
- final List<Integer> original = ((List<Integer>) test.original);
- final List<Integer> list = ((List<Integer>) test.collection);
- list.removeIf(pOdd);
- for (int i : list) {
- assertTrue((i % 2) == 0);
- }
- for (int i : original) {
- if (i % 2 == 0) {
- assertTrue(list.contains(i));
- }
- }
- list.removeIf(pEven);
- assertTrue(list.isEmpty());
- }
-
- for (final CollectionSupplier.TestCase test : supplier.get()) {
- final List<Integer> original = ((List<Integer>) test.original);
- final List<Integer> list = ((List<Integer>) test.collection);
- final List<Integer> listCopy = new ArrayList<>(list);
- if (original.size() > SUBLIST_SIZE) {
- final List<Integer> subList = list.subList(SUBLIST_FROM, SUBLIST_TO);
- final List<Integer> subListCopy = new ArrayList<>(subList);
- listCopy.removeAll(subList);
- subList.removeIf(pOdd);
- for (int i : subList) {
- assertTrue((i % 2) == 0);
- }
- for (int i : subListCopy) {
- if (i % 2 == 0) {
- assertTrue(subList.contains(i));
- } else {
- assertFalse(subList.contains(i));
- }
- }
- subList.removeIf(pEven);
- assertTrue(subList.isEmpty());
- // elements outside the view should remain
- CollectionAsserts.assertContents(list, listCopy);
- }
- }
-
- for (final CollectionSupplier.TestCase test : supplier.get()) {
- final List<Integer> list = ((List<Integer>) test.collection);
- trimmedSubList(list, new Callback() {
- @Override
- public void call(final List<Integer> list) {
- final List<Integer> copy = new ArrayList<>(list);
- list.removeIf(pOdd);
- for (int i : list) {
- assertTrue((i % 2) == 0);
- }
- for (int i : copy) {
- if (i % 2 == 0) {
- assertTrue(list.contains(i));
- } else {
- assertFalse(list.contains(i));
- }
- }
- }
- });
- }
- }
-
- // remove the first element
- private void removeFirst(final List<Integer> original, final List<Integer> list, final AtomicInteger offset) {
- final AtomicBoolean first = new AtomicBoolean(true);
- list.removeIf(x -> first.getAndSet(false));
- CollectionAsserts.assertContents(original.subList(offset.getAndIncrement(), original.size()), list);
- }
-
- @Test
- public void testReplaceAll() throws Exception {
- final int scale = 3;
- final CollectionSupplier supplier = new CollectionSupplier(LIST_CLASSES, SIZE);
- for (final CollectionSupplier.TestCase test : supplier.get()) {
- final List<Integer> original = ((List<Integer>) test.original);
- final List<Integer> list = ((List<Integer>) test.collection);
-
- try {
- list.replaceAll(null);
- fail("expected NPE not thrown");
- } catch (NullPointerException npe) {}
- CollectionAsserts.assertContents(list, original);
-
- list.replaceAll(x -> scale * x);
- for (int i=0; i < original.size(); i++) {
- assertTrue(list.get(i) == (scale * original.get(i)), "mismatch at index " + i);
- }
-
- if (original.size() > SUBLIST_SIZE) {
- final List<Integer> subList = list.subList(SUBLIST_FROM, SUBLIST_TO);
- subList.replaceAll(x -> x + 1);
- // verify elements in view [from, to) were replaced
- for (int i = 0; i < SUBLIST_SIZE; i++) {
- assertTrue(subList.get(i) == ((scale * original.get(i + SUBLIST_FROM)) + 1),
- "mismatch at sublist index " + i);
- }
- // verify that elements [0, from) remain unmodified
- for (int i = 0; i < SUBLIST_FROM; i++) {
- assertTrue(list.get(i) == (scale * original.get(i)),
- "mismatch at original index " + i);
- }
- // verify that elements [to, size) remain unmodified
- for (int i = SUBLIST_TO; i < list.size(); i++) {
- assertTrue(list.get(i) == (scale * original.get(i)),
- "mismatch at original index " + i);
- }
- }
- }
-
- for (final CollectionSupplier.TestCase test : supplier.get()) {
- final List<Integer> list = ((List<Integer>) test.collection);
- trimmedSubList(list, new Callback() {
- @Override
- public void call(final List<Integer> list) {
- final List<Integer> copy = new ArrayList<>(list);
- final int offset = 5;
- list.replaceAll(x -> offset + x);
- for (int i=0; i < copy.size(); i++) {
- assertTrue(list.get(i) == (offset + copy.get(i)), "mismatch at index " + i);
- }
- }
- });
- }
- }
-
- @Test
- public void testSort() throws Exception {
- final CollectionSupplier supplier = new CollectionSupplier(LIST_CLASSES, SIZE);
- for (final CollectionSupplier.TestCase test : supplier.get()) {
- final List<Integer> original = ((List<Integer>) test.original);
- final List<Integer> list = ((List<Integer>) test.collection);
- CollectionSupplier.shuffle(list);
- list.sort(Integer::compare);
- CollectionAsserts.assertSorted(list, Integer::compare);
- if (test.name.startsWith("reverse")) {
- Collections.reverse(list);
- }
- CollectionAsserts.assertContents(list, original);
-
- CollectionSupplier.shuffle(list);
- list.sort(null);
- CollectionAsserts.assertSorted(list, Comparator.<Integer>naturalOrder());
- if (test.name.startsWith("reverse")) {
- Collections.reverse(list);
- }
- CollectionAsserts.assertContents(list, original);
-
- CollectionSupplier.shuffle(list);
- list.sort(Comparator.<Integer>naturalOrder());
- CollectionAsserts.assertSorted(list, Comparator.<Integer>naturalOrder());
- if (test.name.startsWith("reverse")) {
- Collections.reverse(list);
- }
- CollectionAsserts.assertContents(list, original);
-
- CollectionSupplier.shuffle(list);
- list.sort(Comparator.<Integer>reverseOrder());
- CollectionAsserts.assertSorted(list, Comparator.<Integer>reverseOrder());
- if (!test.name.startsWith("reverse")) {
- Collections.reverse(list);
- }
- CollectionAsserts.assertContents(list, original);
-
- CollectionSupplier.shuffle(list);
- list.sort(BIT_COUNT_COMPARATOR);
- CollectionAsserts.assertSorted(list, BIT_COUNT_COMPARATOR);
- // check sort by verifying that bitCount increases and never drops
- int minBitCount = 0;
- int bitCount = 0;
- for (final Integer i : list) {
- bitCount = Integer.bitCount(i);
- assertTrue(bitCount >= minBitCount);
- minBitCount = bitCount;
- }
-
- @SuppressWarnings("unchecked")
- final Class<? extends List<AtomicInteger>> type =
- (Class<? extends List<AtomicInteger>>) Class.forName(test.className);
- final Constructor<? extends List<AtomicInteger>> defaultConstructor = type.getConstructor();
- final List<AtomicInteger> incomparables = (List<AtomicInteger>) defaultConstructor.newInstance();
-
- for (int i=0; i < test.original.size(); i++) {
- incomparables.add(new AtomicInteger(i));
- }
- CollectionSupplier.shuffle(incomparables);
- incomparables.sort(ATOMIC_INTEGER_COMPARATOR);
- for (int i=0; i < test.original.size(); i++) {
- assertEquals(i, incomparables.get(i).intValue());
- }
-
- if (original.size() > SUBLIST_SIZE) {
- final List<Integer> copy = new ArrayList<>(list);
- final List<Integer> subList = list.subList(SUBLIST_FROM, SUBLIST_TO);
- CollectionSupplier.shuffle(subList);
- subList.sort(Comparator.<Integer>naturalOrder());
- CollectionAsserts.assertSorted(subList, Comparator.<Integer>naturalOrder());
- // verify that elements [0, from) remain unmodified
- for (int i = 0; i < SUBLIST_FROM; i++) {
- assertTrue(list.get(i) == copy.get(i),
- "mismatch at index " + i);
- }
- // verify that elements [to, size) remain unmodified
- for (int i = SUBLIST_TO; i < list.size(); i++) {
- assertTrue(list.get(i) == copy.get(i),
- "mismatch at index " + i);
- }
- }
- }
-
- for (final CollectionSupplier.TestCase test : supplier.get()) {
- final List<Integer> list = ((List<Integer>) test.collection);
- trimmedSubList(list, new Callback() {
- @Override
- public void call(final List<Integer> list) {
- final List<Integer> copy = new ArrayList<>(list);
- CollectionSupplier.shuffle(list);
- list.sort(Comparator.<Integer>naturalOrder());
- CollectionAsserts.assertSorted(list, Comparator.<Integer>naturalOrder());
- }
- });
- }
- }
-
- @Test
- public void testForEachThrowsCME() throws Exception {
- final CollectionSupplier supplier = new CollectionSupplier(LIST_CME_CLASSES, SIZE);
- for (final CollectionSupplier.TestCase test : supplier.get()) {
- final List<Integer> list = ((List<Integer>) test.collection);
- if (list.size() <= 1) {
- continue;
- }
- boolean gotException = false;
- try {
- // bad predicate that modifies its list, should throw CME
- list.forEach((x) -> {list.add(x);});
- } catch (ConcurrentModificationException cme) {
- gotException = true;
- }
- if (!gotException) {
- fail("expected CME was not thrown from " + test);
- }
- }
- }
-
- @Test
- public void testRemoveIfThrowsCME() throws Exception {
- final CollectionSupplier supplier = new CollectionSupplier(LIST_CME_CLASSES, SIZE);
- for (final CollectionSupplier.TestCase test : supplier.get()) {
- final List<Integer> list = ((List<Integer>) test.collection);
- if (list.size() <= 1) {
- continue;
- }
- boolean gotException = false;
- try {
- // bad predicate that modifies its list, should throw CME
- list.removeIf((x) -> {return list.add(x);});
- } catch (ConcurrentModificationException cme) {
- gotException = true;
- }
- if (!gotException) {
- fail("expected CME was not thrown from " + test);
- }
- }
- }
-
- @Test
- public void testReplaceAllThrowsCME() throws Exception {
- final CollectionSupplier supplier = new CollectionSupplier(LIST_CME_CLASSES, SIZE);
- for (final CollectionSupplier.TestCase test : supplier.get()) {
- final List<Integer> list = ((List<Integer>) test.collection);
- if (list.size() <= 1) {
- continue;
- }
- boolean gotException = false;
- try {
- // bad predicate that modifies its list, should throw CME
- list.replaceAll(x -> {int n = 3 * x; list.add(n); return n;});
- } catch (ConcurrentModificationException cme) {
- gotException = true;
- }
- if (!gotException) {
- fail("expected CME was not thrown from " + test);
- }
- }
- }
-
- @Test
- public void testSortThrowsCME() throws Exception {
- final CollectionSupplier supplier = new CollectionSupplier(LIST_CME_CLASSES, SIZE);
- for (final CollectionSupplier.TestCase test : supplier.get()) {
- final List<Integer> list = ((List<Integer>) test.collection);
- if (list.size() <= 1) {
- continue;
- }
- boolean gotException = false;
- try {
- // bad predicate that modifies its list, should throw CME
- list.sort((x, y) -> {list.add(x); return x - y;});
- } catch (ConcurrentModificationException cme) {
- gotException = true;
- }
- if (!gotException) {
- fail("expected CME was not thrown from " + test);
- }
- }
- }
-
- private static final List<Integer> SLICED_EXPECTED = Arrays.asList(0, 1, 2, 3, 5, 6, 7, 8, 9);
- private static final List<Integer> SLICED_EXPECTED2 = Arrays.asList(0, 1, 2, 5, 6, 7, 8, 9);
-
- @DataProvider(name="shortIntListProvider", parallel=true)
- public static Object[][] intListCases() {
- final Integer[] DATA = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
- final List<Object[]> cases = new LinkedList<>();
- cases.add(new Object[] { new ArrayList<>(Arrays.asList(DATA)) });
- cases.add(new Object[] { new LinkedList<>(Arrays.asList(DATA)) });
- cases.add(new Object[] { new Vector<>(Arrays.asList(DATA)) });
- cases.add(new Object[] { new CopyOnWriteArrayList<>(Arrays.asList(DATA)) });
- return cases.toArray(new Object[0][cases.size()]);
- }
-
- @Test(dataProvider = "shortIntListProvider")
- public void testRemoveIfFromSlice(final List<Integer> list) throws Exception {
- final List<Integer> sublist = list.subList(3, 6);
- assertTrue(sublist.removeIf(x -> x == 4));
- CollectionAsserts.assertContents(list, SLICED_EXPECTED);
-
- final List<Integer> sublist2 = list.subList(2, 5);
- assertTrue(sublist2.removeIf(x -> x == 3));
- CollectionAsserts.assertContents(list, SLICED_EXPECTED2);
- }
-}
--- a/jdk/test/java/util/Collection/MOAT.java Fri Sep 13 12:20:53 2013 +0100
+++ b/jdk/test/java/util/Collection/MOAT.java Fri Sep 13 11:18:44 2013 -0700
@@ -400,8 +400,6 @@
// If add(null) succeeds, contains(null) & remove(null) should succeed
//----------------------------------------------------------------
private static void testNullElement(Collection<Integer> c) {
- // !!!! 5018849: (coll) TreeSet.contains(null) does not agree with Javadoc
- if (c instanceof TreeSet) return;
try {
check(c.add(null));
--- a/jdk/test/java/util/Collection/testlibrary/CollectionAsserts.java Fri Sep 13 12:20:53 2013 +0100
+++ b/jdk/test/java/util/Collection/testlibrary/CollectionAsserts.java Fri Sep 13 11:18:44 2013 -0700
@@ -41,6 +41,10 @@
*/
public class CollectionAsserts {
+ private CollectionAsserts() {
+ // no instances
+ }
+
public static void assertCountSum(Iterable<? super Integer> it, int count, int sum) {
assertCountSum(it.iterator(), count, sum);
}
@@ -117,10 +121,18 @@
}
public static<T> void assertContents(Iterable<T> actual, Iterable<T> expected) {
- assertContents(actual.iterator(), expected.iterator());
+ assertContents(actual, expected, null);
+ }
+
+ public static<T> void assertContents(Iterable<T> actual, Iterable<T> expected, String msg) {
+ assertContents(actual.iterator(), expected.iterator(), msg);
}
public static<T> void assertContents(Iterator<T> actual, Iterator<T> expected) {
+ assertContents(actual, expected, null);
+ }
+
+ public static<T> void assertContents(Iterator<T> actual, Iterator<T> expected, String msg) {
List<T> history = new ArrayList<>();
while (expected.hasNext()) {
@@ -128,20 +140,23 @@
List<T> expectedData = new ArrayList<>(history);
while (expected.hasNext())
expectedData.add(expected.next());
- fail(String.format("Premature end of data; expected=%s, found=%s", expectedData, history));
+ fail(String.format("%s Premature end of data; expected=%s, found=%s",
+ (msg == null ? "" : msg), expectedData, history));
}
T a = actual.next();
T e = expected.next();
history.add(a);
if (!Objects.equals(a, e))
- fail(String.format("Data mismatch; preceding=%s, nextExpected=%s, nextFound=%s", history, e, a));
+ fail(String.format("%s Data mismatch; preceding=%s, nextExpected=%s, nextFound=%s",
+ (msg == null ? "" : msg), history, e, a));
}
if (actual.hasNext()) {
List<T> rest = new ArrayList<>();
while (actual.hasNext())
rest.add(actual.next());
- fail(String.format("Unexpected data %s after %s", rest, history));
+ fail(String.format("%s Unexpected data %s after %s",
+ (msg == null ? "" : msg), rest, history));
}
}
@@ -151,30 +166,21 @@
assertContents(actual, Arrays.asList(expected).iterator());
}
- public static <T> boolean equalsContentsUnordered(Iterable<T> a, Iterable<T> b) {
- Set<T> sa = new HashSet<>();
- for (T t : a) {
- sa.add(t);
- }
+ public static<T extends Comparable<? super T>> void assertContentsUnordered(Iterable<T> actual, Iterable<T> expected) {
+ assertContentsUnordered(actual, expected, null);
+ }
- Set<T> sb = new HashSet<>();
- for (T t : b) {
- sb.add(t);
+ public static<T extends Comparable<? super T>> void assertContentsUnordered(Iterable<T> actual, Iterable<T> expected, String msg) {
+ List<T> allExpected = new ArrayList<>();
+ for (T t : expected) {
+ allExpected.add(t);
}
- return Objects.equals(sa, sb);
- }
+ for (T t : actual) {
+ assertTrue(allExpected.remove(t), msg + " element '" + String.valueOf(t) + "' not found");
+ }
- public static<T extends Comparable<? super T>> void assertContentsUnordered(Iterable<T> actual, Iterable<T> expected) {
- ArrayList<T> one = new ArrayList<>();
- for (T t : actual)
- one.add(t);
- ArrayList<T> two = new ArrayList<>();
- for (T t : expected)
- two.add(t);
- Collections.sort(one);
- Collections.sort(two);
- assertContents(one, two);
+ assertTrue(allExpected.isEmpty(), msg + "expected contained additional elements");
}
static <T> void assertSplitContents(Iterable<Iterable<T>> splits, Iterable<T> list) {
--- a/jdk/test/java/util/Collection/testlibrary/CollectionSupplier.java Fri Sep 13 12:20:53 2013 +0100
+++ b/jdk/test/java/util/Collection/testlibrary/CollectionSupplier.java Fri Sep 13 11:18:44 2013 -0700
@@ -29,13 +29,11 @@
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
-import java.util.Set;
import org.testng.TestException;
import static org.testng.Assert.assertTrue;
-import java.lang.reflect.Constructor;
import java.util.Collection;
import java.util.Collections;
import java.util.function.Supplier;
@@ -44,15 +42,15 @@
* @library
* @summary A Supplier of test cases for Collection tests
*/
-public final class CollectionSupplier implements Supplier<Iterable<CollectionSupplier.TestCase>> {
+public final class CollectionSupplier<C extends Collection<Integer>> implements Supplier<Iterable<CollectionSupplier.TestCase<C>>> {
- private final String[] classNames;
+ private final Supplier<C>[] classes;
private final int size;
/**
* A Collection test case.
*/
- public static final class TestCase {
+ public static final class TestCase<C extends Collection<Integer>> {
/**
* The name of the test case.
@@ -60,57 +58,45 @@
public final String name;
/**
- * Class name of the instantiated Collection.
- */
- public final String className;
-
- /**
* Unmodifiable reference collection, useful for comparisons.
*/
- public final Collection<Integer> original;
+ public final List<Integer> expected;
/**
* A modifiable test collection.
*/
- public final Collection<Integer> collection;
+ public final C collection;
/**
* Create a Collection test case.
+ *
* @param name name of the test case
- * @param className class name of the instantiated collection
- * @param original reference collection
+ * @param expected reference collection
* @param collection the modifiable test collection
*/
- public TestCase(String name, String className,
- Collection<Integer> original, Collection<Integer> collection) {
+ public TestCase(String name, C collection) {
this.name = name;
- this.className = className;
- this.original =
- List.class.isAssignableFrom(original.getClass()) ?
- Collections.unmodifiableList((List<Integer>) original) :
- Set.class.isAssignableFrom(original.getClass()) ?
- Collections.unmodifiableSet((Set<Integer>) original) :
- Collections.unmodifiableCollection(original);
+ this.expected = Collections.unmodifiableList(
+ Arrays.asList(collection.toArray(new Integer[0])));
this.collection = collection;
}
@Override
public String toString() {
- return name + " " + className +
- "\n original: " + original +
- "\n target: " + collection;
+ return name + " " + collection.getClass().toString();
}
}
/**
* Shuffle a list using a PRNG with known seed for repeatability
+ *
* @param list the list to be shuffled
*/
public static <E> void shuffle(final List<E> list) {
// PRNG with known seed for repeatable tests
final Random prng = new Random(13);
final int size = list.size();
- for (int i=0; i < size; i++) {
+ for (int i = 0; i < size; i++) {
// random index in interval [i, size)
final int j = i + prng.nextInt(size - i);
// swap elements at indices i & j
@@ -127,178 +113,133 @@
* @param classNames class names that implement {@code Collection}
* @param size the desired size of each collection
*/
- public CollectionSupplier(String[] classNames, int size) {
- this.classNames = Arrays.copyOf(classNames, classNames.length);
+ public CollectionSupplier(Supplier<C>[] classes, int size) {
+ this.classes = Arrays.copyOf(classes, classes.length);
this.size = size;
}
@Override
- public Iterable<TestCase> get() {
- try {
- return getThrows();
- } catch (Exception e) {
- throw new TestException(e);
- }
- }
+ public Iterable<TestCase<C>> get() {
+ final Collection<TestCase<C>> cases = new LinkedList<>();
+ for (final Supplier<C> type : classes) {
+ try {
+ final Collection<Integer> empty = type.get();
+ cases.add(new TestCase("empty", empty));
- private Iterable<TestCase> getThrows() throws Exception {
- final Collection<TestCase> collections = new LinkedList<>();
- for (final String className : classNames) {
- @SuppressWarnings("unchecked")
- final Class<? extends Collection<Integer>> type =
- (Class<? extends Collection<Integer>>) Class.forName(className);
- final Constructor<? extends Collection<Integer>>
- defaultConstructor = type.getConstructor();
- final Constructor<? extends Collection<Integer>>
- copyConstructor = type.getConstructor(Collection.class);
+ final Collection<Integer> single = type.get();
+ single.add(42);
+ cases.add(new TestCase("single", single));
- final Collection<Integer> empty = defaultConstructor.newInstance();
- collections.add(new TestCase("empty",
- className,
- copyConstructor.newInstance(empty),
- empty));
+ final Collection<Integer> regular = type.get();
+ for (int i = 0; i < size; i++) {
+ regular.add(i);
+ }
+ cases.add(new TestCase("regular", regular));
- final Collection<Integer> single = defaultConstructor.newInstance();
- single.add(42);
- collections.add(new TestCase("single",
- className,
- copyConstructor.newInstance(single),
- single));
-
- final Collection<Integer> regular = defaultConstructor.newInstance();
- for (int i=0; i < size; i++) {
- regular.add(i);
- }
- collections.add(new TestCase("regular",
- className,
- copyConstructor.newInstance(regular),
- regular));
+ final Collection<Integer> reverse = type.get();
+ for (int i = size; i >= 0; i--) {
+ reverse.add(i);
+ }
+ cases.add(new TestCase("reverse", reverse));
- final Collection<Integer> reverse = defaultConstructor.newInstance();
- for (int i=size; i >= 0; i--) {
- reverse.add(i);
- }
- collections.add(new TestCase("reverse",
- className,
- copyConstructor.newInstance(reverse),
- reverse));
+ final Collection<Integer> odds = type.get();
+ for (int i = 0; i < size; i++) {
+ odds.add((i * 2) + 1);
+ }
+ cases.add(new TestCase("odds", odds));
- final Collection<Integer> odds = defaultConstructor.newInstance();
- for (int i=0; i < size; i++) {
- odds.add((i * 2) + 1);
- }
- collections.add(new TestCase("odds",
- className,
- copyConstructor.newInstance(odds),
- odds));
+ final Collection<Integer> evens = type.get();
+ for (int i = 0; i < size; i++) {
+ evens.add(i * 2);
+ }
+ cases.add(new TestCase("evens", evens));
- final Collection<Integer> evens = defaultConstructor.newInstance();
- for (int i=0; i < size; i++) {
- evens.add(i * 2);
- }
- collections.add(new TestCase("evens",
- className,
- copyConstructor.newInstance(evens),
- evens));
-
- final Collection<Integer> fibonacci = defaultConstructor.newInstance();
- int prev2 = 0;
- int prev1 = 1;
- for (int i=0; i < size; i++) {
- final int n = prev1 + prev2;
- if (n < 0) { // stop on overflow
- break;
+ final Collection<Integer> fibonacci = type.get();
+ int prev2 = 0;
+ int prev1 = 1;
+ for (int i = 0; i < size; i++) {
+ final int n = prev1 + prev2;
+ if (n < 0) { // stop on overflow
+ break;
+ }
+ fibonacci.add(n);
+ prev2 = prev1;
+ prev1 = n;
}
- fibonacci.add(n);
- prev2 = prev1;
- prev1 = n;
- }
- collections.add(new TestCase("fibonacci",
- className,
- copyConstructor.newInstance(fibonacci),
- fibonacci));
+ cases.add(new TestCase("fibonacci", fibonacci));
// variants where the size of the backing storage != reported size
- // created by removing half of the elements
+ // created by removing half of the elements
+ final Collection<Integer> emptyWithSlack = type.get();
+ emptyWithSlack.add(42);
+ assertTrue(emptyWithSlack.remove(42));
+ cases.add(new TestCase("emptyWithSlack", emptyWithSlack));
- final Collection<Integer> emptyWithSlack = defaultConstructor.newInstance();
- emptyWithSlack.add(42);
- assertTrue(emptyWithSlack.remove(42));
- collections.add(new TestCase("emptyWithSlack",
- className,
- copyConstructor.newInstance(emptyWithSlack),
- emptyWithSlack));
-
- final Collection<Integer> singleWithSlack = defaultConstructor.newInstance();
- singleWithSlack.add(42);
- singleWithSlack.add(43);
- assertTrue(singleWithSlack.remove(43));
- collections.add(new TestCase("singleWithSlack",
- className,
- copyConstructor.newInstance(singleWithSlack),
- singleWithSlack));
+ final Collection<Integer> singleWithSlack = type.get();
+ singleWithSlack.add(42);
+ singleWithSlack.add(43);
+ assertTrue(singleWithSlack.remove(43));
+ cases.add(new TestCase("singleWithSlack", singleWithSlack));
- final Collection<Integer> regularWithSlack = defaultConstructor.newInstance();
- for (int i=0; i < (2 * size); i++) {
- regularWithSlack.add(i);
- }
- assertTrue(regularWithSlack.removeIf((x) -> {return x >= size;}));
- collections.add(new TestCase("regularWithSlack",
- className,
- copyConstructor.newInstance(regularWithSlack),
- regularWithSlack));
+ final Collection<Integer> regularWithSlack = type.get();
+ for (int i = 0; i < (2 * size); i++) {
+ regularWithSlack.add(i);
+ }
+ assertTrue(regularWithSlack.removeIf((x) -> {
+ return x >= size;
+ }));
+ cases.add(new TestCase("regularWithSlack", regularWithSlack));
- final Collection<Integer> reverseWithSlack = defaultConstructor.newInstance();
- for (int i=2 * size; i >= 0; i--) {
- reverseWithSlack.add(i);
- }
- assertTrue(reverseWithSlack.removeIf((x) -> {return x < size;}));
- collections.add(new TestCase("reverseWithSlack",
- className,
- copyConstructor.newInstance(reverseWithSlack),
- reverseWithSlack));
+ final Collection<Integer> reverseWithSlack = type.get();
+ for (int i = 2 * size; i >= 0; i--) {
+ reverseWithSlack.add(i);
+ }
+ assertTrue(reverseWithSlack.removeIf((x) -> {
+ return x < size;
+ }));
+ cases.add(new TestCase("reverseWithSlack", reverseWithSlack));
- final Collection<Integer> oddsWithSlack = defaultConstructor.newInstance();
- for (int i = 0; i < 2 * size; i++) {
- oddsWithSlack.add((i * 2) + 1);
- }
- assertTrue(oddsWithSlack.removeIf((x) -> {return x >= size;}));
- collections.add(new TestCase("oddsWithSlack",
- className,
- copyConstructor.newInstance(oddsWithSlack),
- oddsWithSlack));
+ final Collection<Integer> oddsWithSlack = type.get();
+ for (int i = 0; i < 2 * size; i++) {
+ oddsWithSlack.add((i * 2) + 1);
+ }
+ assertTrue(oddsWithSlack.removeIf((x) -> {
+ return x >= size;
+ }));
+ cases.add(new TestCase("oddsWithSlack", oddsWithSlack));
+
+ final Collection<Integer> evensWithSlack = type.get();
+ for (int i = 0; i < 2 * size; i++) {
+ evensWithSlack.add(i * 2);
+ }
+ assertTrue(evensWithSlack.removeIf((x) -> {
+ return x >= size;
+ }));
+ cases.add(new TestCase("evensWithSlack", evensWithSlack));
- final Collection<Integer> evensWithSlack = defaultConstructor.newInstance();
- for (int i = 0; i < 2 * size; i++) {
- evensWithSlack.add(i * 2);
+ final Collection<Integer> fibonacciWithSlack = type.get();
+ prev2 = 0;
+ prev1 = 1;
+ for (int i = 0; i < size; i++) {
+ final int n = prev1 + prev2;
+ if (n < 0) { // stop on overflow
+ break;
+ }
+ fibonacciWithSlack.add(n);
+ prev2 = prev1;
+ prev1 = n;
+ }
+ assertTrue(fibonacciWithSlack.removeIf((x) -> {
+ return x < 20;
+ }));
+ cases.add(new TestCase("fibonacciWithSlack",
+ fibonacciWithSlack));
+ } catch (Exception failed) {
+ throw new TestException(failed);
}
- assertTrue(evensWithSlack.removeIf((x) -> {return x >= size;}));
- collections.add(new TestCase("evensWithSlack",
- className,
- copyConstructor.newInstance(evensWithSlack),
- evensWithSlack));
-
- final Collection<Integer> fibonacciWithSlack = defaultConstructor.newInstance();
- prev2 = 0;
- prev1 = 1;
- for (int i=0; i < size; i++) {
- final int n = prev1 + prev2;
- if (n < 0) { // stop on overflow
- break;
- }
- fibonacciWithSlack.add(n);
- prev2 = prev1;
- prev1 = n;
- }
- assertTrue(fibonacciWithSlack.removeIf((x) -> {return x < 20;}));
- collections.add(new TestCase("fibonacciWithSlack",
- className,
- copyConstructor.newInstance(fibonacciWithSlack),
- fibonacciWithSlack));
-
}
- return collections;
+ return cases;
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/Collection/testlibrary/ExtendsAbstractCollection.java Fri Sep 13 11:18:44 2013 -0700
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+import java.util.AbstractCollection;
+import java.util.HashSet;
+import java.util.AbstractSet;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.function.Supplier;
+
+/**
+ * @library
+ *
+ * A simple mutable collection implementation that provides only default
+ * implementations of all methods. ie. none of the Collection interface default
+ * methods have overridden implementations.
+ *
+ * @param <E> type of collection elements
+ */
+public class ExtendsAbstractCollection<E> extends AbstractCollection<E> {
+
+ protected final Collection<E> coll;
+
+ public ExtendsAbstractCollection() {
+ this(ArrayList<E>::new);
+ }
+
+ public ExtendsAbstractCollection(Collection<E> source) {
+ this();
+ coll.addAll(source);
+ }
+
+ protected ExtendsAbstractCollection(Supplier<Collection<E>> backer) {
+ this.coll = backer.get();
+ }
+
+ public boolean add(E element) {
+ return coll.add(element);
+ }
+
+ public boolean remove(Object element) {
+ return coll.remove(element);
+ }
+
+ public Iterator<E> iterator() {
+ return new Iterator<E>() {
+ Iterator<E> source = coll.iterator();
+
+ public boolean hasNext() {
+ return source.hasNext();
+ }
+
+ public E next() {
+ return source.next();
+ }
+
+ public void remove() {
+ source.remove();
+ }
+ };
+ }
+
+ public int size() {
+ return coll.size();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/Collection/testlibrary/ExtendsAbstractList.java Fri Sep 13 11:18:44 2013 -0700
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+import java.util.ArrayList;
+import java.util.AbstractList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.function.Supplier;
+
+/**
+ * @library
+ *
+ * A simple mutable list implementation that provides only default
+ * implementations of all methods. ie. none of the List interface default
+ * methods have overridden implementations.
+ *
+ * @param <E> type of list elements
+ */
+public class ExtendsAbstractList<E> extends AbstractList<E> {
+
+ protected final List<E> list;
+
+ public ExtendsAbstractList() {
+ this(ArrayList<E>::new);
+ }
+
+ protected ExtendsAbstractList(Supplier<List<E>> supplier) {
+ this.list = supplier.get();
+ }
+
+ public ExtendsAbstractList(Collection<E> source) {
+ this();
+ addAll(source);
+ }
+
+ public boolean add(E element) {
+ return list.add(element);
+ }
+
+ public E get(int index) {
+ return list.get(index);
+ }
+
+ public boolean remove(Object element) {
+ return list.remove(element);
+ }
+
+ public E set(int index, E element) {
+ return list.set(index, element);
+ }
+
+ public void add(int index, E element) {
+ list.add(index, element);
+ }
+
+ public E remove(int index) {
+ return list.remove(index);
+ }
+
+ public Iterator<E> iterator() {
+ return new Iterator<E>() {
+ Iterator<E> source = list.iterator();
+
+ public boolean hasNext() {
+ return source.hasNext();
+ }
+
+ public E next() {
+ return source.next();
+ }
+
+ public void remove() {
+ source.remove();
+ }
+ };
+ }
+
+ public int size() {
+ return list.size();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/Collection/testlibrary/ExtendsAbstractSet.java Fri Sep 13 11:18:44 2013 -0700
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+import java.util.HashSet;
+import java.util.AbstractSet;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.function.Supplier;
+
+/**
+ * @library
+ *
+ * A simple mutable set implementation that provides only default
+ * implementations of all methods. ie. none of the Set interface default methods
+ * have overridden implementations.
+ *
+ * @param <E> type of set members
+ */
+public class ExtendsAbstractSet<E> extends AbstractSet<E> {
+
+ protected final Set<E> set;
+
+ public ExtendsAbstractSet() {
+ this(HashSet<E>::new);
+ }
+
+ public ExtendsAbstractSet(Collection<E> source) {
+ this();
+ addAll(source);
+ }
+
+ protected ExtendsAbstractSet(Supplier<Set<E>> backer) {
+ this.set = backer.get();
+ }
+
+ public boolean add(E element) {
+ return set.add(element);
+ }
+
+ public boolean remove(Object element) {
+ return set.remove(element);
+ }
+
+ public Iterator<E> iterator() {
+ return new Iterator<E>() {
+ Iterator<E> source = set.iterator();
+
+ public boolean hasNext() {
+ return source.hasNext();
+ }
+
+ public E next() {
+ return source.next();
+ }
+
+ public void remove() {
+ source.remove();
+ }
+ };
+ }
+
+ public int size() {
+ return set.size();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/List/ListDefaults.java Fri Sep 13 11:18:44 2013 -0700
@@ -0,0 +1,535 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.LinkedList;
+import java.util.Stack;
+import java.util.Vector;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+import java.lang.reflect.Constructor;
+import java.util.ConcurrentModificationException;
+import java.util.function.Predicate;
+import java.util.function.Supplier;
+
+/**
+ * @test
+ * @summary Unit tests for extension methods on List
+ * @bug 8023367
+ * @library ../Collection/testlibrary
+ * @build CollectionAsserts CollectionSupplier ExtendsAbstractList
+ * @run testng ListDefaults
+ */
+public class ListDefaults {
+
+ private static final Supplier<?>[] LIST_CLASSES = {
+ java.util.ArrayList::new,
+ java.util.LinkedList::new,
+ java.util.Vector::new,
+ java.util.concurrent.CopyOnWriteArrayList::new,
+ ExtendsAbstractList::new
+ };
+
+ private static final Supplier<?>[] LIST_CME_CLASSES = {
+ java.util.ArrayList::new,
+ java.util.Vector::new
+ };
+
+ private static final Predicate<Integer> pEven = x -> 0 == x % 2;
+ private static final Predicate<Integer> pOdd = x -> 1 == x % 2;
+
+ private static final Comparator<Integer> BIT_COUNT_COMPARATOR =
+ (x, y) -> Integer.bitCount(x) - Integer.bitCount(y);
+
+ private static final Comparator<AtomicInteger> ATOMIC_INTEGER_COMPARATOR =
+ (x, y) -> x.intValue() - y.intValue();
+
+ private static final int SIZE = 100;
+ private static final int SUBLIST_FROM = 20;
+ private static final int SUBLIST_TO = SIZE - 5;
+ private static final int SUBLIST_SIZE = SUBLIST_TO - SUBLIST_FROM;
+
+ private static interface Callback {
+ void call(List<Integer> list);
+ }
+
+ // call the callback for each recursive subList
+ private void trimmedSubList(final List<Integer> list, final Callback callback) {
+ int size = list.size();
+ if (size > 1) {
+ // trim 1 element from both ends
+ final List<Integer> subList = list.subList(1, size - 1);
+ callback.call(subList);
+ trimmedSubList(subList, callback);
+ }
+ }
+
+ @DataProvider(name="listProvider", parallel=true)
+ public static Object[][] listCases() {
+ final List<Object[]> cases = new LinkedList<>();
+ cases.add(new Object[] { Collections.emptyList() });
+ cases.add(new Object[] { new ArrayList<>() });
+ cases.add(new Object[] { new LinkedList<>() });
+ cases.add(new Object[] { new Vector<>() });
+ cases.add(new Object[] { new Stack<>() });
+ cases.add(new Object[] { new CopyOnWriteArrayList<>() });
+
+ cases.add(new Object[] { new ArrayList(){{add(42);}} });
+ cases.add(new Object[] { new LinkedList(){{add(42);}} });
+ cases.add(new Object[] { new Vector(){{add(42);}} });
+ cases.add(new Object[] { new Stack(){{add(42);}} });
+ cases.add(new Object[] { new CopyOnWriteArrayList(){{add(42);}} });
+ return cases.toArray(new Object[0][cases.size()]);
+ }
+
+ @Test(dataProvider = "listProvider")
+ public void testProvidedWithNull(final List<Integer> list) throws Exception {
+ try {
+ list.forEach(null);
+ fail("expected NPE not thrown");
+ } catch (NullPointerException npe) {}
+ try {
+ list.replaceAll(null);
+ fail("expected NPE not thrown");
+ } catch (NullPointerException npe) {}
+ try {
+ list.removeIf(null);
+ fail("expected NPE not thrown");
+ } catch (NullPointerException npe) {}
+ try {
+ list.sort(null);
+ } catch (Throwable t) {
+ fail("Exception not expected: " + t);
+ }
+ }
+
+ @Test
+ public void testForEach() throws Exception {
+ final CollectionSupplier<List<Integer>> supplier = new CollectionSupplier((Supplier<List<Integer>>[])LIST_CLASSES, SIZE);
+ for (final CollectionSupplier.TestCase<List<Integer>> test : supplier.get()) {
+ final List<Integer> original = ((List<Integer>) test.expected);
+ final List<Integer> list = ((List<Integer>) test.collection);
+
+ try {
+ list.forEach(null);
+ fail("expected NPE not thrown");
+ } catch (NullPointerException npe) {}
+ CollectionAsserts.assertContents(list, original);
+
+ final List<Integer> actual = new LinkedList<>();
+ list.forEach(actual::add);
+ CollectionAsserts.assertContents(actual, list);
+ CollectionAsserts.assertContents(actual, original);
+
+ if (original.size() > SUBLIST_SIZE) {
+ final List<Integer> subList = original.subList(SUBLIST_FROM, SUBLIST_TO);
+ final List<Integer> actualSubList = new LinkedList<>();
+ subList.forEach(actualSubList::add);
+ assertEquals(actualSubList.size(), SUBLIST_SIZE);
+ for (int i = 0; i < SUBLIST_SIZE; i++) {
+ assertEquals(actualSubList.get(i), original.get(i + SUBLIST_FROM));
+ }
+ }
+
+ trimmedSubList(list, new Callback() {
+ @Override
+ public void call(final List<Integer> list) {
+ final List<Integer> actual = new LinkedList<>();
+ list.forEach(actual::add);
+ CollectionAsserts.assertContents(actual, list);
+ }
+ });
+ }
+ }
+
+ @Test
+ public void testRemoveIf() throws Exception {
+ final CollectionSupplier<List<Integer>> supplier = new CollectionSupplier((Supplier<List<Integer>>[])LIST_CLASSES, SIZE);
+ for (final CollectionSupplier.TestCase<List<Integer>> test : supplier.get()) {
+ final List<Integer> original = ((List<Integer>) test.expected);
+ final List<Integer> list = ((List<Integer>) test.collection);
+
+ try {
+ list.removeIf(null);
+ fail("expected NPE not thrown");
+ } catch (NullPointerException npe) {}
+ CollectionAsserts.assertContents(list, original);
+
+ final AtomicInteger offset = new AtomicInteger(1);
+ while (list.size() > 0) {
+ removeFirst(original, list, offset);
+ }
+ }
+
+ for (final CollectionSupplier.TestCase test : supplier.get()) {
+ final List<Integer> original = ((List<Integer>) test.expected);
+ final List<Integer> list = ((List<Integer>) test.collection);
+ list.removeIf(pOdd);
+ for (int i : list) {
+ assertTrue((i % 2) == 0);
+ }
+ for (int i : original) {
+ if (i % 2 == 0) {
+ assertTrue(list.contains(i));
+ }
+ }
+ list.removeIf(pEven);
+ assertTrue(list.isEmpty());
+ }
+
+ for (final CollectionSupplier.TestCase test : supplier.get()) {
+ final List<Integer> original = ((List<Integer>) test.expected);
+ final List<Integer> list = ((List<Integer>) test.collection);
+ final List<Integer> listCopy = new ArrayList<>(list);
+ if (original.size() > SUBLIST_SIZE) {
+ final List<Integer> subList = list.subList(SUBLIST_FROM, SUBLIST_TO);
+ final List<Integer> subListCopy = new ArrayList<>(subList);
+ listCopy.removeAll(subList);
+ subList.removeIf(pOdd);
+ for (int i : subList) {
+ assertTrue((i % 2) == 0);
+ }
+ for (int i : subListCopy) {
+ if (i % 2 == 0) {
+ assertTrue(subList.contains(i));
+ } else {
+ assertFalse(subList.contains(i));
+ }
+ }
+ subList.removeIf(pEven);
+ assertTrue(subList.isEmpty());
+ // elements outside the view should remain
+ CollectionAsserts.assertContents(list, listCopy);
+ }
+ }
+
+ for (final CollectionSupplier.TestCase test : supplier.get()) {
+ final List<Integer> list = ((List<Integer>) test.collection);
+ trimmedSubList(list, new Callback() {
+ @Override
+ public void call(final List<Integer> list) {
+ final List<Integer> copy = new ArrayList<>(list);
+ list.removeIf(pOdd);
+ for (int i : list) {
+ assertTrue((i % 2) == 0);
+ }
+ for (int i : copy) {
+ if (i % 2 == 0) {
+ assertTrue(list.contains(i));
+ } else {
+ assertFalse(list.contains(i));
+ }
+ }
+ }
+ });
+ }
+ }
+
+ // remove the first element
+ private void removeFirst(final List<Integer> original, final List<Integer> list, final AtomicInteger offset) {
+ final AtomicBoolean first = new AtomicBoolean(true);
+ list.removeIf(x -> first.getAndSet(false));
+ CollectionAsserts.assertContents(original.subList(offset.getAndIncrement(), original.size()), list);
+ }
+
+ @Test
+ public void testReplaceAll() throws Exception {
+ final int scale = 3;
+ final CollectionSupplier<List<Integer>> supplier = new CollectionSupplier((Supplier<List<Integer>>[])LIST_CLASSES, SIZE);
+ for (final CollectionSupplier.TestCase<List<Integer>> test : supplier.get()) {
+ final List<Integer> original = ((List<Integer>) test.expected);
+ final List<Integer> list = ((List<Integer>) test.collection);
+
+ try {
+ list.replaceAll(null);
+ fail("expected NPE not thrown");
+ } catch (NullPointerException npe) {}
+ CollectionAsserts.assertContents(list, original);
+
+ list.replaceAll(x -> scale * x);
+ for (int i=0; i < original.size(); i++) {
+ assertTrue(list.get(i) == (scale * original.get(i)), "mismatch at index " + i);
+ }
+
+ if (original.size() > SUBLIST_SIZE) {
+ final List<Integer> subList = list.subList(SUBLIST_FROM, SUBLIST_TO);
+ subList.replaceAll(x -> x + 1);
+ // verify elements in view [from, to) were replaced
+ for (int i = 0; i < SUBLIST_SIZE; i++) {
+ assertTrue(subList.get(i) == ((scale * original.get(i + SUBLIST_FROM)) + 1),
+ "mismatch at sublist index " + i);
+ }
+ // verify that elements [0, from) remain unmodified
+ for (int i = 0; i < SUBLIST_FROM; i++) {
+ assertTrue(list.get(i) == (scale * original.get(i)),
+ "mismatch at original index " + i);
+ }
+ // verify that elements [to, size) remain unmodified
+ for (int i = SUBLIST_TO; i < list.size(); i++) {
+ assertTrue(list.get(i) == (scale * original.get(i)),
+ "mismatch at original index " + i);
+ }
+ }
+ }
+
+ for (final CollectionSupplier.TestCase test : supplier.get()) {
+ final List<Integer> list = ((List<Integer>) test.collection);
+ trimmedSubList(list, new Callback() {
+ @Override
+ public void call(final List<Integer> list) {
+ final List<Integer> copy = new ArrayList<>(list);
+ final int offset = 5;
+ list.replaceAll(x -> offset + x);
+ for (int i=0; i < copy.size(); i++) {
+ assertTrue(list.get(i) == (offset + copy.get(i)), "mismatch at index " + i);
+ }
+ }
+ });
+ }
+ }
+
+ @Test
+ public void testSort() throws Exception {
+ final CollectionSupplier<List<Integer>> supplier = new CollectionSupplier((Supplier<List<Integer>>[])LIST_CLASSES, SIZE);
+ for (final CollectionSupplier.TestCase<List<Integer>> test : supplier.get()) {
+ final List<Integer> original = ((List<Integer>) test.expected);
+ final List<Integer> list = ((List<Integer>) test.collection);
+ CollectionSupplier.shuffle(list);
+ list.sort(Integer::compare);
+ CollectionAsserts.assertSorted(list, Integer::compare);
+ if (test.name.startsWith("reverse")) {
+ Collections.reverse(list);
+ }
+ CollectionAsserts.assertContents(list, original);
+
+ CollectionSupplier.shuffle(list);
+ list.sort(null);
+ CollectionAsserts.assertSorted(list, Comparator.<Integer>naturalOrder());
+ if (test.name.startsWith("reverse")) {
+ Collections.reverse(list);
+ }
+ CollectionAsserts.assertContents(list, original);
+
+ CollectionSupplier.shuffle(list);
+ list.sort(Comparator.<Integer>naturalOrder());
+ CollectionAsserts.assertSorted(list, Comparator.<Integer>naturalOrder());
+ if (test.name.startsWith("reverse")) {
+ Collections.reverse(list);
+ }
+ CollectionAsserts.assertContents(list, original);
+
+ CollectionSupplier.shuffle(list);
+ list.sort(Comparator.<Integer>reverseOrder());
+ CollectionAsserts.assertSorted(list, Comparator.<Integer>reverseOrder());
+ if (!test.name.startsWith("reverse")) {
+ Collections.reverse(list);
+ }
+ CollectionAsserts.assertContents(list, original);
+
+ CollectionSupplier.shuffle(list);
+ list.sort(BIT_COUNT_COMPARATOR);
+ CollectionAsserts.assertSorted(list, BIT_COUNT_COMPARATOR);
+ // check sort by verifying that bitCount increases and never drops
+ int minBitCount = 0;
+ int bitCount = 0;
+ for (final Integer i : list) {
+ bitCount = Integer.bitCount(i);
+ assertTrue(bitCount >= minBitCount);
+ minBitCount = bitCount;
+ }
+
+ @SuppressWarnings("unchecked")
+ final Constructor<? extends List<?>> defaultConstructor = ((Class<? extends List<?>>)test.collection.getClass()).getConstructor();
+ final List<AtomicInteger> incomparables = (List<AtomicInteger>) defaultConstructor.newInstance();
+
+ for (int i=0; i < test.expected.size(); i++) {
+ incomparables.add(new AtomicInteger(i));
+ }
+ CollectionSupplier.shuffle(incomparables);
+ incomparables.sort(ATOMIC_INTEGER_COMPARATOR);
+ for (int i=0; i < test.expected.size(); i++) {
+ assertEquals(i, incomparables.get(i).intValue());
+ }
+
+ if (original.size() > SUBLIST_SIZE) {
+ final List<Integer> copy = new ArrayList<>(list);
+ final List<Integer> subList = list.subList(SUBLIST_FROM, SUBLIST_TO);
+ CollectionSupplier.shuffle(subList);
+ subList.sort(Comparator.<Integer>naturalOrder());
+ CollectionAsserts.assertSorted(subList, Comparator.<Integer>naturalOrder());
+ // verify that elements [0, from) remain unmodified
+ for (int i = 0; i < SUBLIST_FROM; i++) {
+ assertTrue(list.get(i) == copy.get(i),
+ "mismatch at index " + i);
+ }
+ // verify that elements [to, size) remain unmodified
+ for (int i = SUBLIST_TO; i < list.size(); i++) {
+ assertTrue(list.get(i) == copy.get(i),
+ "mismatch at index " + i);
+ }
+ }
+ }
+
+ for (final CollectionSupplier.TestCase test : supplier.get()) {
+ final List<Integer> list = ((List<Integer>) test.collection);
+ trimmedSubList(list, new Callback() {
+ @Override
+ public void call(final List<Integer> list) {
+ final List<Integer> copy = new ArrayList<>(list);
+ CollectionSupplier.shuffle(list);
+ list.sort(Comparator.<Integer>naturalOrder());
+ CollectionAsserts.assertSorted(list, Comparator.<Integer>naturalOrder());
+ }
+ });
+ }
+ }
+
+ @Test
+ public void testForEachThrowsCME() throws Exception {
+ final CollectionSupplier<List<Integer>> supplier = new CollectionSupplier((Supplier<List<Integer>>[])LIST_CME_CLASSES, SIZE);
+ for (final CollectionSupplier.TestCase<List<Integer>> test : supplier.get()) {
+ final List<Integer> list = ((List<Integer>) test.collection);
+
+ if (list.size() <= 1) {
+ continue;
+ }
+ boolean gotException = false;
+ try {
+ // bad predicate that modifies its list, should throw CME
+ list.forEach((x) -> {list.add(x);});
+ } catch (ConcurrentModificationException cme) {
+ gotException = true;
+ }
+ if (!gotException) {
+ fail("expected CME was not thrown from " + test);
+ }
+ }
+ }
+
+ @Test
+ public void testRemoveIfThrowsCME() throws Exception {
+ final CollectionSupplier<List<Integer>> supplier = new CollectionSupplier((Supplier<List<Integer>>[])LIST_CME_CLASSES, SIZE);
+ for (final CollectionSupplier.TestCase<List<Integer>> test : supplier.get()) {
+ final List<Integer> original = ((List<Integer>) test.expected);
+ final List<Integer> list = ((List<Integer>) test.collection);
+
+ if (list.size() <= 1) {
+ continue;
+ }
+ boolean gotException = false;
+ try {
+ // bad predicate that modifies its list, should throw CME
+ list.removeIf((x) -> {return list.add(x);});
+ } catch (ConcurrentModificationException cme) {
+ gotException = true;
+ }
+ if (!gotException) {
+ fail("expected CME was not thrown from " + test);
+ }
+ }
+ }
+
+ @Test
+ public void testReplaceAllThrowsCME() throws Exception {
+ final CollectionSupplier<List<Integer>> supplier = new CollectionSupplier((Supplier<List<Integer>>[])LIST_CME_CLASSES, SIZE);
+ for (final CollectionSupplier.TestCase<List<Integer>> test : supplier.get()) {
+ final List<Integer> list = ((List<Integer>) test.collection);
+
+ if (list.size() <= 1) {
+ continue;
+ }
+ boolean gotException = false;
+ try {
+ // bad predicate that modifies its list, should throw CME
+ list.replaceAll(x -> {int n = 3 * x; list.add(n); return n;});
+ } catch (ConcurrentModificationException cme) {
+ gotException = true;
+ }
+ if (!gotException) {
+ fail("expected CME was not thrown from " + test);
+ }
+ }
+ }
+
+ @Test
+ public void testSortThrowsCME() throws Exception {
+ final CollectionSupplier<List<Integer>> supplier = new CollectionSupplier((Supplier<List<Integer>>[])LIST_CME_CLASSES, SIZE);
+ for (final CollectionSupplier.TestCase<List<Integer>> test : supplier.get()) {
+ final List<Integer> list = ((List<Integer>) test.collection);
+
+ if (list.size() <= 1) {
+ continue;
+ }
+ boolean gotException = false;
+ try {
+ // bad predicate that modifies its list, should throw CME
+ list.sort((x, y) -> {list.add(x); return x - y;});
+ } catch (ConcurrentModificationException cme) {
+ gotException = true;
+ }
+ if (!gotException) {
+ fail("expected CME was not thrown from " + test);
+ }
+ }
+ }
+
+ private static final List<Integer> SLICED_EXPECTED = Arrays.asList(0, 1, 2, 3, 5, 6, 7, 8, 9);
+ private static final List<Integer> SLICED_EXPECTED2 = Arrays.asList(0, 1, 2, 5, 6, 7, 8, 9);
+
+ @DataProvider(name="shortIntListProvider", parallel=true)
+ public static Object[][] intListCases() {
+ final Integer[] DATA = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ final List<Object[]> cases = new LinkedList<>();
+ cases.add(new Object[] { new ArrayList<>(Arrays.asList(DATA)) });
+ cases.add(new Object[] { new LinkedList<>(Arrays.asList(DATA)) });
+ cases.add(new Object[] { new Vector<>(Arrays.asList(DATA)) });
+ cases.add(new Object[] { new CopyOnWriteArrayList<>(Arrays.asList(DATA)) });
+ cases.add(new Object[] { new ExtendsAbstractList<>(Arrays.asList(DATA)) });
+ return cases.toArray(new Object[0][cases.size()]);
+ }
+
+ @Test(dataProvider = "shortIntListProvider")
+ public void testRemoveIfFromSlice(final List<Integer> list) throws Exception {
+ final List<Integer> sublist = list.subList(3, 6);
+ assertTrue(sublist.removeIf(x -> x == 4));
+ CollectionAsserts.assertContents(list, SLICED_EXPECTED);
+
+ final List<Integer> sublist2 = list.subList(2, 5);
+ assertTrue(sublist2.removeIf(x -> x == 3));
+ CollectionAsserts.assertContents(list, SLICED_EXPECTED2);
+ }
+}
--- a/jdk/test/java/util/Map/Defaults.java Fri Sep 13 12:20:53 2013 +0100
+++ b/jdk/test/java/util/Map/Defaults.java Fri Sep 13 11:18:44 2013 -0700
@@ -155,7 +155,7 @@
assertThrows(
() -> { map.replaceAll((k,v) -> null); },
NullPointerException.class,
- description);
+ description + " should not allow replacement with null value");
}
@Test(dataProvider = "Map<IntegerEnum,String> rw=true keys=withNull values=withNull")
@@ -194,6 +194,15 @@
assertSame(map.get(null), EXTRA_VALUE);
}
+ @Test(dataProvider = "Map<IntegerEnum,String> rw=true keys=nonNull values=nonNull")
+ public void testReplaceKVNoNulls(String description, Map<IntegerEnum, String> map) {
+ assertTrue(map.containsKey(FIRST_KEY), "expected key missing");
+ assertSame(map.get(FIRST_KEY), FIRST_VALUE, "found wrong value");
+ assertThrows( () -> {map.replace(FIRST_KEY, null);}, NullPointerException.class, description + ": should throw NPE");
+ assertSame(map.replace(FIRST_KEY, EXTRA_VALUE), FIRST_VALUE, description + ": replaced wrong value");
+ assertSame(map.get(FIRST_KEY), EXTRA_VALUE, "found wrong value");
+ }
+
@Test(dataProvider = "Map<IntegerEnum,String> rw=true keys=all values=all")
public void testReplaceKV(String description, Map<IntegerEnum, String> map) {
assertTrue(map.containsKey(KEYS[1]));
@@ -224,6 +233,16 @@
assertSame(map.get(null), EXTRA_VALUE);
}
+ @Test(dataProvider = "Map<IntegerEnum,String> rw=true keys=nonNull values=nonNull")
+ public void testReplaceKVVNoNulls(String description, Map<IntegerEnum, String> map) {
+ assertTrue(map.containsKey(FIRST_KEY), "expected key missing");
+ assertSame(map.get(FIRST_KEY), FIRST_VALUE, "found wrong value");
+ assertThrows( () -> {map.replace(FIRST_KEY, FIRST_VALUE, null);}, NullPointerException.class, description + ": should throw NPE");
+ assertThrows( () -> {if (!map.replace(FIRST_KEY, null, EXTRA_VALUE)) throw new NullPointerException("default returns false rather than throwing");}, NullPointerException.class, description + ": should throw NPE");
+ assertTrue(map.replace(FIRST_KEY, FIRST_VALUE, EXTRA_VALUE), description + ": replaced wrong value");
+ assertSame(map.get(FIRST_KEY), EXTRA_VALUE, "found wrong value");
+ }
+
@Test(dataProvider = "Map<IntegerEnum,String> rw=true keys=all values=all")
public void testReplaceKVV(String description, Map<IntegerEnum, String> map) {
assertTrue(map.containsKey(KEYS[1]));
@@ -470,6 +489,9 @@
VALUES[each] = String.valueOf(each);
}
}
+
+ private static final IntegerEnum FIRST_KEY = KEYS[0];
+ private static final String FIRST_VALUE = VALUES[0];
private static final IntegerEnum EXTRA_KEY = IntegerEnum.EXTRA_KEY;
private static final String EXTRA_VALUE = String.valueOf(TEST_SIZE);
@@ -583,6 +605,8 @@
return Arrays.asList(
// null key hostile
new Object[]{"EnumMap", makeMap(() -> new EnumMap(IntegerEnum.class), false, nulls)},
+ new Object[]{"TreeMap", makeMap(TreeMap::new, false, nulls)},
+ new Object[]{"ExtendsAbstractMap(TreeMap)", makeMap(() -> {return new ExtendsAbstractMap(new TreeMap());}, false, nulls)},
new Object[]{"Collections.synchronizedMap(EnumMap)", Collections.synchronizedMap(makeMap(() -> new EnumMap(IntegerEnum.class), false, nulls))}
);
}
@@ -591,10 +615,11 @@
return Arrays.asList(
// null key and value hostile
new Object[]{"Hashtable", makeMap(Hashtable::new, false, false)},
- new Object[]{"TreeMap", makeMap(TreeMap::new, false, false)},
new Object[]{"ConcurrentHashMap", makeMap(ConcurrentHashMap::new, false, false)},
new Object[]{"ConcurrentSkipListMap", makeMap(ConcurrentSkipListMap::new, false, false)},
+ new Object[]{"Collections.synchronizedMap(ConcurrentHashMap)", Collections.synchronizedMap(makeMap(ConcurrentHashMap::new, false, false))},
new Object[]{"Collections.checkedMap(ConcurrentHashMap)", Collections.checkedMap(makeMap(ConcurrentHashMap::new, false, false), IntegerEnum.class, String.class)},
+ new Object[]{"ExtendsAbstractMap(ConcurrentHashMap)", makeMap(() -> {return new ExtendsAbstractMap(new ConcurrentHashMap());}, false, false)},
new Object[]{"ImplementsConcurrentMap", makeMap(ImplementsConcurrentMap::new, false, false)}
);
}
@@ -641,18 +666,17 @@
}
public static <T extends Throwable> void assertThrows(Thrower<T> thrower, Class<T> throwable, String message) {
- Throwable result;
+ Throwable thrown;
try {
thrower.run();
- result = null;
+ thrown = null;
} catch (Throwable caught) {
- result = caught;
+ thrown = caught;
}
- assertInstance(result, throwable,
- (null != message)
- ? message
- : "Failed to throw " + throwable.getCanonicalName());
+ assertInstance(thrown, throwable,
+ ((null != message) ? message : "") +
+ " Failed to throw " + throwable.getCanonicalName());
}
public static <T extends Throwable> void assertThrows(Class<T> throwable, String message, Thrower<T>... throwers) {
@@ -661,11 +685,11 @@
}
}
- public static <T> void assertInstance(T actual, Class<? extends T> expected) {
+ public static void assertInstance(Object actual, Class<?> expected) {
assertInstance(expected.isInstance(actual), null);
}
- public static <T> void assertInstance(T actual, Class<? extends T> expected, String message) {
+ public static void assertInstance(Object actual, Class<?> expected, String message) {
assertTrue(expected.isInstance(actual), message);
}