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