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