undefect. CWE-407 — 63 sites patched across 27 ecosystems

Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com

Patches, unit tests, benchmarks, whitepaper, and outreach briefs.
Public domain — no copyright claimed. Use freely.
This commit is contained in:
russell@unturf.com 2026-03-26 17:11:57 -04:00
commit 0a580b313d
70422 changed files with 17213626 additions and 0 deletions

View file

@ -0,0 +1,149 @@
/*
* Copyright (c) 2021, 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 org.testng.annotations.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.PrimitiveIterator;
import java.util.Spliterators;
import java.util.function.DoubleConsumer;
import java.util.function.IntConsumer;
import java.util.function.LongConsumer;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertThrows;
import static org.testng.Assert.fail;
/**
* @test
* @summary Spliterator.iterator traversing tests
* @library /lib/testlibrary/bootlib
* @run testng IteratorFromSpliteratorTest
* @bug 8267452
*/
public class IteratorFromSpliteratorTest {
@Test
public void testIteratorFromSpliterator() {
List<Integer> input = List.of(1, 2, 3, 4, 5);
for (int i = 0; i < input.size(); i++) {
Iterator<Integer> iterator = Spliterators.iterator(input.spliterator());
List<Integer> result = new ArrayList<>();
int j = i;
while (j++ < input.size() && iterator.hasNext()) {
result.add(iterator.next());
}
// While SpliteratorTraversingAndSplittingTest tests some scenarios with Spliterators.iterator
// it always wraps the resulting iterator into spliterator again, and this limits the use patterns.
// In particular, calling hasNext() right before forEachRemaining() is not tested.
// Here we cover such a scenario.
assertEquals(iterator.hasNext(), result.size() < input.size());
iterator.forEachRemaining(result::add);
iterator.forEachRemaining(x -> fail("Should not be called"));
assertFalse(iterator.hasNext());
assertThrows(NoSuchElementException.class, iterator::next);
iterator.forEachRemaining(x -> fail("Should not be called"));
assertEquals(result, input);
}
}
@Test
public void testIteratorFromSpliteratorInt() {
int[] input = {1, 2, 3, 4, 5};
for (int i = 0; i < input.length; i++) {
PrimitiveIterator.OfInt iterator = Spliterators.iterator(Arrays.spliterator(input));
List<Integer> result = new ArrayList<>();
int j = i;
while (j++ < input.length && iterator.hasNext()) {
result.add(iterator.nextInt());
}
assertEquals(iterator.hasNext(), result.size() < input.length);
iterator.forEachRemaining((IntConsumer) result::add);
iterator.forEachRemaining((IntConsumer) (x -> fail("Should not be called")));
assertFalse(iterator.hasNext());
assertThrows(NoSuchElementException.class, iterator::next);
iterator.forEachRemaining((IntConsumer) (x -> fail("Should not be called")));
assertEquals(result.stream().mapToInt(x -> x).toArray(), input);
}
}
@Test
public void testIteratorFromSpliteratorLong() {
long[] input = {1, 2, 3, 4, 5};
for (int i = 0; i < input.length; i++) {
PrimitiveIterator.OfLong iterator = Spliterators.iterator(Arrays.spliterator(input));
List<Long> result = new ArrayList<>();
int j = i;
while (j++ < input.length && iterator.hasNext()) {
result.add(iterator.nextLong());
}
assertEquals(iterator.hasNext(), result.size() < input.length);
iterator.forEachRemaining((LongConsumer) result::add);
iterator.forEachRemaining((LongConsumer) (x -> fail("Should not be called")));
assertFalse(iterator.hasNext());
assertThrows(NoSuchElementException.class, iterator::next);
iterator.forEachRemaining((LongConsumer) (x -> fail("Should not be called")));
assertEquals(result.stream().mapToLong(x -> x).toArray(), input);
}
}
@Test
public void testIteratorFromSpliteratorDouble() {
double[] input = {1, 2, 3, 4, 5};
for (int i = 0; i < input.length; i++) {
PrimitiveIterator.OfDouble iterator = Spliterators.iterator(Arrays.spliterator(input));
List<Double> result = new ArrayList<>();
int j = i;
while (j++ < input.length && iterator.hasNext()) {
result.add(iterator.nextDouble());
}
assertEquals(iterator.hasNext(), result.size() < input.length);
iterator.forEachRemaining((DoubleConsumer) result::add);
iterator.forEachRemaining((DoubleConsumer) (x -> fail("Should not be called")));
assertFalse(iterator.hasNext());
assertThrows(NoSuchElementException.class, iterator::next);
iterator.forEachRemaining((DoubleConsumer) (x -> fail("Should not be called")));
assertEquals(result.stream().mapToDouble(x -> x).toArray(), input);
}
}
@Test
public void testIteratorFromSpliteratorEmpty() {
Iterator<?>[] iterators = {
Spliterators.iterator(Spliterators.emptySpliterator()),
Spliterators.iterator(Spliterators.emptyIntSpliterator()),
Spliterators.iterator(Spliterators.emptyLongSpliterator()),
Spliterators.iterator(Spliterators.emptyDoubleSpliterator())
};
for (Iterator<?> iterator : iterators) {
iterator.forEachRemaining(x -> fail("Should not be called"));
assertFalse(iterator.hasNext());
iterator.forEachRemaining(x -> fail("Should not be called"));
assertThrows(NoSuchElementException.class, iterator::next);
}
}
}

