1 /*
  2  * Copyright (c) 2013, 2015, 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 8020156 8020009 8022326 8012913 8024405 8024408 8071477
 27  * @run testng SpliteratorCharacteristics
 28  */
 29 
 30 import org.testng.annotations.Test;
 31 
 32 import java.util.Arrays;
 33 import java.util.Collection;
 34 import java.util.Comparator;
 35 import java.util.HashMap;
 36 import java.util.HashSet;
 37 import java.util.LinkedHashMap;
 38 import java.util.LinkedHashSet;
 39 import java.util.List;
 40 import java.util.Map;
 41 import java.util.PrimitiveIterator;
 42 import java.util.Set;
 43 import java.util.SortedMap;
 44 import java.util.SortedSet;
 45 import java.util.Spliterator;
 46 import java.util.Spliterators;
 47 import java.util.TreeMap;
 48 import java.util.TreeSet;
 49 import java.util.WeakHashMap;
 50 import java.util.concurrent.ConcurrentSkipListMap;
 51 import java.util.concurrent.ConcurrentSkipListSet;
 52 import java.util.function.Supplier;
 53 import java.util.stream.DoubleStream;
 54 import java.util.stream.IntStream;
 55 import java.util.stream.LongStream;
 56 
 57 import static org.testng.Assert.*;
 58 
 59 @Test
 60 public class SpliteratorCharacteristics {
 61 
 62     public void testSpliteratorFromCharSequence() {
 63         class CharSequenceImpl implements CharSequence {
 64             final String s;
 65 
 66             public CharSequenceImpl(String s) {
 67                 this.s = s;
 68             }
 69 
 70             @Override
 71             public int length() {
 72                 return s.length();
 73             }
 74 
 75             @Override
 76             public char charAt(int index) {
 77                 return s.charAt(index);
 78             }
 79 
 80             @Override
 81             public CharSequence subSequence(int start, int end) {
 82                 return s.subSequence(start, end);
 83             }
 84 
 85             @Override
 86             public String toString() {
 87                 return s;
 88             }
 89         }
 90 
 91         CharSequence cs = "A";
 92         Spliterator.OfInt s = cs.chars().spliterator();
 93         assertCharacteristics(s, Spliterator.IMMUTABLE | Spliterator.ORDERED |
 94                                  Spliterator.SIZED | Spliterator.SUBSIZED);
 95         assertHasNotCharacteristics(s, Spliterator.CONCURRENT);
 96         s = cs.codePoints().spliterator();
 97         assertCharacteristics(s, Spliterator.IMMUTABLE | Spliterator.ORDERED);
 98         assertHasNotCharacteristics(s, Spliterator.CONCURRENT);
 99 
100         for (CharSequence c : Arrays.asList(new CharSequenceImpl("A"),
101                                              new StringBuilder("A"),
102                                              new StringBuffer("A"))) {
103             s = cs.chars().spliterator();
104             assertCharacteristics(s, Spliterator.ORDERED |
105                                      Spliterator.SIZED | Spliterator.SUBSIZED);
106             assertHasNotCharacteristics(s, Spliterator.CONCURRENT);
107             s = cs.codePoints().spliterator();
108             assertCharacteristics(s, Spliterator.ORDERED);
109             assertHasNotCharacteristics(s, Spliterator.CONCURRENT);
110         }
111     }
112 
113     public void testSpliteratorFromCollection() {
114         List<Integer> l = Arrays.asList(1, 2, 3, 4);
115 
116         {
117             Spliterator<?> s = Spliterators.spliterator(l, 0);
118             assertCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
119             assertHasNotCharacteristics(s, Spliterator.CONCURRENT);
120         }
121 
122         {
123             Spliterator<?> s = Spliterators.spliterator(l, Spliterator.CONCURRENT);
124             assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
125             assertCharacteristics(s, Spliterator.CONCURRENT);
126         }
127 
128         {
129             Spliterator<?> s = Spliterators.spliterator(l.iterator(), 1, 0);
130             assertCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
131             assertHasNotCharacteristics(s, Spliterator.CONCURRENT);
132         }
133 
134         {
135             Spliterator<?> s = Spliterators.spliterator(l.iterator(), 1, Spliterator.CONCURRENT);
136             assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
137             assertCharacteristics(s, Spliterator.CONCURRENT);
138         }
139 
140         {
141             Spliterator<?> s = Spliterators.spliteratorUnknownSize(l.iterator(), 0);
142             assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
143         }
144 
145         {
146             Spliterator<?> s = Spliterators.spliteratorUnknownSize(
147                     l.iterator(), Spliterator.SIZED | Spliterator.SUBSIZED);
148             assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
149         }
150     }
151 
152     public void testSpliteratorOfIntFromIterator() {
153         Supplier<PrimitiveIterator.OfInt> si = () -> IntStream.of(1, 2, 3, 4).iterator();
154 
155         {
156             Spliterator<?> s = Spliterators.spliterator(si.get(), 1, 0);
157             assertCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
158             assertHasNotCharacteristics(s, Spliterator.CONCURRENT);
159         }
160 
161         {
162             Spliterator<?> s = Spliterators.spliterator(si.get(), 1, Spliterator.CONCURRENT);
163             assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
164             assertCharacteristics(s, Spliterator.CONCURRENT);
165         }
166 
167         {
168             Spliterator<?> s = Spliterators.spliteratorUnknownSize(si.get(), 0);
169             assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
170         }
171 
172         {
173             Spliterator<?> s = Spliterators.spliteratorUnknownSize(
174                     si.get(), Spliterator.SIZED | Spliterator.SUBSIZED);
175             assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
176         }
177     }
178 
179     public void testSpliteratorOfLongFromIterator() {
180         Supplier<PrimitiveIterator.OfLong> si = () -> LongStream.of(1, 2, 3, 4).iterator();
181 
182         {
183             Spliterator<?> s = Spliterators.spliterator(si.get(), 1, 0);
184             assertCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
185             assertHasNotCharacteristics(s, Spliterator.CONCURRENT);
186         }
187 
188         {
189             Spliterator<?> s = Spliterators.spliterator(si.get(), 1, Spliterator.CONCURRENT);
190             assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
191             assertCharacteristics(s, Spliterator.CONCURRENT);
192         }
193 
194         {
195             Spliterator<?> s = Spliterators.spliteratorUnknownSize(si.get(), 0);
196             assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
197         }
198 
199         {
200             Spliterator<?> s = Spliterators.spliteratorUnknownSize(
201                     si.get(), Spliterator.SIZED | Spliterator.SUBSIZED);
202             assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
203         }
204     }
205 
206     public void testSpliteratorOfDoubleFromIterator() {
207         Supplier<PrimitiveIterator.OfDouble> si = () -> DoubleStream.of(1, 2, 3, 4).iterator();
208 
209         {
210             Spliterator<?> s = Spliterators.spliterator(si.get(), 1, 0);
211             assertCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
212             assertHasNotCharacteristics(s, Spliterator.CONCURRENT);
213         }
214 
215         {
216             Spliterator<?> s = Spliterators.spliterator(si.get(), 1, Spliterator.CONCURRENT);
217             assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
218             assertCharacteristics(s, Spliterator.CONCURRENT);
219         }
220 
221         {
222             Spliterator<?> s = Spliterators.spliteratorUnknownSize(si.get(), 0);
223             assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
224         }
225 
226         {
227             Spliterator<?> s = Spliterators.spliteratorUnknownSize(
228                     si.get(), Spliterator.SIZED | Spliterator.SUBSIZED);
229             assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
230         }
231     }
232 
233     //
234 
235     public void testHashMap() {
236         assertMapCharacteristics(new HashMap<>(),
237                                  Spliterator.SIZED | Spliterator.DISTINCT);
238     }
239 
240     public void testWeakHashMap() {
241         assertMapCharacteristics(new WeakHashMap<>(),
242                                  Spliterator.DISTINCT);
243     }
244 
245     public void testHashSet() {
246         assertSetCharacteristics(new HashSet<>(),
247                                  Spliterator.SIZED | Spliterator.DISTINCT);
248     }
249 
250     public void testLinkedHashMap() {
251         assertMapCharacteristics(new LinkedHashMap<>(),
252                                  Spliterator.SIZED | Spliterator.DISTINCT |
253                                  Spliterator.ORDERED);
254     }
255 
256     public void testLinkedHashSet() {
257         assertSetCharacteristics(new LinkedHashSet<>(),
258                                  Spliterator.SIZED | Spliterator.DISTINCT |
259                                  Spliterator.ORDERED);
260     }
261 
262     public void testTreeMap() {
263         assertSortedMapCharacteristics(new TreeMap<>(),
264                                        Spliterator.SIZED | Spliterator.DISTINCT |
265                                        Spliterator.SORTED | Spliterator.ORDERED);
266     }
267 
268     public void testTreeMapWithComparator() {
269         assertSortedMapCharacteristics(new TreeMap<>(Comparator.reverseOrder()),
270                                        Spliterator.SIZED | Spliterator.DISTINCT |
271                                        Spliterator.SORTED | Spliterator.ORDERED);
272     }
273 
274     public void testTreeSet() {
275         assertSortedSetCharacteristics(new TreeSet<>(),
276                                        Spliterator.SIZED | Spliterator.DISTINCT |
277                                        Spliterator.SORTED | Spliterator.ORDERED);
278     }
279 
280     public void testTreeSetWithComparator() {
281         assertSortedSetCharacteristics(new TreeSet<>(Comparator.reverseOrder()),
282                                        Spliterator.SIZED | Spliterator.DISTINCT |
283                                        Spliterator.SORTED | Spliterator.ORDERED);
284     }
285 
286     public void testConcurrentSkipListMap() {
287         assertSortedMapCharacteristics(new ConcurrentSkipListMap<>(),
288                                        Spliterator.CONCURRENT | Spliterator.NONNULL |
289                                        Spliterator.DISTINCT | Spliterator.SORTED |
290                                        Spliterator.ORDERED);
291     }
292 
293     public void testConcurrentSkipListMapWithComparator() {
294         assertSortedMapCharacteristics(new ConcurrentSkipListMap<>(Comparator.<Integer>reverseOrder()),
295                                        Spliterator.CONCURRENT | Spliterator.NONNULL |
296                                        Spliterator.DISTINCT | Spliterator.SORTED |
297                                        Spliterator.ORDERED);
298     }
299 
300     public void testConcurrentSkipListSet() {
301         assertSortedSetCharacteristics(new ConcurrentSkipListSet<>(),
302                                        Spliterator.CONCURRENT | Spliterator.NONNULL |
303                                        Spliterator.DISTINCT | Spliterator.SORTED |
304                                        Spliterator.ORDERED);
305     }
306 
307     public void testConcurrentSkipListSetWithComparator() {
308         assertSortedSetCharacteristics(new ConcurrentSkipListSet<>(Comparator.reverseOrder()),
309                                        Spliterator.CONCURRENT | Spliterator.NONNULL |
310                                        Spliterator.DISTINCT | Spliterator.SORTED |
311                                        Spliterator.ORDERED);
312     }
313 
314 
315     //
316 
317 
318     void assertMapCharacteristics(Map<Integer, String> m, int keyCharacteristics) {
319         assertMapCharacteristics(m, keyCharacteristics, 0);
320     }
321 
322     void assertMapCharacteristics(Map<Integer, String> m, int keyCharacteristics, int notValueCharacteristics) {
323         initMap(m);
324 
325         assertCharacteristics(m.keySet(), keyCharacteristics);
326 
327         assertCharacteristics(m.values(),
328                               keyCharacteristics & ~(Spliterator.DISTINCT | notValueCharacteristics));
329 
330         assertCharacteristics(m.entrySet(), keyCharacteristics);
331 
332         if ((keyCharacteristics & Spliterator.SORTED) == 0) {
333             assertISEComparator(m.keySet());
334             assertISEComparator(m.values());
335             assertISEComparator(m.entrySet());
336         }
337     }
338 
339     void assertSetCharacteristics(Set<Integer> s, int keyCharacteristics) {
340         initSet(s);
341 
342         assertCharacteristics(s, keyCharacteristics);
343 
344         if ((keyCharacteristics & Spliterator.SORTED) == 0) {
345             assertISEComparator(s);
346         }
347     }
348 
349     void assertSortedMapCharacteristics(SortedMap<Integer, String> m, int keyCharacteristics) {
350         assertMapCharacteristics(m, keyCharacteristics, Spliterator.SORTED);
351 
352         Set<Integer> keys = m.keySet();
353         if (m.comparator() != null) {
354             assertNotNullComparator(keys);
355         }
356         else {
357             assertNullComparator(keys);
358         }
359 
360         assertISEComparator(m.values());
361 
362         assertNotNullComparator(m.entrySet());
363     }
364 
365     void assertSortedSetCharacteristics(SortedSet<Integer> s, int keyCharacteristics) {
366         assertSetCharacteristics(s, keyCharacteristics);
367 
368         if (s.comparator() != null) {
369             assertNotNullComparator(s);
370         }
371         else {
372             assertNullComparator(s);
373         }
374     }
375 
376     void initMap(Map<Integer, String> m) {
377         m.put(1, "4");
378         m.put(2, "3");
379         m.put(3, "2");
380         m.put(4, "1");
381     }
382 
383     void initSet(Set<Integer> s) {
384         s.addAll(Arrays.asList(1, 2, 3, 4));
385     }
386 
387     void assertCharacteristics(Collection<?> c, int expectedCharacteristics) {
388         assertCharacteristics(c.spliterator(), expectedCharacteristics);
389     }
390 
391     void assertCharacteristics(Spliterator<?> s, int expectedCharacteristics) {
392         assertTrue(s.hasCharacteristics(expectedCharacteristics),
393                    "Spliterator characteristics");
394     }
395 
396     void assertHasNotCharacteristics(Spliterator<?> s, int expectedCharacteristics) {
397         assertFalse(s.hasCharacteristics(expectedCharacteristics),
398                     "Spliterator characteristics");
399     }
400 
401     void assertNullComparator(Collection<?> c) {
402         assertNull(c.spliterator().getComparator(),
403                    "Comparator of Spliterator of Collection");
404     }
405 
406     void assertNotNullComparator(Collection<?> c) {
407         assertNotNull(c.spliterator().getComparator(),
408                       "Comparator of Spliterator of Collection");
409     }
410 
411     void assertISEComparator(Collection<?> c) {
412         assertISEComparator(c.spliterator());
413     }
414 
415     void assertISEComparator(Spliterator<?> s) {
416         boolean caught = false;
417         try {
418             s.getComparator();
419         }
420         catch (IllegalStateException e) {
421             caught = true;
422         }
423         assertTrue(caught, "Throwing IllegalStateException");
424     }
425 }