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 java.util.stream;
24 
25 import org.testng.annotations.Test;
26 
27 import java.util.ArrayList;
28 import java.util.Arrays;
29 import java.util.Comparator;
30 import java.util.EnumSet;
31 import java.util.List;
32 import java.util.Spliterator;
33 import java.util.function.Consumer;
34 import java.util.function.Function;
35 import java.util.function.ToDoubleFunction;
36 import java.util.function.ToIntFunction;
37 import java.util.function.ToLongFunction;
38 
39 import static java.util.stream.Collectors.toList;
40 import static java.util.stream.StreamOpFlag.*;
41 import static org.testng.Assert.*;
42 import static org.testng.Assert.assertEquals;
43 
44 @Test
45 public class StreamOpFlagsTest {
46 
testNullCombine()47     public void testNullCombine() {
48         int sourceFlags = StreamOpFlag.IS_SIZED;
49 
50         assertEquals(sourceFlags, toStreamFlags(combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE)));
51     }
52 
testInitialOpFlagsFromSourceFlags()53     public void testInitialOpFlagsFromSourceFlags() {
54         List<StreamOpFlag> flags = new ArrayList<>(StreamOpFlagTestHelper.allStreamFlags());
55         for (int i = 0; i < (1 << flags.size()); i++)  {
56             int sourceFlags = 0;
57             for (int f = 0; f < flags.size(); f++) {
58                 if ((i & (1 << f)) != 0)  {
59                     sourceFlags |= flags.get(f).set();
60                 }
61             }
62 
63             int opsFlags = combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE);
64             assertEquals(opsFlags, (~(sourceFlags << 1)) & StreamOpFlag.INITIAL_OPS_VALUE);
65         }
66     }
67 
testSameCombine()68     public void testSameCombine() {
69         for (StreamOpFlag f : StreamOpFlagTestHelper.allStreamFlags()) {
70             int sourceFlags = f.set();
71             int opsFlags;
72 
73             opsFlags = combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE);
74             opsFlags = combineOpFlags(f.set(), opsFlags);
75             assertEquals(sourceFlags, toStreamFlags(opsFlags));
76         }
77     }
78 
testOpClear()79     public void testOpClear() {
80         for (StreamOpFlag f : StreamOpFlagTestHelper.allStreamFlags()) {
81             // Clear when source not set
82             int sourceFlags = 0;
83             int opsFlags;
84 
85             opsFlags = combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE);
86             opsFlags = combineOpFlags(f.clear(), opsFlags);
87             assertEquals(sourceFlags, toStreamFlags(opsFlags));
88 
89             // Clear when source set
90             sourceFlags = f.set();
91 
92             opsFlags = combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE);
93             opsFlags = combineOpFlags(f.clear(), opsFlags);
94             assertEquals(0, toStreamFlags(opsFlags));
95         }
96     }
97 
testOpInject()98     public void testOpInject() {
99         for (StreamOpFlag f : StreamOpFlagTestHelper.allStreamFlags()) {
100             // Set when source not set
101             int sourceFlags = 0;
102             int opsFlags;
103 
104             opsFlags = combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE);
105             opsFlags = combineOpFlags(f.set(), opsFlags);
106             assertEquals(f.set(), toStreamFlags(opsFlags));
107 
108             // Set when source set
109             sourceFlags = f.set();
110 
111             opsFlags = combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE);
112             opsFlags = combineOpFlags(f.set(), opsFlags);
113             assertEquals(sourceFlags, toStreamFlags(opsFlags));
114         }
115     }
116 
testPairSet()117     public void testPairSet() {
118         List<Integer> sourceFlagsList
119                 = StreamOpFlagTestHelper.allStreamFlags().stream().map(StreamOpFlag::set).collect(toList());
120         sourceFlagsList.add(0, 0);
121 
122         for (int sourceFlags : sourceFlagsList) {
123             for (StreamOpFlag f1 : StreamOpFlagTestHelper.allStreamFlags()) {
124                 for (StreamOpFlag f2 : StreamOpFlagTestHelper.allStreamFlags()) {
125                     int opsFlags;
126 
127                     opsFlags = combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE);
128                     opsFlags = combineOpFlags(f1.set(), opsFlags);
129                     opsFlags = combineOpFlags(f2.set(), opsFlags);
130                     assertEquals(sourceFlags | f1.set() | f2.set(), toStreamFlags(opsFlags));
131                 }
132             }
133         }
134     }
135 
testPairSetAndClear()136     public void testPairSetAndClear() {
137         List<Integer> sourceFlagsList
138                 = StreamOpFlagTestHelper.allStreamFlags().stream().map(StreamOpFlag::set).collect(toList());
139         sourceFlagsList.add(0, 0);
140 
141         for (int sourceFlags : sourceFlagsList) {
142             for (StreamOpFlag f1 : StreamOpFlagTestHelper.allStreamFlags())  {
143                 for (StreamOpFlag f2 : StreamOpFlagTestHelper.allStreamFlags()) {
144                     int opsFlags;
145 
146                     opsFlags = combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE);
147                     opsFlags = combineOpFlags(f1.set(), opsFlags);
148                     opsFlags = combineOpFlags(f2.clear(), opsFlags);
149                     if (f1 == f2)
150                         assertEquals((f2.set() == sourceFlags) ? 0 : sourceFlags, toStreamFlags(opsFlags));
151                     else
152                         assertEquals((f2.set() == sourceFlags) ? f1.set() : sourceFlags | f1.set(), toStreamFlags(opsFlags));
153                 }
154             }
155         }
156     }
157 
testShortCircuit()158     public void testShortCircuit() {
159         int opsFlags = combineOpFlags(0, StreamOpFlag.INITIAL_OPS_VALUE);
160         assertFalse(StreamOpFlag.SHORT_CIRCUIT.isKnown(opsFlags));
161 
162         opsFlags = combineOpFlags(StreamOpFlag.IS_SHORT_CIRCUIT, opsFlags);
163         assertTrue(StreamOpFlag.SHORT_CIRCUIT.isKnown(opsFlags));
164 
165         opsFlags = combineOpFlags(0, opsFlags);
166         assertTrue(StreamOpFlag.SHORT_CIRCUIT.isKnown(opsFlags));
167     }
168 
testApplySourceFlags()169     public void testApplySourceFlags() {
170         int sourceFlags = StreamOpFlag.IS_SIZED | StreamOpFlag.IS_DISTINCT;
171 
172         List<Integer> ops = Arrays.asList(StreamOpFlag.NOT_SIZED, StreamOpFlag.IS_ORDERED | StreamOpFlag.IS_SORTED);
173 
174         int opsFlags = StreamOpFlag.combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE);
175         for (int opFlags : ops) {
176             opsFlags = combineOpFlags(opFlags, opsFlags);
177         }
178         assertFalse(StreamOpFlag.SIZED.isKnown(opsFlags));
179         assertTrue(StreamOpFlag.SIZED.isCleared(opsFlags));
180         assertFalse(StreamOpFlag.SIZED.isPreserved(opsFlags));
181         assertTrue(StreamOpFlag.DISTINCT.isKnown(opsFlags));
182         assertFalse(StreamOpFlag.DISTINCT.isCleared(opsFlags));
183         assertFalse(StreamOpFlag.DISTINCT.isPreserved(opsFlags));
184         assertTrue(StreamOpFlag.SORTED.isKnown(opsFlags));
185         assertFalse(StreamOpFlag.SORTED.isCleared(opsFlags));
186         assertFalse(StreamOpFlag.SORTED.isPreserved(opsFlags));
187         assertTrue(StreamOpFlag.ORDERED.isKnown(opsFlags));
188         assertFalse(StreamOpFlag.ORDERED.isCleared(opsFlags));
189         assertFalse(StreamOpFlag.ORDERED.isPreserved(opsFlags));
190 
191         int streamFlags = toStreamFlags(opsFlags);
192         assertFalse(StreamOpFlag.SIZED.isKnown(streamFlags));
193         assertTrue(StreamOpFlag.DISTINCT.isKnown(streamFlags));
194         assertTrue(StreamOpFlag.SORTED.isKnown(streamFlags));
195         assertTrue(StreamOpFlag.ORDERED.isKnown(streamFlags));
196     }
197 
testSpliteratorMask()198     public void testSpliteratorMask() {
199         assertSpliteratorMask(StreamOpFlag.DISTINCT.set(), StreamOpFlag.IS_DISTINCT);
200         assertSpliteratorMask(StreamOpFlag.DISTINCT.clear(), 0);
201 
202         assertSpliteratorMask(StreamOpFlag.SORTED.set(), StreamOpFlag.IS_SORTED);
203         assertSpliteratorMask(StreamOpFlag.SORTED.clear(), 0);
204 
205         assertSpliteratorMask(StreamOpFlag.ORDERED.set(), StreamOpFlag.IS_ORDERED);
206         assertSpliteratorMask(StreamOpFlag.ORDERED.clear(), 0);
207 
208         assertSpliteratorMask(StreamOpFlag.SIZED.set(), StreamOpFlag.IS_SIZED);
209         assertSpliteratorMask(StreamOpFlag.SIZED.clear(), 0);
210 
211         assertSpliteratorMask(StreamOpFlag.SHORT_CIRCUIT.set(), 0);
212         assertSpliteratorMask(StreamOpFlag.SHORT_CIRCUIT.clear(), 0);
213     }
214 
assertSpliteratorMask(int actual, int expected)215     private void assertSpliteratorMask(int actual, int expected) {
216         assertEquals(actual & StreamOpFlag.SPLITERATOR_CHARACTERISTICS_MASK, expected);
217     }
218 
testStreamMask()219     public void testStreamMask() {
220         assertStreamMask(StreamOpFlag.DISTINCT.set(), StreamOpFlag.IS_DISTINCT);
221         assertStreamMask(StreamOpFlag.DISTINCT.clear(), 0);
222 
223         assertStreamMask(StreamOpFlag.SORTED.set(), StreamOpFlag.IS_SORTED);
224         assertStreamMask(StreamOpFlag.SORTED.clear(), 0);
225 
226         assertStreamMask(StreamOpFlag.ORDERED.set(), StreamOpFlag.IS_ORDERED);
227         assertStreamMask(StreamOpFlag.ORDERED.clear(), 0);
228 
229         assertStreamMask(StreamOpFlag.SIZED.set(), StreamOpFlag.IS_SIZED);
230         assertStreamMask(StreamOpFlag.SIZED.clear(), 0);
231 
232         assertStreamMask(StreamOpFlag.SHORT_CIRCUIT.set(), 0);
233         assertStreamMask(StreamOpFlag.SHORT_CIRCUIT.clear(), 0);
234     }
235 
assertStreamMask(int actual, int expected)236     private void assertStreamMask(int actual, int expected) {
237         assertEquals(actual & StreamOpFlag.STREAM_MASK, expected);
238     }
239 
testOpMask()240     public void testOpMask() {
241         assertOpMask(StreamOpFlag.DISTINCT.set(), StreamOpFlag.IS_DISTINCT);
242         assertOpMask(StreamOpFlag.DISTINCT.clear(), StreamOpFlag.NOT_DISTINCT);
243 
244         assertOpMask(StreamOpFlag.SORTED.set(), StreamOpFlag.IS_SORTED);
245         assertOpMask(StreamOpFlag.SORTED.clear(), StreamOpFlag.NOT_SORTED);
246 
247         assertOpMask(StreamOpFlag.ORDERED.set(), StreamOpFlag.IS_ORDERED);
248         assertOpMask(StreamOpFlag.ORDERED.clear(), StreamOpFlag.NOT_ORDERED);
249 
250         assertOpMask(StreamOpFlag.SIZED.set(), 0);
251         assertOpMask(StreamOpFlag.SIZED.clear(), StreamOpFlag.NOT_SIZED);
252 
253         assertOpMask(StreamOpFlag.SHORT_CIRCUIT.set(), StreamOpFlag.IS_SHORT_CIRCUIT);
254         assertOpMask(StreamOpFlag.SHORT_CIRCUIT.clear(), 0);
255     }
256 
assertOpMask(int actual, int expected)257     private void assertOpMask(int actual, int expected) {
258         assertEquals(actual & StreamOpFlag.OP_MASK, expected);
259     }
260 
testTerminalOpMask()261     public void testTerminalOpMask() {
262         assertTerminalOpMask(StreamOpFlag.DISTINCT.set(), 0);
263         assertTerminalOpMask(StreamOpFlag.DISTINCT.clear(), 0);
264 
265         assertTerminalOpMask(StreamOpFlag.SORTED.set(), 0);
266         assertTerminalOpMask(StreamOpFlag.SORTED.clear(), 0);
267 
268         assertTerminalOpMask(StreamOpFlag.ORDERED.set(), 0);
269         assertTerminalOpMask(StreamOpFlag.ORDERED.clear(), StreamOpFlag.NOT_ORDERED);
270 
271         assertTerminalOpMask(StreamOpFlag.SIZED.set(), 0);
272         assertTerminalOpMask(StreamOpFlag.SIZED.clear(), 0);
273 
274         assertTerminalOpMask(StreamOpFlag.SHORT_CIRCUIT.set(), StreamOpFlag.IS_SHORT_CIRCUIT);
275         assertTerminalOpMask(StreamOpFlag.SHORT_CIRCUIT.clear(), 0);
276     }
277 
assertTerminalOpMask(int actual, int expected)278     private void assertTerminalOpMask(int actual, int expected) {
279         assertEquals(actual & StreamOpFlag.TERMINAL_OP_MASK, expected);
280     }
281 
testUpstreamTerminalOpMask()282     public void testUpstreamTerminalOpMask() {
283         assertUpstreamTerminalOpMask(StreamOpFlag.DISTINCT.set(), 0);
284         assertUpstreamTerminalOpMask(StreamOpFlag.DISTINCT.clear(), 0);
285 
286         assertUpstreamTerminalOpMask(StreamOpFlag.SORTED.set(), 0);
287         assertUpstreamTerminalOpMask(StreamOpFlag.SORTED.clear(), 0);
288 
289         assertUpstreamTerminalOpMask(StreamOpFlag.ORDERED.set(), 0);
290         assertUpstreamTerminalOpMask(StreamOpFlag.ORDERED.clear(), StreamOpFlag.NOT_ORDERED);
291 
292         assertUpstreamTerminalOpMask(StreamOpFlag.SIZED.set(), 0);
293         assertUpstreamTerminalOpMask(StreamOpFlag.SIZED.clear(), 0);
294 
295         assertUpstreamTerminalOpMask(StreamOpFlag.SHORT_CIRCUIT.set(), 0);
296         assertUpstreamTerminalOpMask(StreamOpFlag.SHORT_CIRCUIT.clear(), 0);
297     }
298 
assertUpstreamTerminalOpMask(int actual, int expected)299     private void assertUpstreamTerminalOpMask(int actual, int expected) {
300         assertEquals(actual & StreamOpFlag.UPSTREAM_TERMINAL_OP_MASK, expected);
301     }
302 
testSpliteratorCharacteristics()303     public void testSpliteratorCharacteristics() {
304         assertEquals(Spliterator.DISTINCT, StreamOpFlag.IS_DISTINCT);
305         assertEquals(Spliterator.SORTED, StreamOpFlag.IS_SORTED);
306         assertEquals(Spliterator.ORDERED, StreamOpFlag.IS_ORDERED);
307         assertEquals(Spliterator.SIZED, StreamOpFlag.IS_SIZED);
308 
309         List<Integer> others = Arrays.asList(Spliterator.NONNULL, Spliterator.IMMUTABLE,
310                                              Spliterator.CONCURRENT, Spliterator.SUBSIZED);
311         for (int c : others) {
312             assertNotEquals(c, StreamOpFlag.IS_SHORT_CIRCUIT);
313         }
314     }
315 
testSpliteratorCharacteristicsMask()316     public void testSpliteratorCharacteristicsMask() {
317         assertSpliteratorCharacteristicsMask(StreamOpFlag.DISTINCT.set(), StreamOpFlag.IS_DISTINCT);
318         assertSpliteratorCharacteristicsMask(StreamOpFlag.DISTINCT.clear(), 0);
319 
320         assertSpliteratorCharacteristicsMask(StreamOpFlag.SORTED.set(), StreamOpFlag.IS_SORTED);
321         assertSpliteratorCharacteristicsMask(StreamOpFlag.SORTED.clear(), 0);
322 
323         assertSpliteratorCharacteristicsMask(StreamOpFlag.ORDERED.set(), StreamOpFlag.IS_ORDERED);
324         assertSpliteratorCharacteristicsMask(StreamOpFlag.ORDERED.clear(), 0);
325 
326         assertSpliteratorCharacteristicsMask(StreamOpFlag.SIZED.set(), StreamOpFlag.IS_SIZED);
327         assertSpliteratorCharacteristicsMask(StreamOpFlag.SIZED.clear(), 0);
328 
329         assertSpliteratorCharacteristicsMask(StreamOpFlag.SHORT_CIRCUIT.set(), 0);
330         assertSpliteratorCharacteristicsMask(StreamOpFlag.SHORT_CIRCUIT.clear(), 0);
331     }
332 
assertSpliteratorCharacteristicsMask(int actual, int expected)333     private void assertSpliteratorCharacteristicsMask(int actual, int expected) {
334         assertEquals(StreamOpFlag.fromCharacteristics(actual), expected);
335     }
336 
testSpliteratorSorted()337     public void testSpliteratorSorted() {
338         class SortedEmptySpliterator implements Spliterator<Object> {
339             final Comparator<Object> c;
340 
341             SortedEmptySpliterator(Comparator<Object> c) {
342                 this.c = c;
343             }
344 
345             @Override
346             public Spliterator<Object> trySplit() {
347                 return null;
348             }
349 
350             @Override
351             public boolean tryAdvance(Consumer<? super Object> action) {
352                 return false;
353             }
354 
355             @Override
356             public long estimateSize() {
357                 return Long.MAX_VALUE;
358             }
359 
360             @Override
361             public int characteristics() {
362                 return Spliterator.SORTED;
363             }
364 
365             @Override
366             public Comparator<? super Object> getComparator() {
367                 return c;
368             }
369         };
370 
371         {
372             int flags = StreamOpFlag.fromCharacteristics(new SortedEmptySpliterator(null));
373             assertEquals(flags, StreamOpFlag.IS_SORTED);
374         }
375 
376         {
377             int flags = StreamOpFlag.fromCharacteristics(new SortedEmptySpliterator((a, b) -> 0));
378             assertEquals(flags, 0);
379         }
380     }
381 }
382