View file

@ -0,0 +1,425 @@
/*
* Copyright (c) 2013, 2015, 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.
*/
/**
* @test
* @bug 8020156 8020009 8022326 8012913 8024405 8024408 8071477
* @run testng SpliteratorCharacteristics
*/
import org.testng.annotations.Test;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.PrimitiveIterator;
import java.util.Set;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.ConcurrentSkipListSet;
import java.util.function.Supplier;
import java.util.stream.DoubleStream;
import java.util.stream.IntStream;
import java.util.stream.LongStream;
import static org.testng.Assert.*;
@Test
public class SpliteratorCharacteristics {
public void testSpliteratorFromCharSequence() {
class CharSequenceImpl implements CharSequence {
final String s;
public CharSequenceImpl(String s) {
this.s = s;
}
@Override
public int length() {
return s.length();
}
@Override
public char charAt(int index) {
return s.charAt(index);
}
@Override
public CharSequence subSequence(int start, int end) {
return s.subSequence(start, end);
}
@Override
public String toString() {
return s;
}
}
CharSequence cs = "A";
Spliterator.OfInt s = cs.chars().spliterator();
assertCharacteristics(s, Spliterator.IMMUTABLE | Spliterator.ORDERED |
Spliterator.SIZED | Spliterator.SUBSIZED);
assertHasNotCharacteristics(s, Spliterator.CONCURRENT);
s = cs.codePoints().spliterator();
assertCharacteristics(s, Spliterator.IMMUTABLE | Spliterator.ORDERED);
assertHasNotCharacteristics(s, Spliterator.CONCURRENT);
for (CharSequence c : Arrays.asList(new CharSequenceImpl("A"),
new StringBuilder("A"),
new StringBuffer("A"))) {
s = cs.chars().spliterator();
assertCharacteristics(s, Spliterator.ORDERED |
Spliterator.SIZED | Spliterator.SUBSIZED);
assertHasNotCharacteristics(s, Spliterator.CONCURRENT);
s = cs.codePoints().spliterator();
assertCharacteristics(s, Spliterator.ORDERED);
assertHasNotCharacteristics(s, Spliterator.CONCURRENT);
}
}
public void testSpliteratorFromCollection() {
List<Integer> l = Arrays.asList(1, 2, 3, 4);
{
Spliterator<?> s = Spliterators.spliterator(l, 0);
assertCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
assertHasNotCharacteristics(s, Spliterator.CONCURRENT);
}
{
Spliterator<?> s = Spliterators.spliterator(l, Spliterator.CONCURRENT);
assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
assertCharacteristics(s, Spliterator.CONCURRENT);
}
{
Spliterator<?> s = Spliterators.spliterator(l.iterator(), 1, 0);
assertCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
assertHasNotCharacteristics(s, Spliterator.CONCURRENT);
}
{
Spliterator<?> s = Spliterators.spliterator(l.iterator(), 1, Spliterator.CONCURRENT);
assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
assertCharacteristics(s, Spliterator.CONCURRENT);
}
{
Spliterator<?> s = Spliterators.spliteratorUnknownSize(l.iterator(), 0);
assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
}
{
Spliterator<?> s = Spliterators.spliteratorUnknownSize(
l.iterator(), Spliterator.SIZED | Spliterator.SUBSIZED);
assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
}
}
public void testSpliteratorOfIntFromIterator() {
Supplier<PrimitiveIterator.OfInt> si = () -> IntStream.of(1, 2, 3, 4).iterator();
{
Spliterator<?> s = Spliterators.spliterator(si.get(), 1, 0);
assertCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
assertHasNotCharacteristics(s, Spliterator.CONCURRENT);
}
{
Spliterator<?> s = Spliterators.spliterator(si.get(), 1, Spliterator.CONCURRENT);
assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
assertCharacteristics(s, Spliterator.CONCURRENT);
}
{
Spliterator<?> s = Spliterators.spliteratorUnknownSize(si.get(), 0);
assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
}
{
Spliterator<?> s = Spliterators.spliteratorUnknownSize(
si.get(), Spliterator.SIZED | Spliterator.SUBSIZED);
assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
}
}
public void testSpliteratorOfLongFromIterator() {
Supplier<PrimitiveIterator.OfLong> si = () -> LongStream.of(1, 2, 3, 4).iterator();
{
Spliterator<?> s = Spliterators.spliterator(si.get(), 1, 0);
assertCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
assertHasNotCharacteristics(s, Spliterator.CONCURRENT);
}
{
Spliterator<?> s = Spliterators.spliterator(si.get(), 1, Spliterator.CONCURRENT);
assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
assertCharacteristics(s, Spliterator.CONCURRENT);
}
{
Spliterator<?> s = Spliterators.spliteratorUnknownSize(si.get(), 0);
assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
}
{
Spliterator<?> s = Spliterators.spliteratorUnknownSize(
si.get(), Spliterator.SIZED | Spliterator.SUBSIZED);
assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
}
}
public void testSpliteratorOfDoubleFromIterator() {
Supplier<PrimitiveIterator.OfDouble> si = () -> DoubleStream.of(1, 2, 3, 4).iterator();
{
Spliterator<?> s = Spliterators.spliterator(si.get(), 1, 0);
assertCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
assertHasNotCharacteristics(s, Spliterator.CONCURRENT);
}
{
Spliterator<?> s = Spliterators.spliterator(si.get(), 1, Spliterator.CONCURRENT);
assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
assertCharacteristics(s, Spliterator.CONCURRENT);
}
{
Spliterator<?> s = Spliterators.spliteratorUnknownSize(si.get(), 0);
assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
}
{
Spliterator<?> s = Spliterators.spliteratorUnknownSize(
si.get(), Spliterator.SIZED | Spliterator.SUBSIZED);
assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
}
}
//
public void testHashMap() {
assertMapCharacteristics(new HashMap<>(),
Spliterator.SIZED | Spliterator.DISTINCT);
}
public void testWeakHashMap() {
assertMapCharacteristics(new WeakHashMap<>(),
Spliterator.DISTINCT);
}
public void testHashSet() {
assertSetCharacteristics(new HashSet<>(),
Spliterator.SIZED | Spliterator.DISTINCT);
}
public void testLinkedHashMap() {
assertMapCharacteristics(new LinkedHashMap<>(),
Spliterator.SIZED | Spliterator.DISTINCT |
Spliterator.ORDERED);
}
public void testLinkedHashSet() {
assertSetCharacteristics(new LinkedHashSet<>(),
Spliterator.SIZED | Spliterator.DISTINCT |
Spliterator.ORDERED);
}
public void testTreeMap() {
assertSortedMapCharacteristics(new TreeMap<>(),
Spliterator.SIZED | Spliterator.DISTINCT |
Spliterator.SORTED | Spliterator.ORDERED);
}
public void testTreeMapWithComparator() {
assertSortedMapCharacteristics(new TreeMap<>(Comparator.reverseOrder()),
Spliterator.SIZED | Spliterator.DISTINCT |
Spliterator.SORTED | Spliterator.ORDERED);
}
public void testTreeSet() {
assertSortedSetCharacteristics(new TreeSet<>(),
Spliterator.SIZED | Spliterator.DISTINCT |
Spliterator.SORTED | Spliterator.ORDERED);
}
public void testTreeSetWithComparator() {
assertSortedSetCharacteristics(new TreeSet<>(Comparator.reverseOrder()),
Spliterator.SIZED | Spliterator.DISTINCT |
Spliterator.SORTED | Spliterator.ORDERED);
}
public void testConcurrentSkipListMap() {
assertSortedMapCharacteristics(new ConcurrentSkipListMap<>(),
Spliterator.CONCURRENT | Spliterator.NONNULL |
Spliterator.DISTINCT | Spliterator.SORTED |
Spliterator.ORDERED);
}
public void testConcurrentSkipListMapWithComparator() {
assertSortedMapCharacteristics(new ConcurrentSkipListMap<>(Comparator.<Integer>reverseOrder()),
Spliterator.CONCURRENT | Spliterator.NONNULL |
Spliterator.DISTINCT | Spliterator.SORTED |
Spliterator.ORDERED);
}
public void testConcurrentSkipListSet() {
assertSortedSetCharacteristics(new ConcurrentSkipListSet<>(),
Spliterator.CONCURRENT | Spliterator.NONNULL |
Spliterator.DISTINCT | Spliterator.SORTED |
Spliterator.ORDERED);
}
public void testConcurrentSkipListSetWithComparator() {
assertSortedSetCharacteristics(new ConcurrentSkipListSet<>(Comparator.reverseOrder()),
Spliterator.CONCURRENT | Spliterator.NONNULL |
Spliterator.DISTINCT | Spliterator.SORTED |
Spliterator.ORDERED);
}
//
void assertMapCharacteristics(Map<Integer, String> m, int keyCharacteristics) {
assertMapCharacteristics(m, keyCharacteristics, 0);
}
void assertMapCharacteristics(Map<Integer, String> m, int keyCharacteristics, int notValueCharacteristics) {
initMap(m);
assertCharacteristics(m.keySet(), keyCharacteristics);
assertCharacteristics(m.values(),
keyCharacteristics & ~(Spliterator.DISTINCT | notValueCharacteristics));
assertCharacteristics(m.entrySet(), keyCharacteristics);
if ((keyCharacteristics & Spliterator.SORTED) == 0) {
assertISEComparator(m.keySet());
assertISEComparator(m.values());
assertISEComparator(m.entrySet());
}
}
void assertSetCharacteristics(Set<Integer> s, int keyCharacteristics) {
initSet(s);
assertCharacteristics(s, keyCharacteristics);
if ((keyCharacteristics & Spliterator.SORTED) == 0) {
assertISEComparator(s);
}
}
void assertSortedMapCharacteristics(SortedMap<Integer, String> m, int keyCharacteristics) {
assertMapCharacteristics(m, keyCharacteristics, Spliterator.SORTED);
Set<Integer> keys = m.keySet();
if (m.comparator() != null) {
assertNotNullComparator(keys);
}
else {
assertNullComparator(keys);
}
assertISEComparator(m.values());
assertNotNullComparator(m.entrySet());
}
void assertSortedSetCharacteristics(SortedSet<Integer> s, int keyCharacteristics) {
assertSetCharacteristics(s, keyCharacteristics);
if (s.comparator() != null) {
assertNotNullComparator(s);
}
else {
assertNullComparator(s);
}
}
void initMap(Map<Integer, String> m) {
m.put(1, "4");
m.put(2, "3");
m.put(3, "2");
m.put(4, "1");
}
void initSet(Set<Integer> s) {
s.addAll(Arrays.asList(1, 2, 3, 4));
}
void assertCharacteristics(Collection<?> c, int expectedCharacteristics) {
assertCharacteristics(c.spliterator(), expectedCharacteristics);
}
void assertCharacteristics(Spliterator<?> s, int expectedCharacteristics) {
assertTrue(s.hasCharacteristics(expectedCharacteristics),
"Spliterator characteristics");
}
void assertHasNotCharacteristics(Spliterator<?> s, int expectedCharacteristics) {
assertFalse(s.hasCharacteristics(expectedCharacteristics),
"Spliterator characteristics");
}
void assertNullComparator(Collection<?> c) {
assertNull(c.spliterator().getComparator(),
"Comparator of Spliterator of Collection");
}
void assertNotNullComparator(Collection<?> c) {
assertNotNull(c.spliterator().getComparator(),
"Comparator of Spliterator of Collection");
}
void assertISEComparator(Collection<?> c) {
assertISEComparator(c.spliterator());
}
void assertISEComparator(Spliterator<?> s) {
boolean caught = false;
try {
s.getComparator();
}
catch (IllegalStateException e) {
caught = true;
}
assertTrue(caught, "Throwing IllegalStateException");
}
}

