1 /*
   2  * Copyright (c) 2012, 2016, 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  * @bug 8148838
  27  */
  28 
  29 package org.openjdk.tests.java.util.stream;
  30 
  31 import java.util.Arrays;
  32 import java.util.Comparator;
  33 import java.util.List;
  34 import java.util.Spliterator;
  35 import java.util.function.Consumer;
  36 import java.util.function.DoubleConsumer;
  37 import java.util.function.Function;
  38 import java.util.function.IntConsumer;
  39 import java.util.function.LongConsumer;
  40 import java.util.function.UnaryOperator;
  41 import java.util.stream.DoubleStream;
  42 import java.util.stream.DoubleStreamTestDataProvider;
  43 import java.util.stream.IntStream;
  44 import java.util.stream.IntStreamTestDataProvider;
  45 import java.util.stream.LambdaTestHelpers;
  46 import java.util.stream.LongStream;
  47 import java.util.stream.LongStreamTestDataProvider;
  48 import java.util.stream.OpTestCase;
  49 import java.util.stream.SpliteratorTestHelper;
  50 import java.util.stream.Stream;
  51 import java.util.stream.StreamSupport;
  52 import java.util.stream.StreamTestDataProvider;
  53 import java.util.stream.TestData;
  54 
  55 import org.testng.Assert;
  56 import org.testng.annotations.Test;
  57 
  58 import static java.util.stream.LambdaTestHelpers.countTo;
  59 import static java.util.stream.LambdaTestHelpers.dpEven;
  60 import static java.util.stream.LambdaTestHelpers.ipEven;
  61 import static java.util.stream.LambdaTestHelpers.irDoubler;
  62 import static java.util.stream.LambdaTestHelpers.lpEven;
  63 import static java.util.stream.LambdaTestHelpers.mDoubler;
  64 import static java.util.stream.LambdaTestHelpers.pEven;
  65 import static java.util.stream.LambdaTestHelpers.permuteStreamFunctions;
  66 
  67 @Test
  68 public class StreamSpliteratorTest extends OpTestCase {
  69 
  70     private static class ProxyNoExactSizeSpliterator<T> implements Spliterator<T> {
  71         final Spliterator<T> sp;
  72         final boolean proxyEstimateSize;
  73         int splits = 0;
  74         int prefixSplits = 0;
  75 
  76         long sizeOnTraversal = -1;
  77 
  78         ProxyNoExactSizeSpliterator(Spliterator<T> sp, boolean proxyEstimateSize) {
  79             this.sp = sp;
  80             this.proxyEstimateSize = proxyEstimateSize;
  81         }
  82 
  83         @Override
  84         public Spliterator<T> trySplit() {
  85             splits++;
  86             Spliterator<T> prefix = sp.trySplit();
  87             if (prefix != null)
  88                 prefixSplits++;
  89             return prefix;
  90         }
  91 
  92         @Override
  93         public boolean tryAdvance(Consumer<? super T> consumer) {
  94             if (sizeOnTraversal == -1)
  95                 sizeOnTraversal = sp.getExactSizeIfKnown();
  96             return sp.tryAdvance(consumer);
  97         }
  98 
  99         @Override
 100         public void forEachRemaining(Consumer<? super T> consumer) {
 101             sizeOnTraversal = sp.getExactSizeIfKnown();
 102             sp.forEachRemaining(consumer);
 103         }
 104 
 105         @Override
 106         public long estimateSize() {
 107             return proxyEstimateSize ? sp.estimateSize() : Long.MAX_VALUE;
 108         }
 109 
 110         @Override
 111         public Comparator<? super T> getComparator() {
 112             return sp.getComparator();
 113         }
 114 
 115         @Override
 116         public int characteristics() {
 117             if (proxyEstimateSize)
 118                 return sp.characteristics();
 119             else
 120                 return sp.characteristics() & ~(Spliterator.SUBSIZED | Spliterator.SIZED);
 121         }
 122 
 123         private static class OfInt extends ProxyNoExactSizeSpliterator<Integer> implements Spliterator.OfInt {
 124             final Spliterator.OfInt psp;
 125 
 126             private OfInt(Spliterator.OfInt sp, boolean proxyEstimateSize) {
 127                 super(sp, proxyEstimateSize);
 128                 this.psp = sp;
 129             }
 130 
 131             @Override
 132             public Spliterator.OfInt trySplit() {
 133                 splits++;
 134                 Spliterator.OfInt prefix = psp.trySplit();
 135                 if (prefix != null)
 136                     prefixSplits++;
 137                 return prefix;
 138             }
 139 
 140             @Override
 141             public boolean tryAdvance(Consumer<? super Integer> consumer) {
 142                 return Spliterator.OfInt.super.tryAdvance(consumer);
 143             }
 144 
 145             @Override
 146             public void forEachRemaining(Consumer<? super Integer> consumer) {
 147                 Spliterator.OfInt.super.forEachRemaining(consumer);
 148             }
 149 
 150             @Override
 151             public boolean tryAdvance(IntConsumer consumer) {
 152                 if (sizeOnTraversal == -1)
 153                     sizeOnTraversal = sp.getExactSizeIfKnown();
 154                 return psp.tryAdvance(consumer);
 155             }
 156 
 157             @Override
 158             public void forEachRemaining(IntConsumer consumer) {
 159                 sizeOnTraversal = sp.getExactSizeIfKnown();
 160                 psp.forEachRemaining(consumer);
 161             }
 162         }
 163 
 164         private static class OfLong extends ProxyNoExactSizeSpliterator<Long> implements Spliterator.OfLong {
 165             final Spliterator.OfLong psp;
 166 
 167             private OfLong(Spliterator.OfLong sp, boolean proxyEstimateSize) {
 168                 super(sp, proxyEstimateSize);
 169                 this.psp = sp;
 170             }
 171 
 172             @Override
 173             public Spliterator.OfLong trySplit() {
 174                 splits++;
 175                 Spliterator.OfLong prefix = psp.trySplit();
 176                 if (prefix != null)
 177                     prefixSplits++;
 178                 return prefix;
 179             }
 180 
 181             @Override
 182             public boolean tryAdvance(Consumer<? super Long> consumer) {
 183                 return Spliterator.OfLong.super.tryAdvance(consumer);
 184             }
 185 
 186             @Override
 187             public void forEachRemaining(Consumer<? super Long> consumer) {
 188                 Spliterator.OfLong.super.forEachRemaining(consumer);
 189             }
 190 
 191             @Override
 192             public boolean tryAdvance(LongConsumer consumer) {
 193                 if (sizeOnTraversal == -1)
 194                     sizeOnTraversal = sp.getExactSizeIfKnown();
 195                 return psp.tryAdvance(consumer);
 196             }
 197 
 198             @Override
 199             public void forEachRemaining(LongConsumer consumer) {
 200                 sizeOnTraversal = sp.getExactSizeIfKnown();
 201                 psp.forEachRemaining(consumer);
 202             }
 203         }
 204 
 205         private static class OfDouble extends ProxyNoExactSizeSpliterator<Double>
 206                 implements Spliterator.OfDouble {
 207             final Spliterator.OfDouble psp;
 208 
 209             private OfDouble(Spliterator.OfDouble sp, boolean proxyEstimateSize) {
 210                 super(sp, proxyEstimateSize);
 211                 this.psp = sp;
 212             }
 213 
 214             @Override
 215             public Spliterator.OfDouble trySplit() {
 216                 splits++;
 217                 Spliterator.OfDouble prefix = psp.trySplit();
 218                 if (prefix != null)
 219                     prefixSplits++;
 220                 return prefix;
 221             }
 222 
 223             @Override
 224             public boolean tryAdvance(Consumer<? super Double> consumer) {
 225                 return Spliterator.OfDouble.super.tryAdvance(consumer);
 226             }
 227 
 228             @Override
 229             public void forEachRemaining(Consumer<? super Double> consumer) {
 230                 Spliterator.OfDouble.super.forEachRemaining(consumer);
 231             }
 232 
 233             @Override
 234             public boolean tryAdvance(DoubleConsumer consumer) {
 235                 if (sizeOnTraversal == -1)
 236                     sizeOnTraversal = sp.getExactSizeIfKnown();
 237                 return psp.tryAdvance(consumer);
 238             }
 239 
 240             @Override
 241             public void forEachRemaining(DoubleConsumer consumer) {
 242                 sizeOnTraversal = sp.getExactSizeIfKnown();
 243                 psp.forEachRemaining(consumer);
 244             }
 245         }
 246     }
 247 
 248     public void testSplitting() {
 249         // Size is assumed to be larger than the target size for no splitting
 250         // @@@ Need way to obtain the target size
 251         List<Integer> l = countTo(1000);
 252 
 253         List<Consumer<Stream<Integer>>> terminalOps = Arrays.asList(
 254                 s -> s.toArray(),
 255                 s -> s.forEach(e -> { }),
 256                 s -> s.reduce(Integer::sum)
 257         );
 258 
 259         List<UnaryOperator<Stream<Integer>>> intermediateOps = Arrays.asList(
 260                 s -> s.parallel(),
 261                 // The following ensures the wrapping spliterator is tested
 262                 s -> s.map(LambdaTestHelpers.identity()).parallel()
 263         );
 264 
 265         for (int i = 0; i < terminalOps.size(); i++) {
 266             setContext("termOpIndex", i);
 267             Consumer<Stream<Integer>> terminalOp = terminalOps.get(i);
 268             for (int j = 0; j < intermediateOps.size(); j++) {
 269                 setContext("intOpIndex", j);
 270                 UnaryOperator<Stream<Integer>> intermediateOp = intermediateOps.get(j);
 271                 for (boolean proxyEstimateSize : new boolean[] {false, true}) {
 272                     setContext("proxyEstimateSize", proxyEstimateSize);
 273                     Spliterator<Integer> sp = intermediateOp.apply(l.stream()).spliterator();
 274                     ProxyNoExactSizeSpliterator<Integer> psp = new ProxyNoExactSizeSpliterator<>(sp, proxyEstimateSize);
 275                     Stream<Integer> s = StreamSupport.stream(psp, true);
 276                     terminalOp.accept(s);
 277                     Assert.assertTrue(psp.splits > 0,
 278                                       String.format("Number of splits should be greater that zero when proxyEstimateSize is %s",
 279                                                     proxyEstimateSize));
 280                     Assert.assertTrue(psp.prefixSplits > 0,
 281                                       String.format("Number of non-null prefix splits should be greater that zero when proxyEstimateSize is %s",
 282                                                     proxyEstimateSize));
 283                     Assert.assertTrue(psp.sizeOnTraversal < l.size(),
 284                                       String.format("Size on traversal of last split should be less than the size of the list, %d, when proxyEstimateSize is %s",
 285                                                     l.size(), proxyEstimateSize));
 286                 }
 287             }
 288         }
 289     }
 290 
 291     @Test(dataProvider = "StreamTestData<Integer>.small",
 292           dataProviderClass = StreamTestDataProvider.class,
 293           groups = { "serialization-hostile" })
 294     public void testStreamSpliterators(String name, TestData.OfRef<Integer> data) {
 295         for (Function<Stream<Integer>, Stream<Integer>> f : streamFunctions()) {
 296             withData(data).
 297                     stream((Stream<Integer> in) -> {
 298                         Stream<Integer> out = f.apply(in);
 299                         return StreamSupport.stream(() -> out.spliterator(), OpTestCase.getStreamFlags(out), false);
 300                     }).
 301                     exercise();
 302 
 303             withData(data).
 304                     stream((Stream<Integer> in) -> {
 305                         Stream<Integer> out = f.apply(in);
 306                         return StreamSupport.stream(() -> out.spliterator(), OpTestCase.getStreamFlags(out), true);
 307                     }).
 308                     exercise();
 309         }
 310     }
 311 
 312     @Test(dataProvider = "StreamTestData<Integer>.small", dataProviderClass = StreamTestDataProvider.class)
 313     public void testSpliterators(String name, TestData.OfRef<Integer> data) {
 314         for (Function<Stream<Integer>, Stream<Integer>> f : streamFunctions()) {
 315             SpliteratorTestHelper.testSpliterator(() -> f.apply(data.stream()).spliterator());
 316         }
 317     }
 318 
 319     @Test(dataProvider = "StreamTestData<Integer>.small", dataProviderClass = StreamTestDataProvider.class)
 320     public void testParSpliterators(String name, TestData.OfRef<Integer> data) {
 321         for (Function<Stream<Integer>, Stream<Integer>> f : streamFunctions()) {
 322             SpliteratorTestHelper.testSpliterator(() -> f.apply(data.parallelStream()).spliterator());
 323         }
 324     }
 325 
 326     private List<Function<Stream<Integer>, Stream<Integer>>> streamFunctions;
 327 
 328     List<Function<Stream<Integer>, Stream<Integer>>> streamFunctions() {
 329         if (streamFunctions == null) {
 330             List<Function<Stream<Integer>, Stream<Integer>>> opFunctions = Arrays.asList(
 331                     s -> s.filter(pEven),
 332                     s -> s.flatMap(x -> Stream.of(x, x)),
 333                     // @@@ Add distinct once asserting results with or without order
 334                     //     is correctly supported
 335 //                    s -> s.distinct(),
 336                     s -> s.sorted());
 337 
 338             streamFunctions = permuteStreamFunctions(opFunctions);
 339         }
 340 
 341         return streamFunctions;
 342     }
 343 
 344     //
 345 
 346     public void testIntSplitting() {
 347         List<Consumer<IntStream>> terminalOps = Arrays.asList(
 348                 s -> s.toArray(),
 349                 s -> s.forEach(e -> {}),
 350                 s -> s.reduce(Integer::sum)
 351         );
 352 
 353         List<UnaryOperator<IntStream>> intermediateOps = Arrays.asList(
 354                 s -> s.parallel(),
 355                 // The following ensures the wrapping spliterator is tested
 356                 s -> s.map(i -> i).parallel()
 357         );
 358 
 359         for (int i = 0; i < terminalOps.size(); i++) {
 360             setContext("termOpIndex", i);
 361             Consumer<IntStream> terminalOp = terminalOps.get(i);
 362             for (int j = 0; j < intermediateOps.size(); j++) {
 363                 setContext("intOpIndex", j);
 364                 UnaryOperator<IntStream> intermediateOp = intermediateOps.get(j);
 365                 for (boolean proxyEstimateSize : new boolean[] {false, true}) {
 366                     setContext("proxyEstimateSize", proxyEstimateSize);
 367                     // Size is assumed to be larger than the target size for no splitting
 368                     // @@@ Need way to obtain the target size
 369                     Spliterator.OfInt sp = intermediateOp.apply(IntStream.range(0, 1000)).spliterator();
 370                     ProxyNoExactSizeSpliterator.OfInt psp = new ProxyNoExactSizeSpliterator.OfInt(sp, proxyEstimateSize);
 371                     IntStream s = StreamSupport.intStream(psp, true);
 372                     terminalOp.accept(s);
 373                     Assert.assertTrue(psp.splits > 0,
 374                                       String.format("Number of splits should be greater that zero when proxyEstimateSize is %s",
 375                                                     proxyEstimateSize));
 376                     Assert.assertTrue(psp.prefixSplits > 0,
 377                                       String.format("Number of non-null prefix splits should be greater that zero when proxyEstimateSize is %s",
 378                                                     proxyEstimateSize));
 379                     Assert.assertTrue(psp.sizeOnTraversal < 1000,
 380                                       String.format("Size on traversal of last split should be less than the size of the list, %d, when proxyEstimateSize is %s",
 381                                                     1000, proxyEstimateSize));
 382                 }
 383             }
 384         }
 385     }
 386 
 387     @Test(dataProvider = "IntStreamTestData.small",
 388           dataProviderClass = IntStreamTestDataProvider.class,
 389           groups = { "serialization-hostile" })
 390     public void testIntStreamSpliterators(String name, TestData.OfInt data) {
 391         for (Function<IntStream, IntStream> f : intStreamFunctions()) {
 392             withData(data).
 393                     stream(in -> {
 394                         IntStream out = f.apply(in);
 395                         return StreamSupport.intStream(() -> out.spliterator(), OpTestCase.getStreamFlags(out), false);
 396                     }).
 397                     exercise();
 398 
 399             withData(data).
 400                     stream((in) -> {
 401                         IntStream out = f.apply(in);
 402                         return StreamSupport.intStream(() -> out.spliterator(), OpTestCase.getStreamFlags(out), true);
 403                     }).
 404                     exercise();
 405         }
 406     }
 407 
 408     @Test(dataProvider = "IntStreamTestData.small", dataProviderClass = IntStreamTestDataProvider.class)
 409     public void testIntSpliterators(String name, TestData.OfInt data) {
 410         for (Function<IntStream, IntStream> f : intStreamFunctions()) {
 411             SpliteratorTestHelper.testIntSpliterator(() -> f.apply(data.stream()).spliterator());
 412         }
 413     }
 414 
 415     @Test(dataProvider = "IntStreamTestData.small", dataProviderClass = IntStreamTestDataProvider.class)
 416     public void testIntParSpliterators(String name, TestData.OfInt data) {
 417         for (Function<IntStream, IntStream> f : intStreamFunctions()) {
 418             SpliteratorTestHelper.testIntSpliterator(() -> f.apply(data.parallelStream()).spliterator());
 419         }
 420     }
 421 
 422     private List<Function<IntStream, IntStream>> intStreamFunctions;
 423 
 424     List<Function<IntStream, IntStream>> intStreamFunctions() {
 425         if (intStreamFunctions == null) {
 426             List<Function<IntStream, IntStream>> opFunctions = Arrays.asList(
 427                     s -> s.filter(ipEven),
 428                     s -> s.flatMap(x -> IntStream.of(x, x)),
 429                     s -> s.sorted());
 430 
 431             intStreamFunctions = permuteStreamFunctions(opFunctions);
 432         }
 433 
 434         return intStreamFunctions;
 435     }
 436 
 437     //
 438 
 439     public void testLongSplitting() {
 440         List<Consumer<LongStream>> terminalOps = Arrays.asList(
 441                 s -> s.toArray(),
 442                 s -> s.forEach(e -> {}),
 443                 s -> s.reduce(Long::sum)
 444         );
 445 
 446         List<UnaryOperator<LongStream>> intermediateOps = Arrays.asList(
 447                 s -> s.parallel(),
 448                 // The following ensures the wrapping spliterator is tested
 449                 s -> s.map(i -> i).parallel()
 450         );
 451 
 452         for (int i = 0; i < terminalOps.size(); i++) {
 453             Consumer<LongStream> terminalOp = terminalOps.get(i);
 454             setContext("termOpIndex", i);
 455             for (int j = 0; j < intermediateOps.size(); j++) {
 456                 setContext("intOpIndex", j);
 457                 UnaryOperator<LongStream> intermediateOp = intermediateOps.get(j);
 458                 for (boolean proxyEstimateSize : new boolean[] {false, true}) {
 459                     setContext("proxyEstimateSize", proxyEstimateSize);
 460                     // Size is assumed to be larger than the target size for no splitting
 461                     // @@@ Need way to obtain the target size
 462                     Spliterator.OfLong sp = intermediateOp.apply(LongStream.range(0, 1000)).spliterator();
 463                     ProxyNoExactSizeSpliterator.OfLong psp = new ProxyNoExactSizeSpliterator.OfLong(sp, proxyEstimateSize);
 464                     LongStream s = StreamSupport.longStream(psp, true);
 465                     terminalOp.accept(s);
 466                     Assert.assertTrue(psp.splits > 0,
 467                                       String.format("Number of splits should be greater that zero when proxyEstimateSize is %s",
 468                                                     proxyEstimateSize));
 469                     Assert.assertTrue(psp.prefixSplits > 0,
 470                                       String.format("Number of non-null prefix splits should be greater that zero when proxyEstimateSize is %s",
 471                                                     proxyEstimateSize));
 472                     Assert.assertTrue(psp.sizeOnTraversal < 1000,
 473                                       String.format("Size on traversal of last split should be less than the size of the list, %d, when proxyEstimateSize is %s",
 474                                                     1000, proxyEstimateSize));
 475                 }
 476             }
 477         }
 478     }
 479 
 480     @Test(dataProvider = "LongStreamTestData.small",
 481           dataProviderClass = LongStreamTestDataProvider.class,
 482           groups = { "serialization-hostile" })
 483     public void testLongStreamSpliterators(String name, TestData.OfLong data) {
 484         for (Function<LongStream, LongStream> f : longStreamFunctions()) {
 485             withData(data).
 486                     stream(in -> {
 487                         LongStream out = f.apply(in);
 488                         return StreamSupport.longStream(() -> out.spliterator(), OpTestCase.getStreamFlags(out), false);
 489                     }).
 490                     exercise();
 491 
 492             withData(data).
 493                     stream((in) -> {
 494                         LongStream out = f.apply(in);
 495                         return StreamSupport.longStream(() -> out.spliterator(), OpTestCase.getStreamFlags(out), true);
 496                     }).
 497                     exercise();
 498         }
 499     }
 500 
 501     @Test(dataProvider = "LongStreamTestData.small", dataProviderClass = LongStreamTestDataProvider.class)
 502     public void testLongSpliterators(String name, TestData.OfLong data) {
 503         for (Function<LongStream, LongStream> f : longStreamFunctions()) {
 504             SpliteratorTestHelper.testLongSpliterator(() -> f.apply(data.stream()).spliterator());
 505         }
 506     }
 507 
 508     @Test(dataProvider = "LongStreamTestData.small", dataProviderClass = LongStreamTestDataProvider.class)
 509     public void testLongParSpliterators(String name, TestData.OfLong data) {
 510         for (Function<LongStream, LongStream> f : longStreamFunctions()) {
 511             SpliteratorTestHelper.testLongSpliterator(() -> f.apply(data.parallelStream()).spliterator());
 512         }
 513     }
 514 
 515     private List<Function<LongStream, LongStream>> longStreamFunctions;
 516 
 517     List<Function<LongStream, LongStream>> longStreamFunctions() {
 518         if (longStreamFunctions == null) {
 519             List<Function<LongStream, LongStream>> opFunctions = Arrays.asList(
 520                     s -> s.filter(lpEven),
 521                     s -> s.flatMap(x -> LongStream.of(x, x)),
 522                     s -> s.sorted());
 523 
 524             longStreamFunctions = permuteStreamFunctions(opFunctions);
 525         }
 526 
 527         return longStreamFunctions;
 528     }
 529 
 530     //
 531 
 532     public void testDoubleSplitting() {
 533         List<Consumer<DoubleStream>> terminalOps = Arrays.asList(
 534                 s -> s.toArray(),
 535                 s -> s.forEach(e -> {}),
 536                 s -> s.reduce(Double::sum)
 537         );
 538 
 539         List<UnaryOperator<DoubleStream>> intermediateOps = Arrays.asList(
 540                 s -> s.parallel(),
 541                 // The following ensures the wrapping spliterator is tested
 542                 s -> s.map(i -> i).parallel()
 543         );
 544 
 545         for (int i = 0; i < terminalOps.size(); i++) {
 546             Consumer<DoubleStream> terminalOp = terminalOps.get(i);
 547             setContext("termOpIndex", i);
 548             for (int j = 0; j < intermediateOps.size(); j++) {
 549                 UnaryOperator<DoubleStream> intermediateOp = intermediateOps.get(j);
 550                 setContext("intOpIndex", j);
 551                 for (boolean proxyEstimateSize : new boolean[] {false, true}) {
 552                     setContext("proxyEstimateSize", proxyEstimateSize);
 553                     // Size is assumed to be larger than the target size for no splitting
 554                     // @@@ Need way to obtain the target size
 555                     Spliterator.OfDouble sp = intermediateOp.apply(IntStream.range(0, 1000).asDoubleStream()).spliterator();
 556                     ProxyNoExactSizeSpliterator.OfDouble psp = new ProxyNoExactSizeSpliterator.OfDouble(sp, proxyEstimateSize);
 557                     DoubleStream s = StreamSupport.doubleStream(psp, true);
 558                     terminalOp.accept(s);
 559                     Assert.assertTrue(psp.splits > 0,
 560                                       String.format("Number of splits should be greater that zero when proxyEstimateSize is %s",
 561                                                     proxyEstimateSize));
 562                     Assert.assertTrue(psp.prefixSplits > 0,
 563                                       String.format("Number of non-null prefix splits should be greater that zero when proxyEstimateSize is %s",
 564                                                     proxyEstimateSize));
 565                     Assert.assertTrue(psp.sizeOnTraversal < 1000,
 566                                       String.format("Size on traversal of last split should be less than the size of the list, %d, when proxyEstimateSize is %s",
 567                                                     1000, proxyEstimateSize));
 568                 }
 569             }
 570         }
 571     }
 572 
 573     @Test(dataProvider = "DoubleStreamTestData.small",
 574           dataProviderClass = DoubleStreamTestDataProvider.class,
 575           groups = { "serialization-hostile" })
 576     public void testDoubleStreamSpliterators(String name, TestData.OfDouble data) {
 577         for (Function<DoubleStream, DoubleStream> f : doubleStreamFunctions()) {
 578             withData(data).
 579                     stream(in -> {
 580                         DoubleStream out = f.apply(in);
 581                         return StreamSupport.doubleStream(() -> out.spliterator(), OpTestCase.getStreamFlags(out), false);
 582                     }).
 583                     exercise();
 584 
 585             withData(data).
 586                     stream((in) -> {
 587                         DoubleStream out = f.apply(in);
 588                         return StreamSupport.doubleStream(() -> out.spliterator(), OpTestCase.getStreamFlags(out), true);
 589                     }).
 590                     exercise();
 591         }
 592     }
 593 
 594     @Test(dataProvider = "DoubleStreamTestData.small", dataProviderClass = DoubleStreamTestDataProvider.class)
 595     public void testDoubleSpliterators(String name, TestData.OfDouble data) {
 596         for (Function<DoubleStream, DoubleStream> f : doubleStreamFunctions()) {
 597             SpliteratorTestHelper.testDoubleSpliterator(() -> f.apply(data.stream()).spliterator());
 598         }
 599     }
 600 
 601     @Test(dataProvider = "DoubleStreamTestData.small", dataProviderClass = DoubleStreamTestDataProvider.class)
 602     public void testDoubleParSpliterators(String name, TestData.OfDouble data) {
 603         for (Function<DoubleStream, DoubleStream> f : doubleStreamFunctions()) {
 604             SpliteratorTestHelper.testDoubleSpliterator(() -> f.apply(data.parallelStream()).spliterator());
 605         }
 606     }
 607 
 608     private List<Function<DoubleStream, DoubleStream>> doubleStreamFunctions;
 609 
 610     List<Function<DoubleStream, DoubleStream>> doubleStreamFunctions() {
 611         if (doubleStreamFunctions == null) {
 612             List<Function<DoubleStream, DoubleStream>> opFunctions = Arrays.asList(
 613                     s -> s.filter(dpEven),
 614                     s -> s.flatMap(x -> DoubleStream.of(x, x)),
 615                     s -> s.sorted());
 616 
 617             doubleStreamFunctions = permuteStreamFunctions(opFunctions);
 618         }
 619 
 620         return doubleStreamFunctions;
 621     }
 622 }