1/* 2 * Copyright (c) 2013, 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 * @run testng UnmodifiableMapEntrySet 27 * @summary Unit tests for wrapping classes should delegate to default methods 28 */ 29 30import java.util.ArrayList; 31import java.util.Collections; 32import java.util.HashMap; 33import java.util.List; 34import java.util.Map; 35import java.util.Spliterator; 36import java.util.TreeMap; 37import java.util.function.Consumer; 38import java.util.function.Function; 39import java.util.function.Supplier; 40 41import org.testng.annotations.Test; 42import org.testng.annotations.DataProvider; 43 44import static org.testng.Assert.assertEquals; 45 46@Test(groups = "unit") 47public class UnmodifiableMapEntrySet { 48 static Object[][] collections; 49 50 static <M extends Map<Integer, Integer>> M fillMap(int size, M m) { 51 for (int i = 0; i < size; i++) { 52 m.put(i, i); 53 } 54 return m; 55 } 56 57 @DataProvider(name="maps") 58 static Object[][] mapCases() { 59 if (collections != null) { 60 return collections; 61 } 62 63 List<Object[]> cases = new ArrayList<>(); 64 for (int size : new int[] {1, 2, 16}) { 65 cases.add(new Object[] { 66 String.format("new HashMap(%d)", size), 67 (Supplier<Map<Integer, Integer>>) 68 () -> Collections.unmodifiableMap(fillMap(size, new HashMap<>())) }); 69 cases.add(new Object[] { 70 String.format("new TreeMap(%d)", size), 71 (Supplier<Map<Integer, Integer>>) 72 () -> Collections.unmodifiableSortedMap(fillMap(size, new TreeMap<>())) }); 73 } 74 75 return cases.toArray(new Object[0][]); 76 } 77 78 static class EntryConsumer implements Consumer<Map.Entry<Integer, Integer>> { 79 int updates; 80 @Override 81 public void accept(Map.Entry<Integer, Integer> me) { 82 try { 83 me.setValue(Integer.MAX_VALUE); 84 updates++; 85 } catch (UnsupportedOperationException e) { 86 } 87 } 88 89 void assertNoUpdates() { 90 assertEquals(updates, 0, "Updates to entries"); 91 } 92 } 93 94 void testWithEntryConsumer(Consumer<EntryConsumer> c) { 95 EntryConsumer ec = new EntryConsumer(); 96 c.accept(ec); 97 ec.assertNoUpdates(); 98 } 99 100 @Test(dataProvider = "maps") 101 public void testForEach(String d, Supplier<Map<Integer, Integer>> ms) { 102 testWithEntryConsumer( 103 ec -> ms.get().entrySet().forEach(ec)); 104 } 105 106 @Test(dataProvider = "maps") 107 public void testIteratorForEachRemaining(String d, Supplier<Map<Integer, Integer>> ms) { 108 testWithEntryConsumer( 109 ec -> ms.get().entrySet().iterator().forEachRemaining(ec)); 110 } 111 112 @Test(dataProvider = "maps") 113 public void testIteratorNext(String d, Supplier<Map<Integer, Integer>> ms) { 114 testWithEntryConsumer(ec -> { 115 for (Map.Entry<Integer, Integer> me : ms.get().entrySet()) { 116 ec.accept(me); 117 } 118 }); 119 } 120 121 @Test(dataProvider = "maps") 122 public void testSpliteratorForEachRemaining(String d, Supplier<Map<Integer, Integer>> ms) { 123 testSpliterator( 124 ms.get().entrySet()::spliterator, 125 // Higher order function returning a consumer that 126 // traverses all spliterator elements using an EntryConsumer 127 s -> ec -> s.forEachRemaining(ec)); 128 } 129 130 @Test(dataProvider = "maps") 131 public void testSpliteratorTryAdvance(String d, Supplier<Map<Integer, Integer>> ms) { 132 testSpliterator( 133 ms.get().entrySet()::spliterator, 134 // Higher order function returning a consumer that 135 // traverses all spliterator elements using an EntryConsumer 136 s -> ec -> { while (s.tryAdvance(ec)); }); 137 } 138 139 void testSpliterator(Supplier<Spliterator<Map.Entry<Integer, Integer>>> ss, 140 // Higher order function that given a spliterator returns a 141 // consumer for that spliterator which traverses elements 142 // using an EntryConsumer 143 Function<Spliterator<Map.Entry<Integer, Integer>>, Consumer<EntryConsumer>> sc) { 144 testWithEntryConsumer(sc.apply(ss.get())); 145 146 Spliterator<Map.Entry<Integer, Integer>> s = ss.get(); 147 Spliterator<Map.Entry<Integer, Integer>> split = s.trySplit(); 148 if (split != null) { 149 testWithEntryConsumer(sc.apply(split)); 150 testWithEntryConsumer(sc.apply(s)); 151 } 152 } 153 154 @Test(dataProvider = "maps") 155 public void testStreamForEach(String d, Supplier<Map<Integer, Integer>> ms) { 156 testWithEntryConsumer(ec -> ms.get().entrySet().stream().forEach(ec)); 157 } 158 159 @Test(dataProvider = "maps") 160 public void testParallelStreamForEach(String d, Supplier<Map<Integer, Integer>> ms) { 161 testWithEntryConsumer(ec -> ms.get().entrySet().parallelStream().forEach(ec)); 162 } 163} 164 165