View file

@ -0,0 +1,342 @@
/*
* Copyright (c) 2013, 2017, 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.
*/
/**
* @test
* @bug 8005698
* @library /lib/testlibrary/bootlib
* @build java.base/java.util.SpliteratorTestHelper
* @run testng SpliteratorCollisions
* @summary Spliterator traversing and splitting hash maps containing colliding hashes
*/
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Spliterator;
import java.util.SpliteratorTestHelper;
import java.util.TreeSet;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;
public class SpliteratorCollisions extends SpliteratorTestHelper {
private static final List<Integer> SIZES = Arrays.asList(0, 1, 10, 100, 1000);
private static class SpliteratorDataBuilder<T> {
List<Object[]> data;
List<T> exp;
Map<T, T> mExp;
SpliteratorDataBuilder(List<Object[]> data, List<T> exp) {
this.data = data;
this.exp = exp;
this.mExp = createMap(exp);
}
Map<T, T> createMap(List<T> l) {
Map<T, T> m = new LinkedHashMap<>();
for (T t : l) {
m.put(t, t);
}
return m;
}
void add(String description, Collection<?> expected, Supplier<Spliterator<?>> s) {
description = joiner(description).toString();
data.add(new Object[]{description, expected, s});
}
void add(String description, Supplier<Spliterator<?>> s) {
add(description, exp, s);
}
void addCollection(Function<Collection<T>, ? extends Collection<T>> c) {
add("new " + c.apply(Collections.<T>emptyList()).getClass().getName() + ".spliterator()",
() -> c.apply(exp).spliterator());
}
void addList(Function<Collection<T>, ? extends List<T>> l) {
// @@@ If collection is instance of List then add sub-list tests
addCollection(l);
}
void addMap(Function<Map<T, T>, ? extends Map<T, T>> m) {
String description = "new " + m.apply(Collections.<T, T>emptyMap()).getClass().getName();
add(description + ".keySet().spliterator()", () -> m.apply(mExp).keySet().spliterator());
add(description + ".values().spliterator()", () -> m.apply(mExp).values().spliterator());
add(description + ".entrySet().spliterator()", mExp.entrySet(), () -> m.apply(mExp).entrySet().spliterator());
}
StringBuilder joiner(String description) {
return new StringBuilder(description).
append(" {").
append("size=").append(exp.size()).
append("}");
}
}
static Object[][] spliteratorDataProvider;
@DataProvider(name = "HashableIntSpliterator")
public static Object[][] spliteratorDataProvider() {
if (spliteratorDataProvider != null) {
return spliteratorDataProvider;
}
List<Object[]> data = new ArrayList<>();
for (int size : SIZES) {
List<HashableInteger> exp = listIntRange(size, false);
SpliteratorDataBuilder<HashableInteger> db = new SpliteratorDataBuilder<>(data, exp);
// Maps
db.addMap(HashMap::new);
db.addMap(LinkedHashMap::new);
// Collections that use HashMap
db.addCollection(HashSet::new);
db.addCollection(LinkedHashSet::new);
db.addCollection(TreeSet::new);
}
return spliteratorDataProvider = data.toArray(new Object[0][]);
}
static Object[][] spliteratorDataProviderWithNull;
@DataProvider(name = "HashableIntSpliteratorWithNull")
public static Object[][] spliteratorNullDataProvider() {
if (spliteratorDataProviderWithNull != null) {
return spliteratorDataProviderWithNull;
}
List<Object[]> data = new ArrayList<>();
for (int size : SIZES) {
List<HashableInteger> exp = listIntRange(size, true);
SpliteratorDataBuilder<HashableInteger> db = new SpliteratorDataBuilder<>(data, exp);
// Maps
db.addMap(HashMap::new);
db.addMap(LinkedHashMap::new);
// TODO: add this back in if we decide to keep TreeBin in WeakHashMap
//db.addMap(WeakHashMap::new);
// Collections that use HashMap
db.addCollection(HashSet::new);
db.addCollection(LinkedHashSet::new);
// db.addCollection(TreeSet::new);
}
return spliteratorDataProviderWithNull = data.toArray(new Object[0][]);
}
static final class HashableInteger implements Comparable<HashableInteger> {
final int value;
final int hashmask; //yes duplication
HashableInteger(int value, int hashmask) {
this.value = value;
this.hashmask = hashmask;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof HashableInteger) {
HashableInteger other = (HashableInteger) obj;
return other.value == value;
}
return false;
}
@Override
public int hashCode() {
return value % hashmask;
}
@Override
public int compareTo(HashableInteger o) {
return value - o.value;
}
@Override
public String toString() {
return Integer.toString(value);
}
}
private static List<HashableInteger> listIntRange(int upTo, boolean withNull) {
List<HashableInteger> exp = new ArrayList<>();
if (withNull) {
exp.add(null);
}
for (int i = 0; i < upTo; i++) {
exp.add(new HashableInteger(i, 10));
}
return Collections.unmodifiableList(exp);
}
@Test(dataProvider = "HashableIntSpliterator")
void testNullPointerException(String description,
Collection<HashableInteger> exp,
Supplier<Spliterator<HashableInteger>> s) {
assertThrowsNPE(() -> s.get().forEachRemaining(null));
assertThrowsNPE(() -> s.get().tryAdvance(null));
}
@Test(dataProvider = "HashableIntSpliteratorWithNull")
void testNullPointerExceptionWithNull(String description,
Collection<HashableInteger> exp,
Supplier<Spliterator<HashableInteger>> s) {
assertThrowsNPE(() -> s.get().forEachRemaining(null));
assertThrowsNPE(() -> s.get().tryAdvance(null));
}
@Test(dataProvider = "HashableIntSpliterator")
void testForEach(String description,
Collection<HashableInteger> exp,
Supplier<Spliterator<HashableInteger>> s) {
testForEach(exp, s, UnaryOperator.identity());
}
@Test(dataProvider = "HashableIntSpliteratorWithNull")
void testForEachWithNull(String description,
Collection<HashableInteger> exp,
Supplier<Spliterator<HashableInteger>> s) {
testForEach(exp, s, UnaryOperator.identity());
}
@Test(dataProvider = "HashableIntSpliterator")
void testTryAdvance(String description,
Collection<HashableInteger> exp,
Supplier<Spliterator<HashableInteger>> s) {
testTryAdvance(exp, s, UnaryOperator.identity());
}
@Test(dataProvider = "HashableIntSpliteratorWithNull")
void testTryAdvanceWithNull(String description,
Collection<HashableInteger> exp,
Supplier<Spliterator<HashableInteger>> s) {
testTryAdvance(exp, s, UnaryOperator.identity());
}
@Test(dataProvider = "HashableIntSpliterator")
void testMixedTryAdvanceForEach(String description,
Collection<HashableInteger> exp,
Supplier<Spliterator<HashableInteger>> s) {
testMixedTryAdvanceForEach(exp, s, UnaryOperator.identity());
}
@Test(dataProvider = "HashableIntSpliteratorWithNull")
void testMixedTryAdvanceForEachWithNull(String description,
Collection<HashableInteger> exp,
Supplier<Spliterator<HashableInteger>> s) {
testMixedTryAdvanceForEach(exp, s, UnaryOperator.identity());
}
@Test(dataProvider = "HashableIntSpliterator")
void testMixedTraverseAndSplit(String description,
Collection<HashableInteger> exp,
Supplier<Spliterator<HashableInteger>> s) {
testMixedTraverseAndSplit(exp, s, UnaryOperator.identity());
}
@Test(dataProvider = "HashableIntSpliteratorWithNull")
void testMixedTraverseAndSplitWithNull(String description,
Collection<HashableInteger> exp,
Supplier<Spliterator<HashableInteger>> s) {
testMixedTraverseAndSplit(exp, s, UnaryOperator.identity());
}
@Test(dataProvider = "HashableIntSpliterator")
void testSplitAfterFullTraversal(String description,
Collection<HashableInteger> exp,
Supplier<Spliterator<HashableInteger>> s) {
testSplitAfterFullTraversal(s, UnaryOperator.identity());
}
@Test(dataProvider = "HashableIntSpliteratorWithNull")
void testSplitAfterFullTraversalWithNull(String description,
Collection<HashableInteger> exp,
Supplier<Spliterator<HashableInteger>> s) {
testSplitAfterFullTraversal(s, UnaryOperator.identity());
}
@Test(dataProvider = "HashableIntSpliterator")
void testSplitOnce(String description,
Collection<HashableInteger> exp,
Supplier<Spliterator<HashableInteger>> s) {
testSplitOnce(exp, s, UnaryOperator.identity());
}
@Test(dataProvider = "HashableIntSpliteratorWithNull")
void testSplitOnceWithNull(String description,
Collection<HashableInteger> exp,
Supplier<Spliterator<HashableInteger>> s) {
testSplitOnce(exp, s, UnaryOperator.identity());
}
@Test(dataProvider = "HashableIntSpliterator")
void testSplitSixDeep(String description,
Collection<HashableInteger> exp,
Supplier<Spliterator<HashableInteger>> s) {
testSplitSixDeep(exp, s, UnaryOperator.identity());
}
@Test(dataProvider = "HashableIntSpliteratorWithNull")
void testSplitSixDeepWithNull(String description,
Collection<HashableInteger> exp,
Supplier<Spliterator<HashableInteger>> s) {
testSplitSixDeep(exp, s, UnaryOperator.identity());
}
@Test(dataProvider = "HashableIntSpliterator")
void testSplitUntilNull(String description,
Collection<HashableInteger> exp,
Supplier<Spliterator<HashableInteger>> s) {
testSplitUntilNull(exp, s, UnaryOperator.identity());
}
@Test(dataProvider = "HashableIntSpliteratorWithNull")
void testSplitUntilNullWithNull(String description,
Collection<HashableInteger> exp,
Supplier<Spliterator<HashableInteger>> s) {
testSplitUntilNull(exp, s, UnaryOperator.identity());
}
}

