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