1 /*
   2  * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /**
  25  * @test
  26  * @summary Spliterator traversing and splitting tests
  27  * @library ../stream/bootlib
  28  * @build java.base/java.util.SpliteratorTestHelper
  29  * @run testng SpliteratorTraversingAndSplittingTest
  30  * @bug 8020016 8071477 8072784 8169838
  31  */
  32 
  33 import org.testng.annotations.DataProvider;
  34 import org.testng.annotations.Test;
  35 
  36 import java.nio.CharBuffer;
  37 import java.util.AbstractCollection;
  38 import java.util.AbstractList;
  39 import java.util.AbstractSet;
  40 import java.util.ArrayDeque;
  41 import java.util.ArrayList;
  42 import java.util.Arrays;
  43 import java.util.BitSet;
  44 import java.util.Collection;
  45 import java.util.Collections;
  46 import java.util.Comparator;
  47 import java.util.HashMap;
  48 import java.util.HashSet;
  49 import java.util.IdentityHashMap;
  50 import java.util.Iterator;
  51 import java.util.LinkedHashMap;
  52 import java.util.LinkedHashSet;
  53 import java.util.LinkedList;
  54 import java.util.List;
  55 import java.util.ListIterator;
  56 import java.util.Map;
  57 import java.util.PriorityQueue;
  58 import java.util.RandomAccess;
  59 import java.util.Set;
  60 import java.util.SortedSet;
  61 import java.util.Spliterator;
  62 import java.util.SpliteratorTestHelper;
  63 import java.util.Spliterators;
  64 import java.util.Stack;
  65 import java.util.TreeMap;
  66 import java.util.TreeSet;
  67 import java.util.Vector;
  68 import java.util.WeakHashMap;
  69 import java.util.concurrent.ArrayBlockingQueue;
  70 import java.util.concurrent.ConcurrentHashMap;
  71 import java.util.concurrent.ConcurrentLinkedQueue;
  72 import java.util.concurrent.ConcurrentSkipListMap;
  73 import java.util.concurrent.ConcurrentSkipListSet;
  74 import java.util.concurrent.CopyOnWriteArrayList;
  75 import java.util.concurrent.CopyOnWriteArraySet;
  76 import java.util.concurrent.LinkedBlockingDeque;
  77 import java.util.concurrent.LinkedBlockingQueue;
  78 import java.util.concurrent.LinkedTransferQueue;
  79 import java.util.concurrent.PriorityBlockingQueue;
  80 import java.util.function.Consumer;
  81 import java.util.function.DoubleConsumer;
  82 import java.util.function.Function;
  83 import java.util.function.IntConsumer;
  84 import java.util.function.LongConsumer;
  85 import java.util.function.Supplier;
  86 import java.util.function.UnaryOperator;
  87 import java.util.stream.IntStream;
  88 
  89 import static java.util.stream.Collectors.toList;
  90 
  91 public class SpliteratorTraversingAndSplittingTest extends SpliteratorTestHelper {
  92 
  93     private static final List<Integer> SIZES = Arrays.asList(0, 1, 10, 42);
  94 
  95     private static final String LOW = new String(new char[] {Character.MIN_LOW_SURROGATE});
  96     private static final String HIGH = new String(new char[] {Character.MIN_HIGH_SURROGATE});
  97     private static final String HIGH_LOW = HIGH + LOW;
  98     private static final String CHAR_HIGH_LOW = "A" + HIGH_LOW;
  99     private static final String HIGH_LOW_CHAR = HIGH_LOW + "A";
 100     private static final String CHAR_HIGH_LOW_CHAR = "A" + HIGH_LOW + "A";
 101 
 102     private static final List<String> STRINGS = generateTestStrings();
 103 
 104     private static List<String> generateTestStrings() {
 105         List<String> strings = new ArrayList<>();
 106         for (int n : Arrays.asList(1, 2, 3, 16, 17)) {
 107             strings.add(generate("A", n));
 108             strings.add(generate(LOW, n));
 109             strings.add(generate(HIGH, n));
 110             strings.add(generate(HIGH_LOW, n));
 111             strings.add(generate(CHAR_HIGH_LOW, n));
 112             strings.add(generate(HIGH_LOW_CHAR, n));
 113             strings.add(generate(CHAR_HIGH_LOW_CHAR, n));
 114         }
 115         return strings;
 116     }
 117 
 118     private static String generate(String s, int n) {
 119         StringBuilder sb = new StringBuilder();
 120         for (int i = 0; i < n; i++) {
 121             sb.append(s);
 122         }
 123         return sb.toString();
 124     }
 125 
 126     private static class SpliteratorDataBuilder<T> {
 127         List<Object[]> data;
 128 
 129         List<T> exp;
 130 
 131         Map<T, T> mExp;
 132 
 133         SpliteratorDataBuilder(List<Object[]> data, List<T> exp) {
 134             this.data = data;
 135             this.exp = exp;
 136             this.mExp = createMap(exp);
 137         }
 138 
 139         Map<T, T> createMap(List<T> l) {
 140             Map<T, T> m = new LinkedHashMap<>();
 141             for (T t : l) {
 142                 m.put(t, t);
 143             }
 144             return m;
 145         }
 146 
 147         void add(String description, Collection<?> expected, Supplier<Spliterator<?>> s) {
 148             description = joiner(description).toString();
 149             data.add(new Object[]{description, expected, s});
 150         }
 151 
 152         void add(String description, Supplier<Spliterator<?>> s) {
 153             add(description, exp, s);
 154         }
 155 
 156         void addCollection(Function<Collection<T>, ? extends Collection<T>> c) {
 157             add("new " + c.apply(Collections.<T>emptyList()).getClass().getName() + ".spliterator()",
 158                 () -> c.apply(exp).spliterator());
 159         }
 160 
 161         void addList(Function<Collection<T>, ? extends List<T>> l) {
 162             addCollection(l);
 163             addCollection(l.andThen(list -> list.subList(0, list.size())));
 164         }
 165 
 166         void addMap(Function<Map<T, T>, ? extends Map<T, T>> m) {
 167             String description = "new " + m.apply(Collections.<T, T>emptyMap()).getClass().getName();
 168             addMap(m, description);
 169         }
 170 
 171         void addMap(Function<Map<T, T>, ? extends Map<T, T>> m, String description) {
 172             add(description + ".keySet().spliterator()", () -> m.apply(mExp).keySet().spliterator());
 173             add(description + ".values().spliterator()", () -> m.apply(mExp).values().spliterator());
 174             add(description + ".entrySet().spliterator()", mExp.entrySet(), () -> m.apply(mExp).entrySet().spliterator());
 175         }
 176 
 177         StringBuilder joiner(String description) {
 178             return new StringBuilder(description).
 179                     append(" {").
 180                     append("size=").append(exp.size()).
 181                     append("}");
 182         }
 183     }
 184 
 185     static Object[][] spliteratorDataProvider;
 186 
 187     @DataProvider(name = "Spliterator<Integer>")
 188     public static Object[][] spliteratorDataProvider() {
 189         if (spliteratorDataProvider != null) {
 190             return spliteratorDataProvider;
 191         }
 192 
 193         List<Object[]> data = new ArrayList<>();
 194         for (int size : SIZES) {
 195             List<Integer> exp = listIntRange(size);
 196             SpliteratorDataBuilder<Integer> db = new SpliteratorDataBuilder<>(data, exp);
 197 
 198             // Direct spliterator methods
 199 
 200             db.add("Spliterators.spliterator(Collection, ...)",
 201                    () -> Spliterators.spliterator(exp, 0));
 202 
 203             db.add("Spliterators.spliterator(Iterator, ...)",
 204                    () -> Spliterators.spliterator(exp.iterator(), exp.size(), 0));
 205 
 206             db.add("Spliterators.spliteratorUnknownSize(Iterator, ...)",
 207                    () -> Spliterators.spliteratorUnknownSize(exp.iterator(), 0));
 208 
 209             db.add("Spliterators.spliterator(Spliterators.iteratorFromSpliterator(Spliterator ), ...)",
 210                    () -> Spliterators.spliterator(Spliterators.iterator(exp.spliterator()), exp.size(), 0));
 211 
 212             db.add("Spliterators.spliterator(T[], ...)",
 213                    () -> Spliterators.spliterator(exp.toArray(new Integer[0]), 0));
 214 
 215             db.add("Arrays.spliterator(T[], ...)",
 216                    () -> Arrays.spliterator(exp.toArray(new Integer[0])));
 217 
 218             class SpliteratorFromIterator extends Spliterators.AbstractSpliterator<Integer> {
 219                 Iterator<Integer> it;
 220 
 221                 SpliteratorFromIterator(Iterator<Integer> it, long est) {
 222                     super(est, Spliterator.SIZED);
 223                     this.it = it;
 224                 }
 225 
 226                 @Override
 227                 public boolean tryAdvance(Consumer<? super Integer> action) {
 228                     if (action == null)
 229                         throw new NullPointerException();
 230                     if (it.hasNext()) {
 231                         action.accept(it.next());
 232                         return true;
 233                     }
 234                     else {
 235                         return false;
 236                     }
 237                 }
 238             }
 239             db.add("new Spliterators.AbstractSpliterator()",
 240                    () -> new SpliteratorFromIterator(exp.iterator(), exp.size()));
 241 
 242             // Collections
 243 
 244             // default method implementations
 245 
 246             class AbstractCollectionImpl extends AbstractCollection<Integer> {
 247                 Collection<Integer> c;
 248 
 249                 AbstractCollectionImpl(Collection<Integer> c) {
 250                     this.c = c;
 251                 }
 252 
 253                 @Override
 254                 public Iterator<Integer> iterator() {
 255                     return c.iterator();
 256                 }
 257 
 258                 @Override
 259                 public int size() {
 260                     return c.size();
 261                 }
 262             }
 263             db.addCollection(
 264                     c -> new AbstractCollectionImpl(c));
 265 
 266             class AbstractListImpl extends AbstractList<Integer> {
 267                 List<Integer> l;
 268 
 269                 AbstractListImpl(Collection<Integer> c) {
 270                     this.l = new ArrayList<>(c);
 271                 }
 272 
 273                 @Override
 274                 public Integer get(int index) {
 275                     return l.get(index);
 276                 }
 277 
 278                 @Override
 279                 public int size() {
 280                     return l.size();
 281                 }
 282             }
 283             db.addCollection(
 284                     c -> new AbstractListImpl(c));
 285 
 286             class AbstractSetImpl extends AbstractSet<Integer> {
 287                 Set<Integer> s;
 288 
 289                 AbstractSetImpl(Collection<Integer> c) {
 290                     this.s = new HashSet<>(c);
 291                 }
 292 
 293                 @Override
 294                 public Iterator<Integer> iterator() {
 295                     return s.iterator();
 296                 }
 297 
 298                 @Override
 299                 public int size() {
 300                     return s.size();
 301                 }
 302             }
 303             db.addCollection(
 304                     c -> new AbstractSetImpl(c));
 305 
 306             class AbstractSortedSetImpl extends AbstractSet<Integer> implements SortedSet<Integer> {
 307                 SortedSet<Integer> s;
 308 
 309                 AbstractSortedSetImpl(Collection<Integer> c) {
 310                     this.s = new TreeSet<>(c);
 311                 }
 312 
 313                 @Override
 314                 public Iterator<Integer> iterator() {
 315                     return s.iterator();
 316                 }
 317 
 318                 @Override
 319                 public int size() {
 320                     return s.size();
 321                 }
 322 
 323                 @Override
 324                 public Comparator<? super Integer> comparator() {
 325                     return s.comparator();
 326                 }
 327 
 328                 @Override
 329                 public SortedSet<Integer> subSet(Integer fromElement, Integer toElement) {
 330                     return s.subSet(fromElement, toElement);
 331                 }
 332 
 333                 @Override
 334                 public SortedSet<Integer> headSet(Integer toElement) {
 335                     return s.headSet(toElement);
 336                 }
 337 
 338                 @Override
 339                 public SortedSet<Integer> tailSet(Integer fromElement) {
 340                     return s.tailSet(fromElement);
 341                 }
 342 
 343                 @Override
 344                 public Integer first() {
 345                     return s.first();
 346                 }
 347 
 348                 @Override
 349                 public Integer last() {
 350                     return s.last();
 351                 }
 352 
 353                 @Override
 354                 public Spliterator<Integer> spliterator() {
 355                     return SortedSet.super.spliterator();
 356                 }
 357             }
 358             db.addCollection(
 359                     c -> new AbstractSortedSetImpl(c));
 360 
 361             class IterableWrapper implements Iterable<Integer> {
 362                 final Iterable<Integer> it;
 363 
 364                 IterableWrapper(Iterable<Integer> it) {
 365                     this.it = it;
 366                 }
 367 
 368                 @Override
 369                 public Iterator<Integer> iterator() {
 370                     return it.iterator();
 371                 }
 372             }
 373             db.add("new Iterable.spliterator()",
 374                    () -> new IterableWrapper(exp).spliterator());
 375 
 376             //
 377 
 378             db.add("Arrays.asList().spliterator()",
 379                    () -> Spliterators.spliterator(Arrays.asList(exp.toArray(new Integer[0])), 0));
 380 
 381             db.addList(ArrayList::new);
 382 
 383             db.addList(LinkedList::new);
 384 
 385             db.addList(Vector::new);
 386 
 387             class AbstractRandomAccessListImpl extends AbstractList<Integer> implements RandomAccess {
 388                 Integer[] ia;
 389 
 390                 AbstractRandomAccessListImpl(Collection<Integer> c) {
 391                     this.ia = c.toArray(new Integer[c.size()]);
 392                 }
 393 
 394                 @Override
 395                 public Integer get(int index) {
 396                     return ia[index];
 397                 }
 398 
 399                 @Override
 400                 public int size() {
 401                     return ia.length;
 402                 }
 403             }
 404             db.addList(AbstractRandomAccessListImpl::new);
 405 
 406             class RandomAccessListImpl implements List<Integer>, RandomAccess {
 407                 Integer[] ia;
 408                 List<Integer> l;
 409 
 410                 RandomAccessListImpl(Collection<Integer> c) {
 411                     this.ia = c.toArray(new Integer[c.size()]);
 412                     this.l = Arrays.asList(ia);
 413                 }
 414 
 415                 @Override
 416                 public Integer get(int index) {
 417                     return ia[index];
 418                 }
 419 
 420                 @Override
 421                 public Integer set(int index, Integer element) {
 422                     throw new UnsupportedOperationException();
 423                 }
 424 
 425                 @Override
 426                 public void add(int index, Integer element) {
 427                     throw new UnsupportedOperationException();
 428                 }
 429 
 430                 @Override
 431                 public Integer remove(int index) {
 432                     throw new UnsupportedOperationException();
 433                 }
 434 
 435                 @Override
 436                 public int indexOf(Object o) {
 437                     return l.indexOf(o);
 438                 }
 439 
 440                 @Override
 441                 public int lastIndexOf(Object o) {
 442                     return Arrays.asList(ia).lastIndexOf(o);
 443                 }
 444 
 445                 @Override
 446                 public ListIterator<Integer> listIterator() {
 447                     return l.listIterator();
 448                 }
 449 
 450                 @Override
 451                 public ListIterator<Integer> listIterator(int index) {
 452                     return l.listIterator(index);
 453                 }
 454 
 455                 @Override
 456                 public List<Integer> subList(int fromIndex, int toIndex) {
 457                     return l.subList(fromIndex, toIndex);
 458                 }
 459 
 460                 @Override
 461                 public int size() {
 462                     return ia.length;
 463                 }
 464 
 465                 @Override
 466                 public boolean isEmpty() {
 467                     return size() != 0;
 468                 }
 469 
 470                 @Override
 471                 public boolean contains(Object o) {
 472                     return l.contains(o);
 473                 }
 474 
 475                 @Override
 476                 public Iterator<Integer> iterator() {
 477                     return l.iterator();
 478                 }
 479 
 480                 @Override
 481                 public Object[] toArray() {
 482                     return l.toArray();
 483                 }
 484 
 485                 @Override
 486                 public <T> T[] toArray(T[] a) {
 487                     return l.toArray(a);
 488                 }
 489 
 490                 @Override
 491                 public boolean add(Integer integer) {
 492                     throw new UnsupportedOperationException();
 493                 }
 494 
 495                 @Override
 496                 public boolean remove(Object o) {
 497                     throw new UnsupportedOperationException();
 498                 }
 499 
 500                 @Override
 501                 public boolean containsAll(Collection<?> c) {
 502                     return l.containsAll(c);
 503                 }
 504 
 505                 @Override
 506                 public boolean addAll(Collection<? extends Integer> c) {
 507                     throw new UnsupportedOperationException();
 508                 }
 509 
 510                 @Override
 511                 public boolean addAll(int index, Collection<? extends Integer> c) {
 512                     throw new UnsupportedOperationException();
 513                 }
 514 
 515                 @Override
 516                 public boolean removeAll(Collection<?> c) {
 517                     throw new UnsupportedOperationException();
 518                 }
 519 
 520                 @Override
 521                 public boolean retainAll(Collection<?> c) {
 522                     throw new UnsupportedOperationException();
 523                 }
 524 
 525                 @Override
 526                 public void clear() {
 527                     throw new UnsupportedOperationException();
 528                 }
 529             }
 530             db.addList(RandomAccessListImpl::new);
 531 
 532             db.addCollection(HashSet::new);
 533 
 534             db.addCollection(LinkedHashSet::new);
 535 
 536             db.addCollection(TreeSet::new);
 537 
 538 
 539             db.addCollection(c -> { Stack<Integer> s = new Stack<>(); s.addAll(c); return s;});
 540 
 541             db.addCollection(PriorityQueue::new);
 542 
 543             db.addCollection(ArrayDeque::new);
 544 
 545 
 546             db.addCollection(ConcurrentSkipListSet::new);
 547 
 548             if (size > 0) {
 549                 db.addCollection(c -> {
 550                     ArrayBlockingQueue<Integer> abq = new ArrayBlockingQueue<>(size);
 551                     abq.addAll(c);
 552                     return abq;
 553                 });
 554             }
 555 
 556             db.addCollection(PriorityBlockingQueue::new);
 557 
 558             db.addCollection(LinkedBlockingQueue::new);
 559 
 560             db.addCollection(LinkedTransferQueue::new);
 561 
 562             db.addCollection(ConcurrentLinkedQueue::new);
 563 
 564             db.addCollection(LinkedBlockingDeque::new);
 565 
 566             db.addCollection(CopyOnWriteArrayList::new);
 567 
 568             db.addCollection(CopyOnWriteArraySet::new);
 569 
 570             if (size == 0) {
 571                 db.addCollection(c -> Collections.<Integer>emptySet());
 572                 db.addList(c -> Collections.<Integer>emptyList());
 573             }
 574             else if (size == 1) {
 575                 db.addCollection(c -> Collections.singleton(exp.get(0)));
 576                 db.addCollection(c -> Collections.singletonList(exp.get(0)));
 577             }
 578 
 579             {
 580                 Integer[] ai = new Integer[size];
 581                 Arrays.fill(ai, 1);
 582                 db.add(String.format("Collections.nCopies(%d, 1)", exp.size()),
 583                        Arrays.asList(ai),
 584                        () -> Collections.nCopies(exp.size(), 1).spliterator());
 585             }
 586 
 587             // Collections.synchronized/unmodifiable/checked wrappers
 588             db.addCollection(Collections::unmodifiableCollection);
 589             db.addCollection(c -> Collections.unmodifiableSet(new HashSet<>(c)));
 590             db.addCollection(c -> Collections.unmodifiableSortedSet(new TreeSet<>(c)));
 591             db.addList(c -> Collections.unmodifiableList(new ArrayList<>(c)));
 592             db.addMap(Collections::unmodifiableMap);
 593             db.addMap(m -> Collections.unmodifiableSortedMap(new TreeMap<>(m)));
 594 
 595             db.addCollection(Collections::synchronizedCollection);
 596             db.addCollection(c -> Collections.synchronizedSet(new HashSet<>(c)));
 597             db.addCollection(c -> Collections.synchronizedSortedSet(new TreeSet<>(c)));
 598             db.addList(c -> Collections.synchronizedList(new ArrayList<>(c)));
 599             db.addMap(Collections::synchronizedMap);
 600             db.addMap(m -> Collections.synchronizedSortedMap(new TreeMap<>(m)));
 601 
 602             db.addCollection(c -> Collections.checkedCollection(c, Integer.class));
 603             db.addCollection(c -> Collections.checkedQueue(new ArrayDeque<>(c), Integer.class));
 604             db.addCollection(c -> Collections.checkedSet(new HashSet<>(c), Integer.class));
 605             db.addCollection(c -> Collections.checkedSortedSet(new TreeSet<>(c), Integer.class));
 606             db.addList(c -> Collections.checkedList(new ArrayList<>(c), Integer.class));
 607             db.addMap(c -> Collections.checkedMap(c, Integer.class, Integer.class));
 608             db.addMap(m -> Collections.checkedSortedMap(new TreeMap<>(m), Integer.class, Integer.class));
 609 
 610             // Maps
 611 
 612             db.addMap(HashMap::new);
 613 
 614             db.addMap(m -> {
 615                 // Create a Map ensuring that for large sizes
 616                 // buckets will contain 2 or more entries
 617                 HashMap<Integer, Integer> cm = new HashMap<>(1, m.size() + 1);
 618                 // Don't use putAll which inflates the table by
 619                 // m.size() * loadFactor, thus creating a very sparse
 620                 // map for 1000 entries defeating the purpose of this test,
 621                 // in addition it will cause the split until null test to fail
 622                 // because the number of valid splits is larger than the
 623                 // threshold
 624                 for (Map.Entry<Integer, Integer> e : m.entrySet())
 625                     cm.put(e.getKey(), e.getValue());
 626                 return cm;
 627             }, "new java.util.HashMap(1, size + 1)");
 628 
 629             db.addMap(LinkedHashMap::new);
 630 
 631             db.addMap(IdentityHashMap::new);
 632 
 633             db.addMap(WeakHashMap::new);
 634 
 635             db.addMap(m -> {
 636                 // Create a Map ensuring that for large sizes
 637                 // buckets will be consist of 2 or more entries
 638                 WeakHashMap<Integer, Integer> cm = new WeakHashMap<>(1, m.size() + 1);
 639                 for (Map.Entry<Integer, Integer> e : m.entrySet())
 640                     cm.put(e.getKey(), e.getValue());
 641                 return cm;
 642             }, "new java.util.WeakHashMap(1, size + 1)");
 643 
 644             // @@@  Descending maps etc
 645             db.addMap(TreeMap::new);
 646 
 647             db.addMap(ConcurrentHashMap::new);
 648 
 649             db.addMap(ConcurrentSkipListMap::new);
 650 
 651             if (size == 0) {
 652                 db.addMap(m -> Collections.<Integer, Integer>emptyMap());
 653             }
 654             else if (size == 1) {
 655                 db.addMap(m -> Collections.singletonMap(exp.get(0), exp.get(0)));
 656             }
 657         }
 658 
 659         return spliteratorDataProvider = data.toArray(new Object[0][]);
 660     }
 661 
 662     private static List<Integer> listIntRange(int upTo) {
 663         List<Integer> exp = new ArrayList<>();
 664         for (int i = 0; i < upTo; i++)
 665             exp.add(i);
 666         return Collections.unmodifiableList(exp);
 667     }
 668 
 669     @Test(dataProvider = "Spliterator<Integer>")
 670     public void testNullPointerException(String description, Collection<Integer> exp, Supplier<Spliterator<Integer>> s) {
 671         executeAndCatch(NullPointerException.class, () -> s.get().forEachRemaining(null));
 672         executeAndCatch(NullPointerException.class, () -> s.get().tryAdvance(null));
 673     }
 674 
 675     @Test(dataProvider = "Spliterator<Integer>")
 676     public void testForEach(String description, Collection<Integer> exp, Supplier<Spliterator<Integer>> s) {
 677         testForEach(exp, s, UnaryOperator.identity());
 678     }
 679 
 680     @Test(dataProvider = "Spliterator<Integer>")
 681     public void testTryAdvance(String description, Collection<Integer> exp, Supplier<Spliterator<Integer>> s) {
 682         testTryAdvance(exp, s, UnaryOperator.identity());
 683     }
 684 
 685     @Test(dataProvider = "Spliterator<Integer>")
 686     public void testMixedTryAdvanceForEach(String description, Collection<Integer> exp, Supplier<Spliterator<Integer>> s) {
 687         testMixedTryAdvanceForEach(exp, s, UnaryOperator.identity());
 688     }
 689 
 690     @Test(dataProvider = "Spliterator<Integer>")
 691     public void testMixedTraverseAndSplit(String description, Collection<Integer> exp, Supplier<Spliterator<Integer>> s) {
 692         testMixedTraverseAndSplit(exp, s, UnaryOperator.identity());
 693     }
 694 
 695     @Test(dataProvider = "Spliterator<Integer>")
 696     public void testSplitAfterFullTraversal(String description, Collection<Integer> exp, Supplier<Spliterator<Integer>> s) {
 697         testSplitAfterFullTraversal(s, UnaryOperator.identity());
 698     }
 699 
 700     @Test(dataProvider = "Spliterator<Integer>")
 701     public void testSplitOnce(String description, Collection<Integer> exp, Supplier<Spliterator<Integer>> s) {
 702         testSplitOnce(exp, s, UnaryOperator.identity());
 703     }
 704 
 705     @Test(dataProvider = "Spliterator<Integer>")
 706     public void testSplitSixDeep(String description, Collection<Integer> exp, Supplier<Spliterator<Integer>> s) {
 707         testSplitSixDeep(exp, s, UnaryOperator.identity());
 708     }
 709 
 710     @Test(dataProvider = "Spliterator<Integer>")
 711     public void testSplitUntilNull(String description, Collection<Integer> exp, Supplier<Spliterator<Integer>> s) {
 712         testSplitUntilNull(exp, s, UnaryOperator.identity());
 713     }
 714 
 715     //
 716 
 717     private static class SpliteratorOfIntDataBuilder {
 718         List<Object[]> data;
 719 
 720         List<Integer> exp;
 721 
 722         SpliteratorOfIntDataBuilder(List<Object[]> data, List<Integer> exp) {
 723             this.data = data;
 724             this.exp = exp;
 725         }
 726 
 727         void add(String description, List<Integer> expected, Supplier<Spliterator.OfInt> s) {
 728             description = joiner(description).toString();
 729             data.add(new Object[]{description, expected, s});
 730         }
 731 
 732         void add(String description, Supplier<Spliterator.OfInt> s) {
 733             add(description, exp, s);
 734         }
 735 
 736         StringBuilder joiner(String description) {
 737             return new StringBuilder(description).
 738                     append(" {").
 739                     append("size=").append(exp.size()).
 740                     append("}");
 741         }
 742     }
 743 
 744     private static class SpliteratorOfIntCharDataBuilder {
 745         List<Object[]> data;
 746 
 747         String s;
 748 
 749         List<Integer> expChars;
 750 
 751         List<Integer> expCodePoints;
 752 
 753         SpliteratorOfIntCharDataBuilder(List<Object[]> data, String s) {
 754             this.data = data;
 755             this.s = s;
 756             this.expChars = transform(s, false);
 757             this.expCodePoints = transform(s, true);
 758         }
 759 
 760         static List<Integer> transform(String s, boolean toCodePoints) {
 761             List<Integer> l = new ArrayList<>();
 762 
 763             if (!toCodePoints) {
 764                 for (int i = 0; i < s.length(); i++) {
 765                     l.add((int) s.charAt(i));
 766                 }
 767             }
 768             else {
 769                 for (int i = 0; i < s.length();) {
 770                     char c1 = s.charAt(i++);
 771                     int cp = c1;
 772                     if (Character.isHighSurrogate(c1) && i < s.length()) {
 773                         char c2 = s.charAt(i);
 774                         if (Character.isLowSurrogate(c2)) {
 775                             i++;
 776                             cp = Character.toCodePoint(c1, c2);
 777                         }
 778                     }
 779                     l.add(cp);
 780                 }
 781             }
 782             return l;
 783         }
 784 
 785         void add(String description, Function<String, CharSequence> f) {
 786             description = description.replace("%s", s);
 787             {
 788                 Supplier<Spliterator.OfInt> supplier = () -> f.apply(s).chars().spliterator();
 789                 data.add(new Object[]{description + ".chars().spliterator()", expChars, supplier});
 790             }
 791             {
 792                 Supplier<Spliterator.OfInt> supplier = () -> f.apply(s).codePoints().spliterator();
 793                 data.add(new Object[]{description + ".codePoints().spliterator()", expCodePoints, supplier});
 794             }
 795         }
 796     }
 797 
 798     static Object[][] spliteratorOfIntDataProvider;
 799 
 800     @DataProvider(name = "Spliterator.OfInt")
 801     public static Object[][] spliteratorOfIntDataProvider() {
 802         if (spliteratorOfIntDataProvider != null) {
 803             return spliteratorOfIntDataProvider;
 804         }
 805 
 806         List<Object[]> data = new ArrayList<>();
 807         for (int size : SIZES) {
 808             int exp[] = arrayIntRange(size);
 809             SpliteratorOfIntDataBuilder db = new SpliteratorOfIntDataBuilder(data, listIntRange(size));
 810 
 811             db.add("Spliterators.spliterator(int[], ...)",
 812                    () -> Spliterators.spliterator(exp, 0));
 813 
 814             db.add("Arrays.spliterator(int[], ...)",
 815                    () -> Arrays.spliterator(exp));
 816 
 817             db.add("Spliterators.spliterator(PrimitiveIterator.OfInt, ...)",
 818                    () -> Spliterators.spliterator(Spliterators.iterator(Arrays.spliterator(exp)), exp.length, 0));
 819 
 820             db.add("Spliterators.spliteratorUnknownSize(PrimitiveIterator.OfInt, ...)",
 821                    () -> Spliterators.spliteratorUnknownSize(Spliterators.iterator(Arrays.spliterator(exp)), 0));
 822 
 823             class IntSpliteratorFromArray extends Spliterators.AbstractIntSpliterator {
 824                 int[] a;
 825                 int index = 0;
 826 
 827                 IntSpliteratorFromArray(int[] a) {
 828                     super(a.length, Spliterator.SIZED);
 829                     this.a = a;
 830                 }
 831 
 832                 @Override
 833                 public boolean tryAdvance(IntConsumer action) {
 834                     if (action == null)
 835                         throw new NullPointerException();
 836                     if (index < a.length) {
 837                         action.accept(a[index++]);
 838                         return true;
 839                     }
 840                     else {
 841                         return false;
 842                     }
 843                 }
 844             }
 845             db.add("new Spliterators.AbstractIntAdvancingSpliterator()",
 846                    () -> new IntSpliteratorFromArray(exp));
 847         }
 848 
 849         // Class for testing default methods
 850         class CharSequenceImpl implements CharSequence {
 851             final String s;
 852 
 853             public CharSequenceImpl(String s) {
 854                 this.s = s;
 855             }
 856 
 857             @Override
 858             public int length() {
 859                 return s.length();
 860             }
 861 
 862             @Override
 863             public char charAt(int index) {
 864                 return s.charAt(index);
 865             }
 866 
 867             @Override
 868             public CharSequence subSequence(int start, int end) {
 869                 return s.subSequence(start, end);
 870             }
 871 
 872             @Override
 873             public String toString() {
 874                 return s;
 875             }
 876         }
 877 
 878         for (String string : STRINGS) {
 879             SpliteratorOfIntCharDataBuilder cdb = new SpliteratorOfIntCharDataBuilder(data, string);
 880             cdb.add("\"%s\"", s -> s);
 881             cdb.add("new CharSequenceImpl(\"%s\")", CharSequenceImpl::new);
 882             cdb.add("new StringBuilder(\"%s\")", StringBuilder::new);
 883             cdb.add("new StringBuffer(\"%s\")", StringBuffer::new);
 884             cdb.add("CharBuffer.wrap(\"%s\".toCharArray())", s -> CharBuffer.wrap(s.toCharArray()));
 885         }
 886 
 887 
 888         Object[][] bitStreamTestcases = new Object[][] {
 889                 { "none", IntStream.empty().toArray() },
 890                 { "index 0", IntStream.of(0).toArray() },
 891                 { "index 255", IntStream.of(255).toArray() },
 892                 { "index 0 and 255", IntStream.of(0, 255).toArray() },
 893                 { "every bit", IntStream.range(0, 255).toArray() },
 894                 { "step 2", IntStream.range(0, 255).map(f -> f * 2).toArray() },
 895                 { "step 3", IntStream.range(0, 255).map(f -> f * 3).toArray() },
 896                 { "step 5", IntStream.range(0, 255).map(f -> f * 5).toArray() },
 897                 { "step 7", IntStream.range(0, 255).map(f -> f * 7).toArray() },
 898                 { "1, 10, 100, 1000", IntStream.of(1, 10, 100, 1000).toArray() },
 899         };
 900         for (Object[] tc : bitStreamTestcases) {
 901             String description = (String)tc[0];
 902             int[] exp = (int[])tc[1];
 903             SpliteratorOfIntDataBuilder db = new SpliteratorOfIntDataBuilder(
 904                     data, IntStream.of(exp).boxed().collect(toList()));
 905 
 906             db.add("BitSet.stream.spliterator() {" + description + "}", () ->
 907                 IntStream.of(exp).collect(BitSet::new, BitSet::set, BitSet::or).
 908                         stream().spliterator()
 909             );
 910         }
 911         return spliteratorOfIntDataProvider = data.toArray(new Object[0][]);
 912     }
 913 
 914     private static int[] arrayIntRange(int upTo) {
 915         int[] exp = new int[upTo];
 916         for (int i = 0; i < upTo; i++)
 917             exp[i] = i;
 918         return exp;
 919     }
 920 
 921     @Test(dataProvider = "Spliterator.OfInt")
 922     public void testIntNullPointerException(String description, Collection<Integer> exp, Supplier<Spliterator.OfInt> s) {
 923         executeAndCatch(NullPointerException.class, () -> s.get().forEachRemaining((IntConsumer) null));
 924         executeAndCatch(NullPointerException.class, () -> s.get().tryAdvance((IntConsumer) null));
 925     }
 926 
 927     @Test(dataProvider = "Spliterator.OfInt")
 928     public void testIntForEach(String description, Collection<Integer> exp, Supplier<Spliterator.OfInt> s) {
 929         testForEach(exp, s, intBoxingConsumer());
 930     }
 931 
 932     @Test(dataProvider = "Spliterator.OfInt")
 933     public void testIntTryAdvance(String description, Collection<Integer> exp, Supplier<Spliterator.OfInt> s) {
 934         testTryAdvance(exp, s, intBoxingConsumer());
 935     }
 936 
 937     @Test(dataProvider = "Spliterator.OfInt")
 938     public void testIntMixedTryAdvanceForEach(String description, Collection<Integer> exp, Supplier<Spliterator.OfInt> s) {
 939         testMixedTryAdvanceForEach(exp, s, intBoxingConsumer());
 940     }
 941 
 942     @Test(dataProvider = "Spliterator.OfInt")
 943     public void testIntMixedTraverseAndSplit(String description, Collection<Integer> exp, Supplier<Spliterator.OfInt> s) {
 944         testMixedTraverseAndSplit(exp, s, intBoxingConsumer());
 945     }
 946 
 947     @Test(dataProvider = "Spliterator.OfInt")
 948     public void testIntSplitAfterFullTraversal(String description, Collection<Integer> exp, Supplier<Spliterator.OfInt> s) {
 949         testSplitAfterFullTraversal(s, intBoxingConsumer());
 950     }
 951 
 952     @Test(dataProvider = "Spliterator.OfInt")
 953     public void testIntSplitOnce(String description, Collection<Integer> exp, Supplier<Spliterator.OfInt> s) {
 954         testSplitOnce(exp, s, intBoxingConsumer());
 955     }
 956 
 957     @Test(dataProvider = "Spliterator.OfInt")
 958     public void testIntSplitSixDeep(String description, Collection<Integer> exp, Supplier<Spliterator.OfInt> s) {
 959         testSplitSixDeep(exp, s, intBoxingConsumer());
 960     }
 961 
 962     @Test(dataProvider = "Spliterator.OfInt")
 963     public void testIntSplitUntilNull(String description, Collection<Integer> exp, Supplier<Spliterator.OfInt> s) {
 964         testSplitUntilNull(exp, s, intBoxingConsumer());
 965     }
 966 
 967     //
 968 
 969     private static class SpliteratorOfLongDataBuilder {
 970         List<Object[]> data;
 971 
 972         List<Long> exp;
 973 
 974         SpliteratorOfLongDataBuilder(List<Object[]> data, List<Long> exp) {
 975             this.data = data;
 976             this.exp = exp;
 977         }
 978 
 979         void add(String description, List<Long> expected, Supplier<Spliterator.OfLong> s) {
 980             description = joiner(description).toString();
 981             data.add(new Object[]{description, expected, s});
 982         }
 983 
 984         void add(String description, Supplier<Spliterator.OfLong> s) {
 985             add(description, exp, s);
 986         }
 987 
 988         StringBuilder joiner(String description) {
 989             return new StringBuilder(description).
 990                     append(" {").
 991                     append("size=").append(exp.size()).
 992                     append("}");
 993         }
 994     }
 995 
 996     static Object[][] spliteratorOfLongDataProvider;
 997 
 998     @DataProvider(name = "Spliterator.OfLong")
 999     public static Object[][] spliteratorOfLongDataProvider() {
1000         if (spliteratorOfLongDataProvider != null) {
1001             return spliteratorOfLongDataProvider;
1002         }
1003 
1004         List<Object[]> data = new ArrayList<>();
1005         for (int size : SIZES) {
1006             long exp[] = arrayLongRange(size);
1007             SpliteratorOfLongDataBuilder db = new SpliteratorOfLongDataBuilder(data, listLongRange(size));
1008 
1009             db.add("Spliterators.spliterator(long[], ...)",
1010                    () -> Spliterators.spliterator(exp, 0));
1011 
1012             db.add("Arrays.spliterator(long[], ...)",
1013                    () -> Arrays.spliterator(exp));
1014 
1015             db.add("Spliterators.spliterator(PrimitiveIterator.OfLong, ...)",
1016                    () -> Spliterators.spliterator(Spliterators.iterator(Arrays.spliterator(exp)), exp.length, 0));
1017 
1018             db.add("Spliterators.spliteratorUnknownSize(PrimitiveIterator.OfLong, ...)",
1019                    () -> Spliterators.spliteratorUnknownSize(Spliterators.iterator(Arrays.spliterator(exp)), 0));
1020 
1021             class LongSpliteratorFromArray extends Spliterators.AbstractLongSpliterator {
1022                 long[] a;
1023                 int index = 0;
1024 
1025                 LongSpliteratorFromArray(long[] a) {
1026                     super(a.length, Spliterator.SIZED);
1027                     this.a = a;
1028                 }
1029 
1030                 @Override
1031                 public boolean tryAdvance(LongConsumer action) {
1032                     if (action == null)
1033                         throw new NullPointerException();
1034                     if (index < a.length) {
1035                         action.accept(a[index++]);
1036                         return true;
1037                     }
1038                     else {
1039                         return false;
1040                     }
1041                 }
1042             }
1043             db.add("new Spliterators.AbstractLongAdvancingSpliterator()",
1044                    () -> new LongSpliteratorFromArray(exp));
1045         }
1046 
1047         return spliteratorOfLongDataProvider = data.toArray(new Object[0][]);
1048     }
1049 
1050     private static List<Long> listLongRange(int upTo) {
1051         List<Long> exp = new ArrayList<>();
1052         for (long i = 0; i < upTo; i++)
1053             exp.add(i);
1054         return Collections.unmodifiableList(exp);
1055     }
1056 
1057     private static long[] arrayLongRange(int upTo) {
1058         long[] exp = new long[upTo];
1059         for (int i = 0; i < upTo; i++)
1060             exp[i] = i;
1061         return exp;
1062     }
1063 
1064     @Test(dataProvider = "Spliterator.OfLong")
1065     public void testLongNullPointerException(String description, Collection<Long> exp, Supplier<Spliterator.OfLong> s) {
1066         executeAndCatch(NullPointerException.class, () -> s.get().forEachRemaining((LongConsumer) null));
1067         executeAndCatch(NullPointerException.class, () -> s.get().tryAdvance((LongConsumer) null));
1068     }
1069 
1070     @Test(dataProvider = "Spliterator.OfLong")
1071     public void testLongForEach(String description, Collection<Long> exp, Supplier<Spliterator.OfLong> s) {
1072         testForEach(exp, s, longBoxingConsumer());
1073     }
1074 
1075     @Test(dataProvider = "Spliterator.OfLong")
1076     public void testLongTryAdvance(String description, Collection<Long> exp, Supplier<Spliterator.OfLong> s) {
1077         testTryAdvance(exp, s, longBoxingConsumer());
1078     }
1079 
1080     @Test(dataProvider = "Spliterator.OfLong")
1081     public void testLongMixedTryAdvanceForEach(String description, Collection<Long> exp, Supplier<Spliterator.OfLong> s) {
1082         testMixedTryAdvanceForEach(exp, s, longBoxingConsumer());
1083     }
1084 
1085     @Test(dataProvider = "Spliterator.OfLong")
1086     public void testLongMixedTraverseAndSplit(String description, Collection<Long> exp, Supplier<Spliterator.OfLong> s) {
1087         testMixedTraverseAndSplit(exp, s, longBoxingConsumer());
1088     }
1089 
1090     @Test(dataProvider = "Spliterator.OfLong")
1091     public void testLongSplitAfterFullTraversal(String description, Collection<Long> exp, Supplier<Spliterator.OfLong> s) {
1092         testSplitAfterFullTraversal(s, longBoxingConsumer());
1093     }
1094 
1095     @Test(dataProvider = "Spliterator.OfLong")
1096     public void testLongSplitOnce(String description, Collection<Long> exp, Supplier<Spliterator.OfLong> s) {
1097         testSplitOnce(exp, s, longBoxingConsumer());
1098     }
1099 
1100     @Test(dataProvider = "Spliterator.OfLong")
1101     public void testLongSplitSixDeep(String description, Collection<Long> exp, Supplier<Spliterator.OfLong> s) {
1102         testSplitSixDeep(exp, s, longBoxingConsumer());
1103     }
1104 
1105     @Test(dataProvider = "Spliterator.OfLong")
1106     public void testLongSplitUntilNull(String description, Collection<Long> exp, Supplier<Spliterator.OfLong> s) {
1107         testSplitUntilNull(exp, s, longBoxingConsumer());
1108     }
1109 
1110     //
1111 
1112     private static class SpliteratorOfDoubleDataBuilder {
1113         List<Object[]> data;
1114 
1115         List<Double> exp;
1116 
1117         SpliteratorOfDoubleDataBuilder(List<Object[]> data, List<Double> exp) {
1118             this.data = data;
1119             this.exp = exp;
1120         }
1121 
1122         void add(String description, List<Double> expected, Supplier<Spliterator.OfDouble> s) {
1123             description = joiner(description).toString();
1124             data.add(new Object[]{description, expected, s});
1125         }
1126 
1127         void add(String description, Supplier<Spliterator.OfDouble> s) {
1128             add(description, exp, s);
1129         }
1130 
1131         StringBuilder joiner(String description) {
1132             return new StringBuilder(description).
1133                     append(" {").
1134                     append("size=").append(exp.size()).
1135                     append("}");
1136         }
1137     }
1138 
1139     static Object[][] spliteratorOfDoubleDataProvider;
1140 
1141     @DataProvider(name = "Spliterator.OfDouble")
1142     public static Object[][] spliteratorOfDoubleDataProvider() {
1143         if (spliteratorOfDoubleDataProvider != null) {
1144             return spliteratorOfDoubleDataProvider;
1145         }
1146 
1147         List<Object[]> data = new ArrayList<>();
1148         for (int size : SIZES) {
1149             double exp[] = arrayDoubleRange(size);
1150             SpliteratorOfDoubleDataBuilder db = new SpliteratorOfDoubleDataBuilder(data, listDoubleRange(size));
1151 
1152             db.add("Spliterators.spliterator(double[], ...)",
1153                    () -> Spliterators.spliterator(exp, 0));
1154 
1155             db.add("Arrays.spliterator(double[], ...)",
1156                    () -> Arrays.spliterator(exp));
1157 
1158             db.add("Spliterators.spliterator(PrimitiveIterator.OfDouble, ...)",
1159                    () -> Spliterators.spliterator(Spliterators.iterator(Arrays.spliterator(exp)), exp.length, 0));
1160 
1161             db.add("Spliterators.spliteratorUnknownSize(PrimitiveIterator.OfDouble, ...)",
1162                    () -> Spliterators.spliteratorUnknownSize(Spliterators.iterator(Arrays.spliterator(exp)), 0));
1163 
1164             class DoubleSpliteratorFromArray extends Spliterators.AbstractDoubleSpliterator {
1165                 double[] a;
1166                 int index = 0;
1167 
1168                 DoubleSpliteratorFromArray(double[] a) {
1169                     super(a.length, Spliterator.SIZED);
1170                     this.a = a;
1171                 }
1172 
1173                 @Override
1174                 public boolean tryAdvance(DoubleConsumer action) {
1175                     if (action == null)
1176                         throw new NullPointerException();
1177                     if (index < a.length) {
1178                         action.accept(a[index++]);
1179                         return true;
1180                     }
1181                     else {
1182                         return false;
1183                     }
1184                 }
1185             }
1186             db.add("new Spliterators.AbstractDoubleAdvancingSpliterator()",
1187                    () -> new DoubleSpliteratorFromArray(exp));
1188         }
1189 
1190         return spliteratorOfDoubleDataProvider = data.toArray(new Object[0][]);
1191     }
1192 
1193     private static List<Double> listDoubleRange(int upTo) {
1194         List<Double> exp = new ArrayList<>();
1195         for (double i = 0; i < upTo; i++)
1196             exp.add(i);
1197         return Collections.unmodifiableList(exp);
1198     }
1199 
1200     private static double[] arrayDoubleRange(int upTo) {
1201         double[] exp = new double[upTo];
1202         for (int i = 0; i < upTo; i++)
1203             exp[i] = i;
1204         return exp;
1205     }
1206 
1207     @Test(dataProvider = "Spliterator.OfDouble")
1208     public void testDoubleNullPointerException(String description, Collection<Double> exp, Supplier<Spliterator.OfDouble> s) {
1209         executeAndCatch(NullPointerException.class, () -> s.get().forEachRemaining((DoubleConsumer) null));
1210         executeAndCatch(NullPointerException.class, () -> s.get().tryAdvance((DoubleConsumer) null));
1211     }
1212 
1213     @Test(dataProvider = "Spliterator.OfDouble")
1214     public void testDoubleForEach(String description, Collection<Double> exp, Supplier<Spliterator.OfDouble> s) {
1215         testForEach(exp, s, doubleBoxingConsumer());
1216     }
1217 
1218     @Test(dataProvider = "Spliterator.OfDouble")
1219     public void testDoubleTryAdvance(String description, Collection<Double> exp, Supplier<Spliterator.OfDouble> s) {
1220         testTryAdvance(exp, s, doubleBoxingConsumer());
1221     }
1222 
1223     @Test(dataProvider = "Spliterator.OfDouble")
1224     public void testDoubleMixedTryAdvanceForEach(String description, Collection<Double> exp, Supplier<Spliterator.OfDouble> s) {
1225         testMixedTryAdvanceForEach(exp, s, doubleBoxingConsumer());
1226     }
1227 
1228     @Test(dataProvider = "Spliterator.OfDouble")
1229     public void testDoubleMixedTraverseAndSplit(String description, Collection<Double> exp, Supplier<Spliterator.OfDouble> s) {
1230         testMixedTraverseAndSplit(exp, s, doubleBoxingConsumer());
1231     }
1232 
1233     @Test(dataProvider = "Spliterator.OfDouble")
1234     public void testDoubleSplitAfterFullTraversal(String description, Collection<Double> exp, Supplier<Spliterator.OfDouble> s) {
1235         testSplitAfterFullTraversal(s, doubleBoxingConsumer());
1236     }
1237 
1238     @Test(dataProvider = "Spliterator.OfDouble")
1239     public void testDoubleSplitOnce(String description, Collection<Double> exp, Supplier<Spliterator.OfDouble> s) {
1240         testSplitOnce(exp, s, doubleBoxingConsumer());
1241     }
1242 
1243     @Test(dataProvider = "Spliterator.OfDouble")
1244     public void testDoubleSplitSixDeep(String description, Collection<Double> exp, Supplier<Spliterator.OfDouble> s) {
1245         testSplitSixDeep(exp, s, doubleBoxingConsumer());
1246     }
1247 
1248     @Test(dataProvider = "Spliterator.OfDouble")
1249     public void testDoubleSplitUntilNull(String description, Collection<Double> exp, Supplier<Spliterator.OfDouble> s) {
1250         testSplitUntilNull(exp, s, doubleBoxingConsumer());
1251     }
1252 
1253 }