View file

@ -0,0 +1,184 @@
/*
* Copyright (c) 2013, 2017, 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.ConcurrentModificationException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Spliterator;
import java.util.Stack;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Vector;
import java.util.WeakHashMap;
import java.util.function.Supplier;
import org.testng.Assert.ThrowingRunnable;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import static org.testng.Assert.assertThrows;
/**
* @test
* @bug 8148748
* @summary Spliterator fail-fast tests
* @run testng SpliteratorFailFastTest
*/
@Test
public class SpliteratorFailFastTest extends SpliteratorLateBindingFailFastHelper {
static Object[][] spliteratorDataProvider;
@DataProvider(name = "Source")
public static Object[][] spliteratorDataProvider() {
if (spliteratorDataProvider != null) {
return spliteratorDataProvider;
}
List<Object[]> data = new ArrayList<>();
SpliteratorDataBuilder<Integer> db =
new SpliteratorDataBuilder<>(data, 5, Arrays.asList(1, 2, 3, 4));
// Collections
db.addList(ArrayList::new);
db.addList(LinkedList::new);
db.addList(Vector::new);
db.addList(AbstractRandomAccessListImpl::new);
db.addCollection(HashSet::new);
db.addCollection(LinkedHashSet::new);
db.addCollection(TreeSet::new);
db.addCollection(c -> {
Stack<Integer> s = new Stack<>();
s.addAll(c);
return s;
});
db.addCollection(PriorityQueue::new);
// ArrayDeque fails some tests since its fail-fast support is weaker
// than other collections and limited to detecting most, but not all,
// removals. It probably requires its own test since it is difficult
// to abstract out the conditions under which it fails-fast.
// db.addCollection(ArrayDeque::new);
// Maps
db.addMap(HashMap::new);
db.addMap(LinkedHashMap::new);
// This fails when run through jtreg but passes when run through
// ant
// db.addMap(IdentityHashMap::new);
db.addMap(WeakHashMap::new);
// @@@ Descending maps etc
db.addMap(TreeMap::new);
return spliteratorDataProvider = data.toArray(new Object[0][]);
}
@Test(dataProvider = "Source")
public <T> void testTryAdvance(String description, Supplier<Source<T>> ss) {
{
Source<T> source = ss.get();
Spliterator<T> s = source.spliterator();
s.tryAdvance(e -> {
});
source.update();
assertThrowsCME(() -> s.tryAdvance(e -> {
}));
}
{
Source<T> source = ss.get();
Spliterator<T> s = source.spliterator();
s.tryAdvance(e -> {
});
source.update();
assertThrowsCME(() -> s.forEachRemaining(e -> {
}));
}
}
@Test(dataProvider = "Source")
public <T> void testForEach(String description, Supplier<Source<T>> ss) {
Source<T> source = ss.get();
Spliterator<T> s = source.spliterator();
assertThrowsCME(() -> s.forEachRemaining(e -> {
source.update();
}));
}
@Test(dataProvider = "Source")
public <T> void testEstimateSize(String description, Supplier<Source<T>> ss) {
{
Source<T> source = ss.get();
Spliterator<T> s = source.spliterator();
s.estimateSize();
source.update();
assertThrowsCME(() -> s.tryAdvance(e -> {
}));
}
{
Source<T> source = ss.get();
Spliterator<T> s = source.spliterator();
s.estimateSize();
source.update();
assertThrowsCME(() -> s.forEachRemaining(e -> {
}));
}
}
private void assertThrowsCME(ThrowingRunnable r) {
assertThrows(ConcurrentModificationException.class, r);
}
}

