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.StreamTestDataProvider;
31 import org.openjdk.testlib.java.util.stream.TestData;
32 
33 import org.testng.annotations.Test;
34 
35 import java.util.*;
36 import java.util.function.Function;
37 import java.util.stream.BaseStream;
38 import java.util.stream.Stream;
39 import java.util.stream.IntStream;
40 import java.util.stream.LongStream;
41 import java.util.stream.DoubleStream;
42 
43 import static org.openjdk.testlib.java.util.stream.LambdaTestHelpers.*;
44 import static org.testng.Assert.assertEquals;
45 
46 import android.platform.test.annotations.LargeTest;
47 
48 
49 /**
50  * ToArrayOpTest
51  *
52  */
53 @Test
54 public class ToArrayOpTest extends OpTestCase {
55 
testToArray()56     public void testToArray() {
57         assertCountSum(Arrays.asList(countTo(0).stream().toArray()), 0, 0);
58         assertCountSum(Arrays.asList(countTo(10).stream().toArray()), 10, 55);
59     }
60 
61     @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
testOps(String name, TestData.OfRef<Integer> data)62     public void testOps(String name, TestData.OfRef<Integer> data) {
63         exerciseTerminalOps(data, s -> s.toArray());
64     }
65 
66     @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
testOpsWithMap(String name, TestData.OfRef<Integer> data)67     public void testOpsWithMap(String name, TestData.OfRef<Integer> data) {
68         // Retain the size of the source
69         // This should kick in the parallel evaluation optimization for tasks stuffing elements into a shared array
70 
71         Object[] objects = exerciseTerminalOps(data, s -> s.map(i -> (Integer) (i + i)), s -> s.toArray());
72         assertTrue(objects.length == data.size());
73     }
74 
75     @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
testOpsWithSorted(String name, TestData.OfRef<Integer> data)76     public void testOpsWithSorted(String name, TestData.OfRef<Integer> data) {
77         // Retain the size of the source
78         // This should kick in the parallel evaluation optimization for tasks stuffing elements into a shared array
79 
80         Object[] objects = exerciseTerminalOps(data, s -> s.sorted(), s -> s.toArray());
81         assertTrue(objects.length == data.size());
82     }
83 
84     @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
testOpsWithFlatMap(String name, TestData.OfRef<Integer> data)85     public void testOpsWithFlatMap(String name, TestData.OfRef<Integer> data) {
86         // Double the size of the source
87         // Fixed size optimizations will not be used
88 
89         Object[] objects = exerciseTerminalOps(data,
90                                                s -> s.flatMap(e -> Arrays.stream(new Object[] { e, e })),
91                                                s -> s.toArray());
92         assertTrue(objects.length == data.size() * 2);
93     }
94 
95     @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
testOpsWithFilter(String name, TestData.OfRef<Integer> data)96     public void testOpsWithFilter(String name, TestData.OfRef<Integer> data) {
97         // Reduce the size of the source
98         // Fixed size optimizations will not be used
99 
100         exerciseTerminalOps(data, s -> s.filter(LambdaTestHelpers.pEven), s -> s.toArray());
101     }
102 
testAsArrayWithType()103     public void testAsArrayWithType() {
104         exerciseTerminalOps(
105                 TestData.Factory.ofCollection("", Arrays.asList(1.1, 2.2, 3.4, 4.4)),
106                 s -> // First pipeline slice using Object[] with Double elements
107                     s.sorted()
108                     // Second pipeline slice using Integer[] with Integer elements
109                     .map((Double d) -> Integer.valueOf(d.intValue())).sorted(),
110                 s -> s.toArray(Integer[]::new));
111     }
112 
113     private List<Function<Stream<Integer>, Stream<Integer>>> uniqueAndSortedPermutations =
114             LambdaTestHelpers.permuteStreamFunctions(Arrays.asList(
115                     s -> s.distinct(),
116                     s -> s.distinct(),
117                     s -> s.sorted(),
118                     s -> s.sorted()
119             ));
120 
121     @LargeTest
122     @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
testDistinctAndSortedPermutations(String name, TestData.OfRef<Integer> data)123     public void testDistinctAndSortedPermutations(String name, TestData.OfRef<Integer> data) {
124         for (Function<Stream<Integer>, Stream<Integer>> f : uniqueAndSortedPermutations) {
125             exerciseTerminalOps(data, f, s -> s.toArray());
126 
127             Integer[] is = exerciseTerminalOps(data, f, s -> s.toArray(Integer[]::new));
128             assertEquals(is.getClass(), Integer[].class);
129 
130             Number[] ns = exerciseTerminalOps(data, f, s -> s.toArray(Number[]::new));
131             assertEquals(ns.getClass(), Number[].class);
132 
133             if (data.size() > 0) {
134                 Exception caught = null;
135                 try {
136                     exerciseTerminalOps(data, f, s -> s.toArray(String[]::new));
137                 } catch (Exception e) {
138                     caught = e;
139                 }
140                 assertTrue(caught != null);
141                 assertEquals(caught.getClass(), ArrayStoreException.class);
142             }
143         }
144     }
145 
146     private List<Function<Stream<Integer>, Stream<Integer>>> statefulOpPermutations =
147             LambdaTestHelpers.permuteStreamFunctions(Arrays.asList(
148                     s -> s.limit(10),
149                     s -> s.distinct(),
150                     s -> s.sorted()
151             ));
152 
statefulOpResultAsserter(TestData.OfRef<Integer> data)153     private <T extends Object> ResultAsserter<T[]> statefulOpResultAsserter(TestData.OfRef<Integer> data) {
154         return (act, exp, ord, par) -> {
155             if (par) {
156                 if (!data.isOrdered()) {
157                     // Relax the checking if the data source is unordered
158                     // It is not exactly possible to determine if the limit
159                     // operation is present and if it is before or after
160                     // the sorted operation
161                     // If the limit operation is present and before the sorted
162                     // operation then the sub-set output after limit is a
163                     // non-deterministic sub-set of the source
164                     List<Integer> expected = new ArrayList<>();
165                     data.forEach(expected::add);
166 
167                     List<T> actual = Arrays.asList(act);
168 
169                     assertEquals(actual.size(), exp.length);
170                     assertTrue(expected.containsAll(actual));
171                     return;
172                 }
173                 else if (!ord) {
174                     LambdaTestHelpers.assertContentsUnordered(Arrays.asList(act),
175                                                               Arrays.asList(exp));
176                     return;
177                 }
178             }
179             assertEquals(act, exp);
180         };
181     }
182 
183     @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class,
184           groups = { "serialization-hostile" })
185     public void testStatefulOpPermutations(String name, TestData.OfRef<Integer> data) {
186         for (Function<Stream<Integer>, Stream<Integer>> f : statefulOpPermutations) {
187             withData(data).terminal(f, s -> s.toArray())
188                     .resultAsserter(statefulOpResultAsserter(data))
189                     .exercise();
190 
191             Integer[] is = withData(data).terminal(f, s -> s.toArray(Integer[]::new))
192                     .resultAsserter(statefulOpResultAsserter(data))
193                     .exercise();
194             assertEquals(is.getClass(), Integer[].class);
195 
196             Number[] ns = withData(data).terminal(f, s -> s.toArray(Number[]::new))
197                     .resultAsserter(statefulOpResultAsserter(data))
198                     .exercise();
199             assertEquals(ns.getClass(), Number[].class);
200 
201             if (data.size() > 0) {
202                 Exception caught = null;
203                 try {
204                     exerciseTerminalOps(data, f, s -> s.toArray(String[]::new));
205                 } catch (Exception e) {
206                     caught = e;
207                 }
208                 assertTrue(caught != null);
209                 assertEquals(caught.getClass(), ArrayStoreException.class);
210             }
211         }
212     }
213 
214     //
215 
216     @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
217     public void testIntOps(String name, TestData.OfInt data) {
218         exerciseTerminalOps(data, s -> s.toArray());
219     }
220 
221     @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
222     public void testIntOpsWithMap(String name, TestData.OfInt data) {
223         // Retain the size of the source
224         // This should kick in the parallel evaluation optimization for tasks stuffing elements into a shared array
225 
226         int[] ints = exerciseTerminalOps(data, s -> s.map(i -> i + i), s -> s.toArray());
227         assertTrue(ints.length == data.size());
228     }
229 
230     @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
231     public void testIntOpsWithSorted(String name, TestData.OfInt data) {
232         // Retain the size of the source
233         // This should kick in the parallel evaluation optimization for tasks stuffing elements into a shared array
234 
235         int[] ints = exerciseTerminalOps(data, s -> s.sorted(), (IntStream s) -> s.toArray());
236         assertTrue(ints.length == data.size());
237     }
238 
239     @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
240     public void testIntOpsWithFlatMap(String name, TestData.OfInt data) {
241         // Int the size of the source
242         // Fixed size optimizations will not be used
243 
244         int[] objects = exerciseTerminalOps(data,
245                                                s -> s.flatMap(e -> Arrays.stream(new int[] { e, e })),
246                                                s -> s.toArray());
247         assertTrue(objects.length == data.size() * 2);
248     }
249 
250     @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
251     public void testIntOpsWithFilter(String name, TestData.OfInt data) {
252         // Reduce the size of the source
253         // Fixed size optimizations will not be used
254 
255         exerciseTerminalOps(data, s -> s.filter(LambdaTestHelpers.ipEven), s -> s.toArray());
256     }
257 
258     private List<Function<IntStream, IntStream>> intUniqueAndSortedPermutations =
259             LambdaTestHelpers.permuteStreamFunctions(Arrays.asList(
260                     s -> s.distinct(),
261                     s -> s.distinct(),
262                     s -> s.sorted(),
263                     s -> s.sorted()
264             ));
265 
266     @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
267     public void testIntDistinctAndSortedPermutations(String name, TestData.OfInt data) {
268         for (Function<IntStream, IntStream> f : intUniqueAndSortedPermutations) {
269             exerciseTerminalOps(data, f, s -> s.toArray());
270         }
271     }
272 
273     private List<Function<IntStream, IntStream>> intStatefulOpPermutations =
274             LambdaTestHelpers.permuteStreamFunctions(Arrays.asList(
275                     s -> s.limit(10),
276                     s -> s.distinct(),
277                     s -> s.sorted()
278             ));
279 
280     @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
281     public void testIntStatefulOpPermutations(String name, TestData.OfInt data) {
282         for (Function<IntStream, IntStream> f : intStatefulOpPermutations) {
283             exerciseTerminalOps(data, f, s -> s.toArray());
284         }
285     }
286 
287     //
288 
289     @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
290     public void testLongOps(String name, TestData.OfLong data) {
291         exerciseTerminalOps(data, s -> s.toArray());
292     }
293 
294     @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
295     public void testLongOpsWithMap(String name, TestData.OfLong data) {
296         // Retain the size of the source
297         // This should kick in the parallel evaluation optimization for tasks stuffing elements into a shared array
298 
299         long[] longs = exerciseTerminalOps(data, s -> s.map(i -> i + i), s -> s.toArray());
300         assertTrue(longs.length == data.size());
301     }
302 
303     @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
304     public void testLongOpsWithSorted(String name, TestData.OfLong data) {
305         // Retain the size of the source
306         // This should kick in the parallel evaluation optimization for tasks stuffing elements into a shared array
307 
308         long[] longs = exerciseTerminalOps(data, s -> s.sorted(), (LongStream s) -> s.toArray());
309         assertTrue(longs.length == data.size());
310     }
311 
312     @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
313     public void testLongOpsWithFlatMap(String name, TestData.OfLong data) {
314         // Long the size of the source
315         // Fixed size optimizations will not be used
316 
317         long[] objects = exerciseTerminalOps(data,
318                                                s -> s.flatMap(e -> Arrays.stream(new long[] { e, e })),
319                                                s -> s.toArray());
320         assertTrue(objects.length == data.size() * 2);
321     }
322 
323     @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
324     public void testLongOpsWithFilter(String name, TestData.OfLong data) {
325         // Reduce the size of the source
326         // Fixed size optimizations will not be used
327 
328         exerciseTerminalOps(data, s -> s.filter(LambdaTestHelpers.lpEven), s -> s.toArray());
329     }
330 
331     private List<Function<LongStream, LongStream>> longUniqueAndSortedPermutations =
332             LambdaTestHelpers.permuteStreamFunctions(Arrays.asList(
333                     s -> s.distinct(),
334                     s -> s.distinct(),
335                     s -> s.sorted(),
336                     s -> s.sorted()
337             ));
338 
339     @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
340     public void testLongDistinctAndSortedPermutations(String name, TestData.OfLong data) {
341         for (Function<LongStream, LongStream> f : longUniqueAndSortedPermutations) {
342             exerciseTerminalOps(data, f, s -> s.toArray());
343         }
344     }
345 
346     private List<Function<LongStream, LongStream>> longStatefulOpPermutations =
347             LambdaTestHelpers.permuteStreamFunctions(Arrays.asList(
348                     s -> s.limit(10),
349                     s -> s.distinct(),
350                     s -> s.sorted()
351             ));
352 
353     @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
354     public void testLongStatefulOpPermutations(String name, TestData.OfLong data) {
355         for (Function<LongStream, LongStream> f : longStatefulOpPermutations) {
356             exerciseTerminalOps(data, f, s -> s.toArray());
357         }
358     }
359 
360     //
361 
362     @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
363     public void testDoubleOps(String name, TestData.OfDouble data) {
364         exerciseTerminalOps(data, s -> s.toArray());
365     }
366 
367     @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
368     public void testDoubleOpsWithMap(String name, TestData.OfDouble data) {
369         // Retain the size of the source
370         // This should kick in the parallel evaluation optimization for tasks stuffing elements into a shared array
371 
372         double[] doubles = exerciseTerminalOps(data, s -> s.map(i -> i + i), s -> s.toArray());
373         assertTrue(doubles.length == data.size());
374     }
375 
376     @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
377     public void testDoubleOpsWithSorted(String name, TestData.OfDouble data) {
378         // Retain the size of the source
379         // This should kick in the parallel evaluation optimization for tasks stuffing elements into a shared array
380 
381         double[] doubles = exerciseTerminalOps(data, s -> s.sorted(), (DoubleStream s) -> s.toArray());
382         assertTrue(doubles.length == data.size());
383     }
384 
385     @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
386     public void testDoubleOpsWithFlatMap(String name, TestData.OfDouble data) {
387         // Double the size of the source
388         // Fixed size optimizations will not be used
389 
390         double[] objects = exerciseTerminalOps(data,
391                                                s -> s.flatMap(e -> Arrays.stream(new double[] { e, e })),
392                                                s -> s.toArray());
393         assertTrue(objects.length == data.size() * 2);
394     }
395 
396     @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
397     public void testDoubleOpsWithFilter(String name, TestData.OfDouble data) {
398         // Reduce the size of the source
399         // Fixed size optimizations will not be used
400 
401         exerciseTerminalOps(data, s -> s.filter(LambdaTestHelpers.dpEven), s -> s.toArray());
402     }
403 
404     private List<Function<DoubleStream, DoubleStream>> doubleUniqueAndSortedPermutations =
405             LambdaTestHelpers.permuteStreamFunctions(Arrays.asList(
406                     s -> s.distinct(),
407                     s -> s.distinct(),
408                     s -> s.sorted(),
409                     s -> s.sorted()
410             ));
411 
412     @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
413     public void testDoubleDistinctAndSortedPermutations(String name, TestData.OfDouble data) {
414         for (Function<DoubleStream, DoubleStream> f : doubleUniqueAndSortedPermutations) {
415             exerciseTerminalOps(data, f, s -> s.toArray());
416         }
417     }
418 
419     private List<Function<DoubleStream, DoubleStream>> doubleStatefulOpPermutations =
420             LambdaTestHelpers.permuteStreamFunctions(Arrays.asList(
421                     s -> s.limit(10),
422                     s -> s.distinct(),
423                     s -> s.sorted()
424             ));
425 
426     @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
427     public void testDoubleStatefulOpPermutations(String name, TestData.OfDouble data) {
428         for (Function<DoubleStream, DoubleStream> f : doubleStatefulOpPermutations) {
429             exerciseTerminalOps(data, f, s -> s.toArray());
430         }
431     }
432 }
433