8021591: Additional explicit null checks
Reviewed-by: psandoz, alanb
This commit is contained in:
parent
767ab8c9ae
commit
b59dc6762e
jdk
src/share/classes
java/util
javax/security/auth
test/java/util
@ -3900,6 +3900,7 @@ public class Collections {
|
||||
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()) {
|
||||
|
@ -957,6 +957,8 @@ public class Hashtable<K,V>
|
||||
|
||||
@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 @@ public class Hashtable<K,V>
|
||||
|
||||
@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;
|
||||
|
@ -997,6 +997,7 @@ public class IdentityHashMap<K,V>
|
||||
* 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 @@ public class IdentityHashMap<K,V>
|
||||
* 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())) {
|
||||
|
@ -805,6 +805,10 @@ public interface Map<K,V> {
|
||||
* 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 @@ public interface Map<K,V> {
|
||||
* (<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
|
||||
|
@ -1012,7 +1012,7 @@ public class TreeMap<K,V>
|
||||
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();
|
||||
|
@ -49,6 +49,7 @@ import java.util.Hashtable;
|
||||
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 class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
|
||||
}
|
||||
|
||||
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 class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
|
||||
}
|
||||
|
||||
public final boolean retainAll(Collection<?> c) {
|
||||
Objects.requireNonNull(c);
|
||||
boolean modified = false;
|
||||
for (Iterator<E> it = iterator(); it.hasNext();) {
|
||||
if (!c.contains(it.next())) {
|
||||
|
@ -1186,7 +1186,7 @@ public final class Subject implements java.io.Serializable {
|
||||
}
|
||||
|
||||
public boolean removeAll(Collection<?> c) {
|
||||
|
||||
Objects.requireNonNull(c);
|
||||
boolean modified = false;
|
||||
final Iterator<E> e = iterator();
|
||||
while (e.hasNext()) {
|
||||
@ -1222,7 +1222,7 @@ public final class Subject implements java.io.Serializable {
|
||||
}
|
||||
|
||||
public boolean retainAll(Collection<?> c) {
|
||||
|
||||
Objects.requireNonNull(c);
|
||||
boolean modified = false;
|
||||
boolean retain = false;
|
||||
final Iterator<E> e = iterator();
|
||||
|
@ -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 static org.testng.Assert.fail;
|
||||
|
||||
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
|
||||
* @library testlibrary
|
||||
* @build CollectionAsserts CollectionSupplier
|
||||
* @run testng CollectionDefaults
|
||||
* @summary Unit tests for extension methods on Collection
|
||||
* @library testlibrary
|
||||
* @build CollectionAsserts CollectionSupplier ExtendsAbstractSet ExtendsAbstractCollection
|
||||
* @run testng CollectionDefaults
|
||||
*/
|
||||
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 @@ public class CollectionDefaults {
|
||||
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);
|
||||
|
@ -400,8 +400,6 @@ public class MOAT {
|
||||
// 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));
|
||||
|
@ -41,6 +41,10 @@ import static org.testng.Assert.fail;
|
||||
*/
|
||||
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 class CollectionAsserts {
|
||||
}
|
||||
|
||||
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 @@ public class CollectionAsserts {
|
||||
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 @@ public class CollectionAsserts {
|
||||
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);
|
||||
}
|
||||
|
||||
Set<T> sb = new HashSet<>();
|
||||
for (T t : b) {
|
||||
sb.add(t);
|
||||
}
|
||||
|
||||
return Objects.equals(sa, sb);
|
||||
public static<T extends Comparable<? super T>> void assertContentsUnordered(Iterable<T> actual, Iterable<T> expected) {
|
||||
assertContentsUnordered(actual, expected, null);
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
for (T t : actual) {
|
||||
assertTrue(allExpected.remove(t), msg + " element '" + String.valueOf(t) + "' not found");
|
||||
}
|
||||
|
||||
assertTrue(allExpected.isEmpty(), msg + "expected contained additional elements");
|
||||
}
|
||||
|
||||
static <T> void assertSplitContents(Iterable<Iterable<T>> splits, Iterable<T> list) {
|
||||
|
@ -29,13 +29,11 @@ import java.util.Arrays;
|
||||
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,73 +42,61 @@ import java.util.function.Supplier;
|
||||
* @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.
|
||||
*/
|
||||
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 @@ public final class CollectionSupplier implements Supplier<Iterable<CollectionSup
|
||||
* @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> 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 = 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 = 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 = 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> regular = type.get();
|
||||
for (int i = 0; i < size; i++) {
|
||||
regular.add(i);
|
||||
}
|
||||
fibonacci.add(n);
|
||||
prev2 = prev1;
|
||||
prev1 = n;
|
||||
}
|
||||
collections.add(new TestCase("fibonacci",
|
||||
className,
|
||||
copyConstructor.newInstance(fibonacci),
|
||||
fibonacci));
|
||||
cases.add(new TestCase("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> odds = type.get();
|
||||
for (int i = 0; i < size; i++) {
|
||||
odds.add((i * 2) + 1);
|
||||
}
|
||||
cases.add(new TestCase("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> 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;
|
||||
}
|
||||
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 = type.get();
|
||||
singleWithSlack.add(42);
|
||||
singleWithSlack.add(43);
|
||||
assertTrue(singleWithSlack.remove(43));
|
||||
cases.add(new TestCase("singleWithSlack", singleWithSlack));
|
||||
|
||||
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> 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> 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> 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> evensWithSlack = defaultConstructor.newInstance();
|
||||
for (int i = 0; i < 2 * size; i++) {
|
||||
evensWithSlack.add(i * 2);
|
||||
}
|
||||
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;
|
||||
final Collection<Integer> regularWithSlack = type.get();
|
||||
for (int i = 0; i < (2 * size); i++) {
|
||||
regularWithSlack.add(i);
|
||||
}
|
||||
fibonacciWithSlack.add(n);
|
||||
prev2 = prev1;
|
||||
prev1 = n;
|
||||
}
|
||||
assertTrue(fibonacciWithSlack.removeIf((x) -> {return x < 20;}));
|
||||
collections.add(new TestCase("fibonacciWithSlack",
|
||||
className,
|
||||
copyConstructor.newInstance(fibonacciWithSlack),
|
||||
fibonacciWithSlack));
|
||||
assertTrue(regularWithSlack.removeIf((x) -> {
|
||||
return x >= size;
|
||||
}));
|
||||
cases.add(new TestCase("regularWithSlack", regularWithSlack));
|
||||
|
||||
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 = 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> 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);
|
||||
}
|
||||
}
|
||||
|
||||
return collections;
|
||||
return cases;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -28,8 +28,6 @@ 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;
|
||||
@ -46,28 +44,30 @@ 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
|
||||
* @bug 8023367
|
||||
* @library testlibrary
|
||||
* @build CollectionAsserts CollectionSupplier
|
||||
* @run testng ListDefaults
|
||||
* @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 String[] LIST_CLASSES = {
|
||||
"java.util.ArrayList",
|
||||
"java.util.LinkedList",
|
||||
"java.util.Vector",
|
||||
"java.util.concurrent.CopyOnWriteArrayList"
|
||||
};
|
||||
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 String[] LIST_CME_CLASSES = {
|
||||
"java.util.ArrayList",
|
||||
"java.util.Vector"
|
||||
};
|
||||
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;
|
||||
@ -139,13 +139,9 @@ public class ListDefaults {
|
||||
|
||||
@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 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 {
|
||||
@ -182,10 +178,9 @@ public class ListDefaults {
|
||||
|
||||
@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 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 {
|
||||
@ -201,7 +196,7 @@ public class ListDefaults {
|
||||
}
|
||||
|
||||
for (final CollectionSupplier.TestCase test : supplier.get()) {
|
||||
final List<Integer> original = ((List<Integer>) test.original);
|
||||
final List<Integer> original = ((List<Integer>) test.expected);
|
||||
final List<Integer> list = ((List<Integer>) test.collection);
|
||||
list.removeIf(pOdd);
|
||||
for (int i : list) {
|
||||
@ -217,7 +212,7 @@ public class ListDefaults {
|
||||
}
|
||||
|
||||
for (final CollectionSupplier.TestCase test : supplier.get()) {
|
||||
final List<Integer> original = ((List<Integer>) test.original);
|
||||
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) {
|
||||
@ -274,9 +269,9 @@ public class ListDefaults {
|
||||
@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 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 {
|
||||
@ -329,9 +324,9 @@ public class ListDefaults {
|
||||
|
||||
@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 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);
|
||||
@ -378,17 +373,15 @@ public class ListDefaults {
|
||||
}
|
||||
|
||||
@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 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.original.size(); i++) {
|
||||
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.original.size(); i++) {
|
||||
for (int i=0; i < test.expected.size(); i++) {
|
||||
assertEquals(i, incomparables.get(i).intValue());
|
||||
}
|
||||
|
||||
@ -427,9 +420,10 @@ public class ListDefaults {
|
||||
|
||||
@Test
|
||||
public void testForEachThrowsCME() throws Exception {
|
||||
final CollectionSupplier supplier = new CollectionSupplier(LIST_CME_CLASSES, SIZE);
|
||||
for (final CollectionSupplier.TestCase test : supplier.get()) {
|
||||
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;
|
||||
}
|
||||
@ -448,9 +442,11 @@ public class ListDefaults {
|
||||
|
||||
@Test
|
||||
public void testRemoveIfThrowsCME() throws Exception {
|
||||
final CollectionSupplier supplier = new CollectionSupplier(LIST_CME_CLASSES, SIZE);
|
||||
for (final CollectionSupplier.TestCase test : supplier.get()) {
|
||||
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;
|
||||
}
|
||||
@ -469,9 +465,10 @@ public class ListDefaults {
|
||||
|
||||
@Test
|
||||
public void testReplaceAllThrowsCME() throws Exception {
|
||||
final CollectionSupplier supplier = new CollectionSupplier(LIST_CME_CLASSES, SIZE);
|
||||
for (final CollectionSupplier.TestCase test : supplier.get()) {
|
||||
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;
|
||||
}
|
||||
@ -490,9 +487,10 @@ public class ListDefaults {
|
||||
|
||||
@Test
|
||||
public void testSortThrowsCME() throws Exception {
|
||||
final CollectionSupplier supplier = new CollectionSupplier(LIST_CME_CLASSES, SIZE);
|
||||
for (final CollectionSupplier.TestCase test : supplier.get()) {
|
||||
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;
|
||||
}
|
||||
@ -520,6 +518,7 @@ public class ListDefaults {
|
||||
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()]);
|
||||
}
|
||||
|
@ -155,7 +155,7 @@ public class Defaults {
|
||||
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 @@ public class Defaults {
|
||||
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 @@ public class Defaults {
|
||||
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 @@ public class Defaults {
|
||||
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 @@ public class Defaults {
|
||||
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 @@ public class Defaults {
|
||||
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 class Defaults {
|
||||
}
|
||||
|
||||
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 class Defaults {
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user