View file

@ -0,0 +1,224 @@
/*
* Copyright (c) 2016, 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.AbstractList;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.RandomAccess;
import java.util.Spliterator;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
class SpliteratorLateBindingFailFastHelper {
interface Source<T> {
Spliterator<T> spliterator();
void update();
default boolean bindOnCharacteristics() {
return false;
}
}
static class IntSource<T> implements Source<Integer> {
final T b;
final Function<? super T, Spliterator.OfInt> toSpliterator;
final Consumer<T> updater;
final boolean bindOnCharacteristics;
public IntSource(T b, Function<? super T, Spliterator.OfInt> toSpliterator,
Consumer<T> updater) {
this(b, toSpliterator, updater, false);
}
public IntSource(T b, Function<? super T, Spliterator.OfInt> toSpliterator,
Consumer<T> updater, boolean bindOnCharacteristics) {
this.b = b;
this.toSpliterator = toSpliterator;
this.updater = updater;
this.bindOnCharacteristics = bindOnCharacteristics;
}
@Override
public Spliterator.OfInt spliterator() {
return toSpliterator.apply(b);
}
@Override
public void update() {
updater.accept(b);
}
@Override
public boolean bindOnCharacteristics() {
return bindOnCharacteristics;
}
}
static class SpliteratorDataBuilder<T> {
final List<Object[]> data;
final T newValue;
final List<T> exp;
final Map<T, T> mExp;
SpliteratorDataBuilder(List<Object[]> data, T newValue, List<T> exp) {
this.data = data;
this.newValue = newValue;
this.exp = exp;
this.mExp = createMap(exp);
}
Map<T, T> createMap(List<T> l) {
Map<T, T> m = new LinkedHashMap<>();
for (T t : l) {
m.put(t, t);
}
return m;
}
void add(String description, Supplier<Source<?>> s) {
data.add(new Object[]{description, s});
}
void addCollection(Function<Collection<T>, ? extends Collection<T>> f) {
class CollectionSource implements Source<T> {
final Collection<T> c = f.apply(exp);
final Consumer<Collection<T>> updater;
CollectionSource(Consumer<Collection<T>> updater) {
this.updater = updater;
}
@Override
public Spliterator<T> spliterator() {
return c.spliterator();
}
@Override
public void update() {
updater.accept(c);
}
}
String description = "new " + f.apply(Collections.<T>emptyList()).getClass().getName() + ".spliterator() ";
add(description + "ADD", () -> new CollectionSource(c -> c.add(newValue)));
add(description + "REMOVE", () -> new CollectionSource(c -> c.remove(c.iterator().next())));
}
void addList(Function<Collection<T>, ? extends List<T>> l) {
addCollection(l);
addCollection(l.andThen(list -> list.subList(0, list.size())));
}
void addMap(Function<Map<T, T>, ? extends Map<T, T>> mapConstructor) {
class MapSource<U> implements Source<U> {
final Map<T, T> m = mapConstructor.apply(mExp);
final Collection<U> c;
final Consumer<Map<T, T>> updater;
MapSource(Function<Map<T, T>, Collection<U>> f, Consumer<Map<T, T>> updater) {
this.c = f.apply(m);
this.updater = updater;
}
@Override
public Spliterator<U> spliterator() {
return c.spliterator();
}
@Override
public void update() {
updater.accept(m);
}
}
Map<String, Consumer<Map<T, T>>> actions = new HashMap<>();
actions.put("ADD", m -> m.put(newValue, newValue));
actions.put("REMOVE", m -> m.remove(m.keySet().iterator().next()));
String description = "new " + mapConstructor.apply(Collections.<T, T>emptyMap()).getClass().getName();
for (Map.Entry<String, Consumer<Map<T, T>>> e : actions.entrySet()) {
add(description + ".keySet().spliterator() " + e.getKey(),
() -> new MapSource<>(m -> m.keySet(), e.getValue()));
add(description + ".values().spliterator() " + e.getKey(),
() -> new MapSource<>(m -> m.values(), e.getValue()));
add(description + ".entrySet().spliterator() " + e.getKey(),
() -> new MapSource<>(m -> m.entrySet(), e.getValue()));
}
}
}
static class AbstractRandomAccessListImpl extends AbstractList<Integer> implements RandomAccess {
List<Integer> l;
AbstractRandomAccessListImpl(Collection<Integer> c) {
this.l = new ArrayList<>(c);
}
@Override
public boolean add(Integer integer) {
modCount++;
return l.add(integer);
}
@Override
public Iterator<Integer> iterator() {
return l.iterator();
}
@Override
public Integer get(int index) {
return l.get(index);
}
@Override
public boolean remove(Object o) {
modCount++;
return l.remove(o);
}
@Override
public int size() {
return l.size();
}
@Override
public List<Integer> subList(int fromIndex, int toIndex) {
return l.subList(fromIndex, toIndex);
}
}
}

View file

@ -0,0 +1,221 @@
/*
* Copyright (c) 2013, 2016, 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 org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import java.nio.CharBuffer;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Set;
import java.util.Spliterator;
import java.util.Stack;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Vector;
import java.util.WeakHashMap;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Stream;
import static org.testng.Assert.assertEquals;
/**
* @test
* @bug 8148748 8170155
* @summary Spliterator last-binding tests
* @run testng SpliteratorLateBindingTest
*/
@Test
public class SpliteratorLateBindingTest extends SpliteratorLateBindingFailFastHelper {
static Object[][] spliteratorDataProvider;
@DataProvider(name = "Source")
public static Object[][] sourceDataProvider() {
if (spliteratorDataProvider != null) {
return spliteratorDataProvider;
}
List<Object[]> data = new ArrayList<>();
SpliteratorDataBuilder<Integer> db =
new SpliteratorDataBuilder<>(data, 5, Arrays.asList(1, 2, 3, 4));
// Collections
db.addList(ArrayList::new);
db.addList(LinkedList::new);
db.addList(Vector::new);
db.addList(AbstractRandomAccessListImpl::new);
db.addCollection(HashSet::new);
db.addCollection(LinkedHashSet::new);
db.addCollection(TreeSet::new);
db.addCollection(c -> {
Stack<Integer> s = new Stack<>();
s.addAll(c);
return s;
});
db.addCollection(PriorityQueue::new);
db.addCollection(ArrayDeque::new);
// Maps
db.addMap(HashMap::new);
db.addMap(LinkedHashMap::new);
db.addMap(IdentityHashMap::new);
db.addMap(WeakHashMap::new);
// @@@ Descending maps etc
db.addMap(TreeMap::new);
// BitSet
List<Integer> bits = List.of(0, 1, 2);
Function<BitSet, Spliterator.OfInt> bitsSource = bs -> bs.stream().spliterator();
db.add("new BitSet.stream().spliterator() ADD",
() -> new IntSource<>(toBitSet(bits), bitsSource, bs -> bs.set(3)));
db.add("new BitSet.stream().spliterator() REMOVE",
() -> new IntSource<>(toBitSet(bits), bitsSource, bs -> bs.clear(2)));
// CharSequence
Function<CharSequence, Spliterator.OfInt> charsSource = sb -> sb.chars().spliterator();
Function<CharSequence, Spliterator.OfInt> pointsSource = sb -> sb.codePoints().spliterator();
db.add("new StringBuilder.chars().spliterator() ADD",
() -> new IntSource<>(new StringBuilder("ABC"), charsSource, bs -> bs.append("D"), true));
db.add("new StringBuilder.chars().spliterator() REMOVE",
() -> new IntSource<>(new StringBuilder("ABC"), charsSource, bs -> bs.deleteCharAt(2), true));
db.add("new StringBuilder.codePoints().spliterator() ADD",
() -> new IntSource<>(new StringBuilder("ABC"), pointsSource, bs -> bs.append("D"), true));
db.add("new StringBuilder.codePoints().spliterator() REMOVE",
() -> new IntSource<>(new StringBuilder("ABC"), pointsSource, bs -> bs.deleteCharAt(2), true));
db.add("new StringBuffer.chars().spliterator() ADD",
() -> new IntSource<>(new StringBuffer("ABC"), charsSource, bs -> bs.append("D"), true));
db.add("new StringBuffer.chars().spliterator() REMOVE",
() -> new IntSource<>(new StringBuffer("ABC"), charsSource, bs -> bs.deleteCharAt(2), true));
db.add("new StringBuffer.codePoints().spliterator() ADD",
() -> new IntSource<>(new StringBuffer("ABC"), pointsSource, bs -> bs.append("D"), true));
db.add("new StringBuffer.codePoints().spliterator() REMOVE",
() -> new IntSource<>(new StringBuffer("ABC"), pointsSource, bs -> bs.deleteCharAt(2), true));
db.add("CharBuffer.wrap().chars().spliterator() ADD",
() -> new IntSource<>(CharBuffer.wrap("ABCD").limit(3), charsSource, bs -> bs.limit(4), true));
db.add("CharBuffer.wrap().chars().spliterator() REMOVE",
() -> new IntSource<>(CharBuffer.wrap("ABCD"), charsSource, bs -> bs.limit(3), true));
db.add("CharBuffer.wrap().codePoints().spliterator() ADD",
() -> new IntSource<>(CharBuffer.wrap("ABCD").limit(3), pointsSource, bs -> bs.limit(4), true));
db.add("CharBuffer.wrap().codePoints().spliterator() REMOVE",
() -> new IntSource<>(CharBuffer.wrap("ABCD"), pointsSource, bs -> bs.limit(3), true));
return spliteratorDataProvider = data.toArray(new Object[0][]);
}
@DataProvider(name = "Source.Non.Binding.Characteristics")
public static Object[][] sourceCharacteristicsDataProvider() {
return Stream.of(sourceDataProvider()).filter(tc -> {
@SuppressWarnings("unchecked")
Supplier<Source<?>> s = (Supplier<Source<?>>) tc[1];
return !s.get().bindOnCharacteristics();
}).toArray(Object[][]::new);
}
static BitSet toBitSet(List<Integer> bits) {
BitSet bs = new BitSet();
bits.forEach(bs::set);
return bs;
}
@Test(dataProvider = "Source")
public <T> void testForEach(String description, Supplier<Source<T>> ss) {
Source<T> source = ss.get();
Spliterator<T> s = source.spliterator();
source.update();
Set<T> a = new HashSet<>();
s.forEachRemaining(a::add);
Set<T> e = new HashSet<>();
source.spliterator().forEachRemaining(e::add);
assertEquals(a, e);
}
@Test(dataProvider = "Source")
public <T> void testTryAdvance(String description, Supplier<Source<T>> ss) {
Source<T> source = ss.get();
Spliterator<T> s = source.spliterator();
source.update();
Set<T> a = new HashSet<>();
while (s.tryAdvance(a::add)) {
}
Set<T> e = new HashSet<>();
source.spliterator().forEachRemaining(e::add);
assertEquals(a, e);
}
@Test(dataProvider = "Source.Non.Binding.Characteristics")
public <T> void testCharacteristics(String description, Supplier<Source<T>> ss) {
Source<T> source = ss.get();
Spliterator<T> s = source.spliterator();
s.characteristics();
source.update();
Set<T> a = new HashSet<>();
s.forEachRemaining(a::add);
Set<T> e = new HashSet<>();
source.spliterator().forEachRemaining(e::add);
assertEquals(a, e);
}
}

File diff suppressed because it is too large Load diff