1 /*
2  * Copyright (c) 2007, 2014, 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 5017904 6356890 8004928
27  * @summary Test empty iterators, enumerations, and collections
28  */
29 
30 package test.java.util.Collections;
31 
32 import java.util.Collection;
33 import java.util.Collections;
34 import java.util.Enumeration;
35 import java.util.Hashtable;
36 import java.util.Iterator;
37 import java.util.List;
38 import java.util.Map;
39 import java.util.NoSuchElementException;
40 import java.util.concurrent.SynchronousQueue;
41 
42 import static java.util.Collections.emptyEnumeration;
43 import static java.util.Collections.emptyIterator;
44 import static java.util.Collections.emptyList;
45 import static java.util.Collections.emptyListIterator;
46 import static java.util.Collections.emptyMap;
47 import static java.util.Collections.emptySet;
48 import static java.util.Collections.nCopies;
49 import static java.util.Collections.unmodifiableMap;
50 
51 public class EmptyIterator {
52 
test(String[] args)53     void test(String[] args) throws Throwable {
54         testEmptyCollection(emptyList());
55         testEmptyCollection(emptySet());
56         testEmptyCollection(new SynchronousQueue<Object>());
57         testEmptyMap(emptyMap());
58 
59         Hashtable<?,?> emptyTable = new Hashtable<>();
60         testEmptyEnumeration(emptyTable.keys());
61         testEmptyEnumeration(emptyTable.elements());
62         testEmptyIterator(emptyTable.keySet().iterator());
63         testEmptyIterator(emptyTable.values().iterator());
64         testEmptyIterator(emptyTable.entrySet().iterator());
65 
66         final Enumeration<EmptyIterator> finalEmptyTyped = emptyEnumeration();
67         testEmptyEnumeration(finalEmptyTyped);
68 
69         final Enumeration<?> finalEmptyAbstract = emptyEnumeration();
70         testEmptyEnumeration(finalEmptyAbstract);
71 
72         testEmptyIterator(emptyIterator());
73     }
74 
testEmptyEnumeration(final Enumeration<?> e)75     void testEmptyEnumeration(final Enumeration<?> e) {
76         check(e == emptyEnumeration());
77         check(!e.hasMoreElements());
78         THROWS(NoSuchElementException.class,
79                new F(){void f(){ e.nextElement(); }});
80     }
81 
testEmptyIterator(final Iterator<?> it)82     void testEmptyIterator(final Iterator<?> it) {
83         check(it == emptyIterator());
84         check(! it.hasNext());
85         THROWS(NoSuchElementException.class,
86                new F(){void f(){ it.next(); }});
87         THROWS(IllegalStateException.class,
88                new F(){void f(){ it.remove(); }});
89     }
90 
testEmptyMap(Map<?,?> m)91     void testEmptyMap(Map<?,?> m) {
92         check(m == emptyMap());
93         check(m.entrySet().iterator() ==
94               Collections.<Map.Entry<?,?>>emptyIterator());
95         check(m.values().iterator() == emptyIterator());
96         check(m.keySet().iterator() == emptyIterator());
97         equal(m, unmodifiableMap(m));
98 
99         testEmptyCollection(m.keySet());
100         testEmptyCollection(m.entrySet());
101         testEmptyCollection(m.values());
102     }
103 
testToArray(final Collection<?> c)104     void testToArray(final Collection<?> c) {
105         Object[] a = c.toArray();
106         equal(a.length, 0);
107         equal(a.getClass().getComponentType(), Object.class);
108         THROWS(NullPointerException.class,
109                new F(){void f(){ c.toArray((Object[])null); }});
110 
111         {
112             String[] t = new String[0];
113             check(c.toArray(t) == t);
114         }
115 
116         {
117             String[] t = nCopies(10, "").toArray(new String[0]);
118             check(c.toArray(t) == t);
119             check(t[0] == null);
120             for (int i=1; i<t.length; i++)
121                 check(t[i] == "");
122         }
123     }
124 
testEmptyCollection(final Collection<?> c)125     void testEmptyCollection(final Collection<?> c) {
126         testEmptyIterator(c.iterator());
127 
128         check(c.iterator() == emptyIterator());
129         if (c instanceof List)
130             check(((List<?>)c).listIterator() == emptyListIterator());
131 
132         testToArray(c);
133     }
134 
135     //--------------------- Infrastructure ---------------------------
136     volatile int passed = 0, failed = 0;
pass()137     void pass() {passed++;}
fail()138     void fail() {failed++; Thread.dumpStack();}
fail(String msg)139     void fail(String msg) {System.err.println(msg); fail();}
unexpected(Throwable t)140     void unexpected(Throwable t) {failed++; t.printStackTrace();}
check(boolean cond)141     void check(boolean cond) {if (cond) pass(); else fail();}
equal(Object x, Object y)142     void equal(Object x, Object y) {
143         if (x == null ? y == null : x.equals(y)) pass();
144         else fail(x + " not equal to " + y);}
main(String[] args)145     public static void main(String[] args) throws Throwable {
146         new EmptyIterator().instanceMain(args);}
instanceMain(String[] args)147     void instanceMain(String[] args) throws Throwable {
148         try {test(args);} catch (Throwable t) {unexpected(t);}
149         System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
150         if (failed > 0) throw new AssertionError("Some tests failed");}
f()151     abstract class F {abstract void f() throws Throwable;}
THROWS(Class<? extends Throwable> k, F... fs)152     void THROWS(Class<? extends Throwable> k, F... fs) {
153         for (F f : fs)
154             try {f.f(); fail("Expected " + k.getName() + " not thrown");}
155             catch (Throwable t) {
156                 if (k.isAssignableFrom(t.getClass())) pass();
157                 else unexpected(t);}}
158 }
159