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 java.util.Arrays;
26 import java.util.HashMap;
27 import java.util.Iterator;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.PrimitiveIterator;
31 import java.util.Spliterators;
32 import java.util.function.DoublePredicate;
33 import java.util.function.Function;
34 import java.util.function.IntPredicate;
35 import java.util.function.LongPredicate;
36 import java.util.function.Predicate;
37 import java.util.function.Supplier;
38 import java.util.stream.DoubleStream;
39 import java.util.stream.DoubleStreamTestDataProvider;
40 import java.util.stream.IntStream;
41 import java.util.stream.IntStreamTestDataProvider;
42 import java.util.stream.LongStream;
43 import java.util.stream.LongStreamTestDataProvider;
44 import java.util.stream.OpTestCase;
45 import java.util.stream.Stream;
46 import java.util.stream.StreamSupport;
47 import java.util.stream.StreamTestDataProvider;
48 import java.util.stream.TestData;
49 
50 import org.testng.annotations.Test;
51 
52 import static java.util.stream.LambdaTestHelpers.countTo;
53 import static java.util.stream.LambdaTestHelpers.dpEven;
54 import static java.util.stream.LambdaTestHelpers.dpFalse;
55 import static java.util.stream.LambdaTestHelpers.dpOdd;
56 import static java.util.stream.LambdaTestHelpers.dpTrue;
57 import static java.util.stream.LambdaTestHelpers.ipEven;
58 import static java.util.stream.LambdaTestHelpers.ipFalse;
59 import static java.util.stream.LambdaTestHelpers.ipOdd;
60 import static java.util.stream.LambdaTestHelpers.ipTrue;
61 import static java.util.stream.LambdaTestHelpers.lpEven;
62 import static java.util.stream.LambdaTestHelpers.lpFalse;
63 import static java.util.stream.LambdaTestHelpers.lpOdd;
64 import static java.util.stream.LambdaTestHelpers.lpTrue;
65 import static java.util.stream.LambdaTestHelpers.pEven;
66 import static java.util.stream.LambdaTestHelpers.pFalse;
67 import static java.util.stream.LambdaTestHelpers.pOdd;
68 import static java.util.stream.LambdaTestHelpers.pTrue;
69 
70 /**
71  * MatchOpTest
72  *
73  * @author Brian Goetz
74  */
75 @Test
76 public class MatchOpTest extends OpTestCase {
77     private enum Kind { ANY, ALL, NONE }
78 
79     @SuppressWarnings("unchecked")
80     private static final Predicate<Integer>[] INTEGER_PREDICATES
81             = (Predicate<Integer>[]) new Predicate<?>[]{pTrue, pFalse, pEven, pOdd};
82 
83     @SuppressWarnings({"serial", "rawtypes"})
84     private final Map kinds
85             = new HashMap<Kind, Function<Predicate<Integer>, Function<Stream<Integer>, Boolean>>>() {{
86         put(Kind.ANY, p -> s -> s.anyMatch(p));
87         put(Kind.ALL, p -> s -> s.allMatch(p));
88         put(Kind.NONE, p -> s -> s.noneMatch(p));
89     }};
90 
91     @SuppressWarnings("unchecked")
kinds()92     private <T> Map<Kind, Function<Predicate<T>, Function<Stream<T>, Boolean>>> kinds() {
93         return (Map<Kind, Function<Predicate<T>, Function<Stream<T>, Boolean>>>) kinds;
94     }
95 
assertPredicates(List<T> source, Kind kind, Predicate<T>[] predicates, boolean... answers)96     private <T> void assertPredicates(List<T> source, Kind kind, Predicate<T>[] predicates, boolean... answers) {
97         for (int i = 0; i < predicates.length; i++) {
98             setContext("i", i);
99             boolean match = this.<T>kinds().get(kind).apply(predicates[i]).apply(source.stream());
100             assertEquals(answers[i], match, kind.toString() + predicates[i].toString());
101         }
102     }
103 
testStreamMatches()104     public void testStreamMatches() {
105         assertPredicates(countTo(0), Kind.ANY, INTEGER_PREDICATES, false, false, false, false);
106         assertPredicates(countTo(0), Kind.ALL, INTEGER_PREDICATES, true, true, true, true);
107         assertPredicates(countTo(0), Kind.NONE, INTEGER_PREDICATES, true, true, true, true);
108 
109         assertPredicates(countTo(1), Kind.ANY, INTEGER_PREDICATES, true, false, false, true);
110         assertPredicates(countTo(1), Kind.ALL, INTEGER_PREDICATES, true, false, false, true);
111         assertPredicates(countTo(1), Kind.NONE, INTEGER_PREDICATES, false, true, true, false);
112 
113         assertPredicates(countTo(5), Kind.ANY, INTEGER_PREDICATES, true, false, true, true);
114         assertPredicates(countTo(5), Kind.ALL, INTEGER_PREDICATES, true, false, false, false);
115         assertPredicates(countTo(5), Kind.NONE, INTEGER_PREDICATES, false, true, false, false);
116     }
117 
118     @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
testStream(String name, TestData.OfRef<Integer> data)119     public void testStream(String name, TestData.OfRef<Integer> data) {
120         for (Predicate<Integer> p : INTEGER_PREDICATES) {
121             setContext("p", p);
122             for (Kind kind : Kind.values()) {
123                 setContext("kind", kind);
124                 exerciseTerminalOps(data, this.<Integer>kinds().get(kind).apply(p));
125                 exerciseTerminalOps(data, s -> s.filter(pFalse), this.<Integer>kinds().get(kind).apply(p));
126                 exerciseTerminalOps(data, s -> s.filter(pEven), this.<Integer>kinds().get(kind).apply(p));
127             }
128         }
129     }
130 
testInfinite()131     public void testInfinite() {
132         class CycleIterator implements Iterator<Integer> {
133             final Supplier<Iterator<Integer>> source;
134             Iterator<Integer> i = null;
135 
136             CycleIterator(Supplier<Iterator<Integer>> source) {
137                 this.source = source;
138             }
139 
140             @Override
141             public Integer next() {
142                 if (i == null || !i.hasNext()) {
143                     i = source.get();
144                 }
145                 return i.next();
146             }
147 
148             @Override
149             public boolean hasNext() {
150                 if (i == null || !i.hasNext()) {
151                     i = source.get();
152                 }
153                 return i.hasNext();
154             }
155         }
156 
157         Supplier<Iterator<Integer>> source = () -> Arrays.asList(1, 2, 3, 4).iterator();
158         Supplier<Stream<Integer>> s = () -> StreamSupport.stream(Spliterators.spliteratorUnknownSize(new CycleIterator(source), 0), false);
159 
160         assertFalse(s.get().allMatch(i -> i > 3));
161         assertTrue(s.get().anyMatch(i -> i > 3));
162         assertFalse(s.get().noneMatch(i -> i > 3));
163         assertFalse(s.get().parallel().allMatch(i -> i > 3));
164         assertTrue(s.get().parallel().anyMatch(i -> i > 3));
165         assertFalse(s.get().parallel().noneMatch(i -> i > 3));
166     }
167 
168     //
169 
170     private static final IntPredicate[] INT_PREDICATES
171             = new IntPredicate[]{ipTrue, ipFalse, ipEven, ipOdd};
172 
173     @SuppressWarnings("serial")
174     private final Map<Kind, Function<IntPredicate, Function<IntStream, Boolean>>> intKinds
175             = new HashMap<Kind, Function<IntPredicate, Function<IntStream, Boolean>>>() {{
176         put(Kind.ANY, p -> s -> s.anyMatch(p));
177         put(Kind.ALL, p -> s -> s.allMatch(p));
178         put(Kind.NONE, p -> s -> s.noneMatch(p));
179     }};
180 
assertIntPredicates(Supplier<IntStream> source, Kind kind, IntPredicate[] predicates, boolean... answers)181     private void assertIntPredicates(Supplier<IntStream> source, Kind kind, IntPredicate[] predicates, boolean... answers) {
182         for (int i = 0; i < predicates.length; i++) {
183             setContext("i", i);
184             boolean match = intKinds.get(kind).apply(predicates[i]).apply(source.get());
185             assertEquals(answers[i], match, kind.toString() + predicates[i].toString());
186         }
187     }
188 
testIntStreamMatches()189     public void testIntStreamMatches() {
190         assertIntPredicates(() -> IntStream.range(0, 0), Kind.ANY, INT_PREDICATES, false, false, false, false);
191         assertIntPredicates(() -> IntStream.range(0, 0), Kind.ALL, INT_PREDICATES, true, true, true, true);
192         assertIntPredicates(() -> IntStream.range(0, 0), Kind.NONE, INT_PREDICATES, true, true, true, true);
193 
194         assertIntPredicates(() -> IntStream.range(1, 2), Kind.ANY, INT_PREDICATES, true, false, false, true);
195         assertIntPredicates(() -> IntStream.range(1, 2), Kind.ALL, INT_PREDICATES, true, false, false, true);
196         assertIntPredicates(() -> IntStream.range(1, 2), Kind.NONE, INT_PREDICATES, false, true, true, false);
197 
198         assertIntPredicates(() -> IntStream.range(1, 6), Kind.ANY, INT_PREDICATES, true, false, true, true);
199         assertIntPredicates(() -> IntStream.range(1, 6), Kind.ALL, INT_PREDICATES, true, false, false, false);
200         assertIntPredicates(() -> IntStream.range(1, 6), Kind.NONE, INT_PREDICATES, false, true, false, false);
201     }
202 
203     @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
testIntStream(String name, TestData.OfInt data)204     public void testIntStream(String name, TestData.OfInt data) {
205         for (IntPredicate p : INT_PREDICATES) {
206             setContext("p", p);
207             for (Kind kind : Kind.values()) {
208                 setContext("kind", kind);
209                 exerciseTerminalOps(data, intKinds.get(kind).apply(p));
210                 exerciseTerminalOps(data, s -> s.filter(ipFalse), intKinds.get(kind).apply(p));
211                 exerciseTerminalOps(data, s -> s.filter(ipEven), intKinds.get(kind).apply(p));
212             }
213         }
214     }
215 
testIntInfinite()216     public void testIntInfinite() {
217         class CycleIterator implements PrimitiveIterator.OfInt {
218             final Supplier<PrimitiveIterator.OfInt> source;
219             PrimitiveIterator.OfInt i = null;
220 
221             CycleIterator(Supplier<PrimitiveIterator.OfInt> source) {
222                 this.source = source;
223             }
224 
225             @Override
226             public int nextInt() {
227                 if (i == null || !i.hasNext()) {
228                     i = source.get();
229                 }
230                 return i.nextInt();
231             }
232 
233             @Override
234             public boolean hasNext() {
235                 if (i == null || !i.hasNext()) {
236                     i = source.get();
237                 }
238                 return i.hasNext();
239             }
240         }
241 
242         Supplier<PrimitiveIterator.OfInt> source = () -> Arrays.stream(new int[]{1, 2, 3, 4}).iterator();
243         Supplier<IntStream> s = () -> StreamSupport.intStream(Spliterators.spliteratorUnknownSize(new CycleIterator(source), 0), false);
244 
245         assertFalse(s.get().allMatch(i -> i > 3));
246         assertTrue(s.get().anyMatch(i -> i > 3));
247         assertFalse(s.get().noneMatch(i -> i > 3));
248         assertFalse(s.get().parallel().allMatch(i -> i > 3));
249         assertTrue(s.get().parallel().anyMatch(i -> i > 3));
250         assertFalse(s.get().parallel().noneMatch(i -> i > 3));
251     }
252 
253     //
254 
255     private static final LongPredicate[] LONG_PREDICATES
256             = new LongPredicate[]{lpTrue, lpFalse, lpEven, lpOdd};
257 
258     @SuppressWarnings("serial")
259     private final Map<Kind, Function<LongPredicate, Function<LongStream, Boolean>>> longKinds
260             = new HashMap<Kind, Function<LongPredicate, Function<LongStream, Boolean>>>() {{
261         put(Kind.ANY, p -> s -> s.anyMatch(p));
262         put(Kind.ALL, p -> s -> s.allMatch(p));
263         put(Kind.NONE, p -> s -> s.noneMatch(p));
264     }};
265 
assertLongPredicates(Supplier<LongStream> source, Kind kind, LongPredicate[] predicates, boolean... answers)266     private void assertLongPredicates(Supplier<LongStream> source, Kind kind, LongPredicate[] predicates, boolean... answers) {
267         for (int i = 0; i < predicates.length; i++) {
268             setContext("i", i);
269             boolean match = longKinds.get(kind).apply(predicates[i]).apply(source.get());
270             assertEquals(answers[i], match, kind.toString() + predicates[i].toString());
271         }
272     }
273 
testLongStreamMatches()274     public void testLongStreamMatches() {
275         assertLongPredicates(() -> LongStream.range(0, 0), Kind.ANY, LONG_PREDICATES, false, false, false, false);
276         assertLongPredicates(() -> LongStream.range(0, 0), Kind.ALL, LONG_PREDICATES, true, true, true, true);
277         assertLongPredicates(() -> LongStream.range(0, 0), Kind.NONE, LONG_PREDICATES, true, true, true, true);
278 
279         assertLongPredicates(() -> LongStream.range(1, 2), Kind.ANY, LONG_PREDICATES, true, false, false, true);
280         assertLongPredicates(() -> LongStream.range(1, 2), Kind.ALL, LONG_PREDICATES, true, false, false, true);
281         assertLongPredicates(() -> LongStream.range(1, 2), Kind.NONE, LONG_PREDICATES, false, true, true, false);
282 
283         assertLongPredicates(() -> LongStream.range(1, 6), Kind.ANY, LONG_PREDICATES, true, false, true, true);
284         assertLongPredicates(() -> LongStream.range(1, 6), Kind.ALL, LONG_PREDICATES, true, false, false, false);
285         assertLongPredicates(() -> LongStream.range(1, 6), Kind.NONE, LONG_PREDICATES, false, true, false, false);
286     }
287 
288     @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
testLongStream(String name, TestData.OfLong data)289     public void testLongStream(String name, TestData.OfLong data) {
290         for (LongPredicate p : LONG_PREDICATES) {
291             setContext("p", p);
292             for (Kind kind : Kind.values()) {
293                 setContext("kind", kind);
294                 exerciseTerminalOps(data, longKinds.get(kind).apply(p));
295                 exerciseTerminalOps(data, s -> s.filter(lpFalse), longKinds.get(kind).apply(p));
296                 exerciseTerminalOps(data, s -> s.filter(lpEven), longKinds.get(kind).apply(p));
297             }
298         }
299     }
300 
testLongInfinite()301     public void testLongInfinite() {
302         class CycleIterator implements PrimitiveIterator.OfLong {
303             final Supplier<PrimitiveIterator.OfLong> source;
304             PrimitiveIterator.OfLong i = null;
305 
306             CycleIterator(Supplier<PrimitiveIterator.OfLong> source) {
307                 this.source = source;
308             }
309 
310             @Override
311             public long nextLong() {
312                 if (i == null || !i.hasNext()) {
313                     i = source.get();
314                 }
315                 return i.nextLong();
316             }
317 
318             @Override
319             public boolean hasNext() {
320                 if (i == null || !i.hasNext()) {
321                     i = source.get();
322                 }
323                 return i.hasNext();
324             }
325         }
326 
327         Supplier<PrimitiveIterator.OfLong> source = () -> Arrays.stream(new long[]{1, 2, 3, 4}).iterator();
328         Supplier<LongStream> s = () -> StreamSupport.longStream(Spliterators.spliteratorUnknownSize(new CycleIterator(source), 0), false);
329 
330         assertFalse(s.get().allMatch(i -> i > 3));
331         assertTrue(s.get().anyMatch(i -> i > 3));
332         assertFalse(s.get().noneMatch(i -> i > 3));
333         assertFalse(s.get().parallel().allMatch(i -> i > 3));
334         assertTrue(s.get().parallel().anyMatch(i -> i > 3));
335         assertFalse(s.get().parallel().noneMatch(i -> i > 3));
336     }
337 
338     //
339 
340     private static final DoublePredicate[] DOUBLE_PREDICATES
341             = new DoublePredicate[]{dpTrue, dpFalse, dpEven, dpOdd};
342 
343     @SuppressWarnings("serial")
344     private final Map<Kind, Function<DoublePredicate, Function<DoubleStream, Boolean>>> doubleKinds
345             = new HashMap<Kind, Function<DoublePredicate, Function<DoubleStream, Boolean>>>() {{
346         put(Kind.ANY, p -> s -> s.anyMatch(p));
347         put(Kind.ALL, p -> s -> s.allMatch(p));
348         put(Kind.NONE, p -> s -> s.noneMatch(p));
349     }};
350 
assertDoublePredicates(Supplier<DoubleStream> source, Kind kind, DoublePredicate[] predicates, boolean... answers)351     private void assertDoublePredicates(Supplier<DoubleStream> source, Kind kind, DoublePredicate[] predicates, boolean... answers) {
352         for (int i = 0; i < predicates.length; i++) {
353             setContext("i", i);
354             boolean match = doubleKinds.get(kind).apply(predicates[i]).apply(source.get());
355             assertEquals(answers[i], match, kind.toString() + predicates[i].toString());
356         }
357     }
358 
testDoubleStreamMatches()359     public void testDoubleStreamMatches() {
360         assertDoublePredicates(() -> LongStream.range(0, 0).asDoubleStream(), Kind.ANY, DOUBLE_PREDICATES, false, false, false, false);
361         assertDoublePredicates(() -> LongStream.range(0, 0).asDoubleStream(), Kind.ALL, DOUBLE_PREDICATES, true, true, true, true);
362         assertDoublePredicates(() -> LongStream.range(0, 0).asDoubleStream(), Kind.NONE, DOUBLE_PREDICATES, true, true, true, true);
363 
364         assertDoublePredicates(() -> LongStream.range(1, 2).asDoubleStream(), Kind.ANY, DOUBLE_PREDICATES, true, false, false, true);
365         assertDoublePredicates(() -> LongStream.range(1, 2).asDoubleStream(), Kind.ALL, DOUBLE_PREDICATES, true, false, false, true);
366         assertDoublePredicates(() -> LongStream.range(1, 2).asDoubleStream(), Kind.NONE, DOUBLE_PREDICATES, false, true, true, false);
367 
368         assertDoublePredicates(() -> LongStream.range(1, 6).asDoubleStream(), Kind.ANY, DOUBLE_PREDICATES, true, false, true, true);
369         assertDoublePredicates(() -> LongStream.range(1, 6).asDoubleStream(), Kind.ALL, DOUBLE_PREDICATES, true, false, false, false);
370         assertDoublePredicates(() -> LongStream.range(1, 6).asDoubleStream(), Kind.NONE, DOUBLE_PREDICATES, false, true, false, false);
371     }
372 
373     @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
testDoubleStream(String name, TestData.OfDouble data)374     public void testDoubleStream(String name, TestData.OfDouble data) {
375         for (DoublePredicate p : DOUBLE_PREDICATES) {
376             setContext("p", p);
377             for (Kind kind : Kind.values()) {
378                 setContext("kind", kind);
379                 exerciseTerminalOps(data, doubleKinds.get(kind).apply(p));
380                 exerciseTerminalOps(data, s -> s.filter(dpFalse), doubleKinds.get(kind).apply(p));
381                 exerciseTerminalOps(data, s -> s.filter(dpEven), doubleKinds.get(kind).apply(p));
382             }
383         }
384     }
385 
testDoubleInfinite()386     public void testDoubleInfinite() {
387         class CycleIterator implements PrimitiveIterator.OfDouble {
388             final Supplier<PrimitiveIterator.OfDouble> source;
389             PrimitiveIterator.OfDouble i = null;
390 
391             CycleIterator(Supplier<PrimitiveIterator.OfDouble> source) {
392                 this.source = source;
393             }
394 
395             @Override
396             public double nextDouble() {
397                 if (i == null || !i.hasNext()) {
398                     i = source.get();
399                 }
400                 return i.nextDouble();
401             }
402 
403             @Override
404             public boolean hasNext() {
405                 if (i == null || !i.hasNext()) {
406                     i = source.get();
407                 }
408                 return i.hasNext();
409             }
410         }
411 
412         Supplier<PrimitiveIterator.OfDouble> source = () -> Arrays.stream(new double[]{1, 2, 3, 4}).iterator();
413         Supplier<DoubleStream> s = () -> StreamSupport.doubleStream(Spliterators.spliteratorUnknownSize(new CycleIterator(source), 0), false);
414 
415         assertFalse(s.get().allMatch(i -> i > 3));
416         assertTrue(s.get().anyMatch(i -> i > 3));
417         assertFalse(s.get().noneMatch(i -> i > 3));
418         assertFalse(s.get().parallel().allMatch(i -> i > 3));
419         assertTrue(s.get().parallel().anyMatch(i -> i > 3));
420         assertFalse(s.get().parallel().noneMatch(i -> i > 3));
421     }
422 }
423