1 /*
2 * Copyright (c) 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 8072726
27 * @summary Tests for Enumeration-to-Iterator conversion.
28 * @run testng EnumerationAsIterator
29 */
30
31 import org.testng.annotations.DataProvider;
32 import org.testng.annotations.Test;
33
34 import java.util.ArrayList;
35 import java.util.Arrays;
36 import java.util.Collection;
37 import java.util.Collections;
38 import java.util.Enumeration;
39 import java.util.Iterator;
40 import java.util.List;
41 import java.util.NoSuchElementException;
42 import java.util.concurrent.atomic.AtomicInteger;
43 import java.util.function.Supplier;
44
45 import static org.testng.Assert.*;
46
47 @Test
48 public class EnumerationAsIterator {
49 static Object[] of(String description, Supplier<Enumeration<?>> s, Collection<?> exp) {
50 return new Object[]{description, s, exp};
51 }
52
53 static Object[] of(String description, Collection<?> c, Collection<?> exp) {
54 return of(description, () -> Collections.enumeration(c), exp);
55 }
56
57 /**
58 * A wrapper Enumeration that doesn't override the
59 * default method on Enumeration.
60 */
61 static <T> Enumeration<T> wrapInDefault(Enumeration<T> e) {
62 return new Enumeration<>() {
63 @Override
64 public boolean hasMoreElements() {
65 return e.hasMoreElements();
66 }
67
68 @Override
69 public T nextElement() {
70 return e.nextElement();
71 }
72 };
73 }
74
75 @DataProvider
76 public static Iterator<Object[]> unmodifiable() {
77 return Arrays.asList(
78 of("Default-wrapped ArrayList",
79 () -> wrapInDefault(
80 Collections.enumeration(new ArrayList<>(Arrays.asList("a")))),
81 Arrays.asList("a")),
82
83 of("Unmodifiable ArrayList",
84 Collections.unmodifiableList(new ArrayList<>(Arrays.asList("a"))),
85 Arrays.asList("a")),
86
87 of("Modifiable ArrayList",
88 new ArrayList<>(Arrays.asList("a")),
89 Arrays.asList("a"))
90 ).iterator();
91 }
92
93 @DataProvider
94 public static Iterator<Object[]> others() {
95 return Arrays.asList(
96 of("Default Collections.emptyEnumeration()",
97 () -> wrapInDefault(Collections.emptyEnumeration()),
98 Collections.emptyList()),
99
100 of("Collections.emptyEnumeration()",
101 Collections::emptyEnumeration,
102 Collections.emptyList()),
103
104 of("Collections.emptyList()",
105 Collections.emptyList(),
106 Collections.emptyList()),
107
108 of("Collections.singletonList()",
109 Collections.singletonList("a"),
110 Collections.singletonList("a")),
111
112 of("Arrays.asList(...)",
113 Arrays.asList("a", "b", "c"),
114 Arrays.asList("a", "b", "c"))
115 ).iterator();
116 }
117
118 @DataProvider
119 public static Iterator<Object[]> all() {
120 List<Object[]> all = new ArrayList<>();
121 unmodifiable().forEachRemaining(all::add);
122 others().forEachRemaining(all::add);
123 return all.iterator();
124 }
125
126 @Test(dataProvider = "all")
127 public void consumeByNext(String description, Supplier<Enumeration<?>> s, Collection<?> exp) {
128 Iterator<?> i = s.get().asIterator();
129 int count = 0;
130 while (i.hasNext()) {
131 assertTrue(i.hasNext());
132
133 i.next();
134 count++;
135 }
136 assertEquals(count, exp.size());
137
138 assertFalse(i.hasNext());
139
140 try {
141 i.next();
142 fail();
143 } catch (NoSuchElementException e) {
144 }
145 }
146
147 @Test(dataProvider = "all")
148 public void consumeByForEachRemaining(String description,
149 Supplier<Enumeration<?>> s,
150 Collection<?> exp) {
151 Iterator<?> i = s.get().asIterator();
152 AtomicInteger ai = new AtomicInteger();
153 i.forEachRemaining(e -> ai.getAndIncrement());
154 assertEquals(ai.get(), exp.size());
155 i.forEachRemaining(e -> ai.getAndIncrement());
156 assertEquals(ai.get(), exp.size());
157
158 assertFalse(i.hasNext());
159
160 try {
161 i.next();
162 fail();
163 } catch (NoSuchElementException e) {
164 }
165 }
166
167 @Test(dataProvider = "all")
168 public void consumeByNextThenForEachRemaining(String description,
169 Supplier<Enumeration<?>> s,
170 Collection<?> exp) {
171 Iterator<?> i = s.get().asIterator();
172 AtomicInteger ai = new AtomicInteger();
173 if (i.hasNext()) {
174 i.next();
175 ai.getAndIncrement();
176 }
177 i.forEachRemaining(e -> ai.getAndIncrement());
178 assertEquals(ai.get(), exp.size());
179 i.forEachRemaining(e -> ai.getAndIncrement());
180 assertEquals(ai.get(), exp.size());
181
182 assertFalse(i.hasNext());
183
184 try {
185 i.next();
186 fail();
187 } catch (NoSuchElementException e) {
188 }
189 }
190
191 @Test(dataProvider = "all")
192 public void contents(String description, Supplier<Enumeration<?>> s, Collection<?> exp) {
193 assertEquals(copy(s.get()), exp);
194 }
195
196 private List<?> copy(Enumeration<?> input) {
197 List<Object> output = new ArrayList<>();
198 input.asIterator().forEachRemaining(output::add);
199 return output;
200 }
201
202 @Test(dataProvider = "unmodifiable",
203 expectedExceptions=UnsupportedOperationException.class)
204 public void removeThrowsAfterAdvancingE(String description,
205 Supplier<Enumeration<?>> s,
206 Collection<?> exp) {
207 Enumeration<?> e = s.get();
208 e.nextElement();
209 e.asIterator().remove();
210 }
211
212 @Test(dataProvider = "unmodifiable",
213 expectedExceptions=UnsupportedOperationException.class)
214 public void removeThrowsAfterAdvancingI(String description,
215 Supplier<Enumeration<?>> s,
216 Collection<?> exp) {
217 Iterator<?> i = s.get().asIterator();
218 i.next();
219 i.remove();
220 }
221 }