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