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