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 {
of(String description, Supplier<Enumeration<?>> s, Collection<?> exp)49     static Object[] of(String description, Supplier<Enumeration<?>> s, Collection<?> exp) {
50         return new Object[]{description, s, exp};
51     }
52 
of(String description, Collection<?> c, Collection<?> exp)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      */
wrapInDefault(Enumeration<T> e)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 }
222