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