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 8010122 8004518
27 * @summary Test Map default methods
28 * @author Mike Duigou
29 * @run testng Defaults
30 */
31 import java.util.AbstractMap;
32 import java.util.AbstractSet;
33 import java.util.ArrayList;
34 import java.util.Arrays;
35 import java.util.Collection;
36 import java.util.Collections;
37 import java.util.EnumMap;
38 import java.util.HashMap;
39 import java.util.Hashtable;
40 import java.util.IdentityHashMap;
41 import java.util.Iterator;
42 import java.util.LinkedHashMap;
43 import java.util.Map;
44 import java.util.TreeMap;
45 import java.util.Set;
46 import java.util.WeakHashMap;
47 import java.util.concurrent.ConcurrentMap;
48 import java.util.concurrent.ConcurrentHashMap;
49 import java.util.concurrent.ConcurrentSkipListMap;
50 import java.util.function.Supplier;
51
52 import org.testng.annotations.Test;
53 import org.testng.annotations.DataProvider;
54 import static org.testng.Assert.fail;
55 import static org.testng.Assert.assertEquals;
56 import static org.testng.Assert.assertTrue;
57 import static org.testng.Assert.assertFalse;
58 import static org.testng.Assert.assertNull;
59 import static org.testng.Assert.assertSame;
60
61 public class Defaults {
62
63 @Test(dataProvider = "Nulls Map<IntegerEnum,String>")
64 public void testGetOrDefaultNulls(String description, Map<IntegerEnum, String> map) {
65 assertTrue(map.containsKey(null), "null key absent");
66 assertNull(map.get(null), "value not null");
67 assertSame(map.get(null), map.getOrDefault(null, EXTRA_VALUE), "values should match");
68 }
69
70 @Test(dataProvider = "Map<IntegerEnum,String>")
71 public void testGetOrDefault(String description, Map<IntegerEnum, String> map) {
72 assertTrue(map.containsKey(KEYS[1]), "expected key missing");
73 assertSame(map.get(KEYS[1]), map.getOrDefault(KEYS[1], EXTRA_VALUE), "values should match");
74 assertFalse(map.containsKey(EXTRA_KEY), "expected absent key");
75 assertSame(map.getOrDefault(EXTRA_KEY, EXTRA_VALUE), EXTRA_VALUE, "value not returned as default");
76 assertNull(map.getOrDefault(EXTRA_KEY, null), "null not returned as default");
77 }
78
79 @Test(dataProvider = "R/W Nulls Map<IntegerEnum,String>")
80 public void testPutIfAbsentNulls(String description, Map<IntegerEnum, String> map) {
81 assertTrue(map.containsKey(null), "null key absent");
82 assertNull(map.get(null), "value not null");
83 assertNull(map.putIfAbsent(null, EXTRA_VALUE), "previous not null");
84 assertTrue(map.containsKey(null), "null key absent");
85 assertSame(map.get(null), EXTRA_VALUE, "unexpected value");
86 assertSame(map.putIfAbsent(null, null), EXTRA_VALUE, "previous not expected value");
87 assertTrue(map.containsKey(null), "null key absent");
88 assertSame(map.get(null), EXTRA_VALUE, "unexpected value");
89 assertSame(map.remove(null), EXTRA_VALUE, "removed unexpected value");
90
91 assertFalse(map.containsKey(null), description + ": key present after remove");
92 assertNull(map.putIfAbsent(null, null), "previous not null");
93 assertTrue(map.containsKey(null), "null key absent");
94 assertNull(map.get(null), "value not null");
95 assertNull(map.putIfAbsent(null, EXTRA_VALUE), "previous not null");
96 assertSame(map.get(null), EXTRA_VALUE, "value not expected");
97 }
98
99 @Test(dataProvider = "R/W Map<IntegerEnum,String>")
100 public void testPutIfAbsent(String description, Map<IntegerEnum, String> map) {
101 assertTrue(map.containsKey(KEYS[1]));
102 Object expected = map.get(KEYS[1]);
103 assertTrue(null == expected || expected == VALUES[1]);
104 assertSame(map.putIfAbsent(KEYS[1], EXTRA_VALUE), expected);
105 assertSame(map.get(KEYS[1]), expected);
106
107 assertFalse(map.containsKey(EXTRA_KEY));
108 assertSame(map.putIfAbsent(EXTRA_KEY, EXTRA_VALUE), null);
109 assertSame(map.get(EXTRA_KEY), EXTRA_VALUE);
110 }
111
112 @Test(dataProvider = "Nulls Map<IntegerEnum,String>")
113 public void testForEach(String description, Map<IntegerEnum, String> map) {
114 IntegerEnum[] EACH_KEY = new IntegerEnum[map.size()];
115
116 map.forEach((k, v) -> {
117 int idx = (null == k) ? 0 : k.ordinal(); // substitute for index.
118 assertNull(EACH_KEY[idx]);
119 EACH_KEY[idx] = (idx == 0) ? KEYS[0] : k; // substitute for comparison.
120 assertSame(v, map.get(k));
121 });
122
123 assertEquals(KEYS, EACH_KEY);
124 }
125
126 @Test(dataProvider = "R/W Nulls Map<IntegerEnum,String>")
127 public static void testRemoveNulls(String description, Map<IntegerEnum, String> map) {
128 assertTrue(map.containsKey(null), "null key absent");
129 assertNull(map.get(null), "value not null");
130 assertFalse(map.remove(null, EXTRA_VALUE), description);
131 assertTrue(map.containsKey(null));
132 assertNull(map.get(null));
133 assertTrue(map.remove(null, null));
134 assertFalse(map.containsKey(null));
135 assertNull(map.get(null));
136 assertFalse(map.remove(null, null));
137 }
138
139 @Test(dataProvider = "R/W Map<IntegerEnum,String>")
140 public static void testRemove(String description, Map<IntegerEnum, String> map) {
141 assertTrue(map.containsKey(KEYS[1]));
142 Object expected = map.get(KEYS[1]);
143 assertTrue(null == expected || expected == VALUES[1]);
144 assertFalse(map.remove(KEYS[1], EXTRA_VALUE), description);
145 assertSame(map.get(KEYS[1]), expected);
146 assertTrue(map.remove(KEYS[1], expected));
147 assertNull(map.get(KEYS[1]));
148 assertFalse(map.remove(KEYS[1], expected));
149
150 assertFalse(map.containsKey(EXTRA_KEY));
151 assertFalse(map.remove(EXTRA_KEY, EXTRA_VALUE));
152 }
153
154 @Test(dataProvider = "R/W Nulls Map<IntegerEnum,String>")
155 public void testReplaceKVNulls(String description, Map<IntegerEnum, String> map) {
156 assertTrue(map.containsKey(null), "null key absent");
157 assertNull(map.get(null), "value not null");
158 assertSame(map.replace(null, EXTRA_VALUE), null);
159 assertSame(map.get(null), EXTRA_VALUE);
160 }
161
162 @Test(dataProvider = "R/W Map<IntegerEnum,String>")
163 public void testReplaceKV(String description, Map<IntegerEnum, String> map) {
164 assertTrue(map.containsKey(KEYS[1]));
165 Object expected = map.get(KEYS[1]);
166 assertTrue(null == expected || expected == VALUES[1]);
167 assertSame(map.replace(KEYS[1], EXTRA_VALUE), expected);
168 assertSame(map.get(KEYS[1]), EXTRA_VALUE);
169
170 assertFalse(map.containsKey(EXTRA_KEY));
171 assertNull(map.replace(EXTRA_KEY, EXTRA_VALUE));
172 assertFalse(map.containsKey(EXTRA_KEY));
173 assertNull(map.get(EXTRA_KEY));
174 assertNull(map.put(EXTRA_KEY, EXTRA_VALUE));
175 assertSame(map.get(EXTRA_KEY), EXTRA_VALUE);
176 assertSame(map.replace(EXTRA_KEY, (String)expected), EXTRA_VALUE);
177 assertSame(map.get(EXTRA_KEY), expected);
178 }
179
180 @Test(dataProvider = "R/W Nulls Map<IntegerEnum,String>")
181 public void testReplaceKVVNulls(String description, Map<IntegerEnum, String> map) {
182 assertTrue(map.containsKey(null), "null key absent");
183 assertNull(map.get(null), "value not null");
184 assertFalse(map.replace(null, EXTRA_VALUE, EXTRA_VALUE));
185 assertNull(map.get(null));
186 assertTrue(map.replace(null, null, EXTRA_VALUE));
187 assertSame(map.get(null), EXTRA_VALUE);
188 assertTrue(map.replace(null, EXTRA_VALUE, EXTRA_VALUE));
189 assertSame(map.get(null), EXTRA_VALUE);
190 }
191
192 @Test(dataProvider = "R/W Map<IntegerEnum,String>")
193 public void testReplaceKVV(String description, Map<IntegerEnum, String> map) {
194 assertTrue(map.containsKey(KEYS[1]));
195 Object expected = map.get(KEYS[1]);
196 assertTrue(null == expected || expected == VALUES[1]);
197 assertFalse(map.replace(KEYS[1], EXTRA_VALUE, EXTRA_VALUE));
198 assertSame(map.get(KEYS[1]), expected);
199 assertTrue(map.replace(KEYS[1], (String)expected, EXTRA_VALUE));
200 assertSame(map.get(KEYS[1]), EXTRA_VALUE);
201 assertTrue(map.replace(KEYS[1], EXTRA_VALUE, EXTRA_VALUE));
202 assertSame(map.get(KEYS[1]), EXTRA_VALUE);
203
204 assertFalse(map.containsKey(EXTRA_KEY));
205 assertFalse(map.replace(EXTRA_KEY, EXTRA_VALUE, EXTRA_VALUE));
206 assertFalse(map.containsKey(EXTRA_KEY));
207 assertNull(map.get(EXTRA_KEY));
208 assertNull(map.put(EXTRA_KEY, EXTRA_VALUE));
209 assertTrue(map.containsKey(EXTRA_KEY));
210 assertSame(map.get(EXTRA_KEY), EXTRA_VALUE);
211 assertTrue(map.replace(EXTRA_KEY, EXTRA_VALUE, EXTRA_VALUE));
212 assertSame(map.get(EXTRA_KEY), EXTRA_VALUE);
213 }
214
215 @Test(dataProvider = "R/W Nulls Map<IntegerEnum,String>")
216 public void testComputeIfAbsentNulls(String description, Map<IntegerEnum, String> map) {
217 assertTrue(map.containsKey(null), "null key absent");
218 assertNull(map.get(null), "value not null");
219 assertSame(map.computeIfAbsent(null, (k) -> EXTRA_VALUE), EXTRA_VALUE, description);
220 assertSame(map.get(null), EXTRA_VALUE, description);
221 }
222
223 @Test(dataProvider = "R/W Map<IntegerEnum,String>")
224 public void testComputeIfAbsent(String description, Map<IntegerEnum, String> map) {
225 assertTrue(map.containsKey(KEYS[1]));
226 Object expected = map.get(KEYS[1]);
227 assertTrue(null == expected || expected == VALUES[1], description + String.valueOf(expected));
228 expected = (null == expected) ? EXTRA_VALUE : expected;
229 assertSame(map.computeIfAbsent(KEYS[1], (k) -> EXTRA_VALUE), expected, description);
230 assertSame(map.get(KEYS[1]), expected, description);
231
232 assertFalse(map.containsKey(EXTRA_KEY));
233 assertSame(map.computeIfAbsent(EXTRA_KEY, (k) -> EXTRA_VALUE), EXTRA_VALUE);
234 assertSame(map.get(EXTRA_KEY), EXTRA_VALUE);
235 }
236
237 @Test(dataProvider = "R/W Nulls Map<IntegerEnum,String>")
238 public void testComputeIfPresentNulls(String description, Map<IntegerEnum, String> map) {
239 assertTrue(map.containsKey(null));
240 assertNull(map.get(null));
241 assertSame(map.computeIfPresent(null, (k, v) -> {
242 fail();
243 return EXTRA_VALUE;
244 }), null, description);
245 assertTrue(map.containsKey(null));
246 assertSame(map.get(null), null, description);
247 }
248
249 @Test(dataProvider = "R/W Map<IntegerEnum,String>")
250 public void testComputeIfPresent(String description, Map<IntegerEnum, String> map) {
251 assertTrue(map.containsKey(KEYS[1]));
252 Object value = map.get(KEYS[1]);
253 assertTrue(null == value || value == VALUES[1], description + String.valueOf(value));
254 Object expected = (null == value) ? null : EXTRA_VALUE;
255 assertSame(map.computeIfPresent(KEYS[1], (k, v) -> {
256 assertSame(v, value);
257 return EXTRA_VALUE;
258 }), expected, description);
259 assertSame(map.get(KEYS[1]), expected, description);
260
261 assertFalse(map.containsKey(EXTRA_KEY));
262 assertSame(map.computeIfPresent(EXTRA_KEY, (k, v) -> {
263 fail();
264 return EXTRA_VALUE;
265 }), null);
266 assertFalse(map.containsKey(EXTRA_KEY));
267 assertSame(map.get(EXTRA_KEY), null);
268 }
269
270 @Test(dataProvider = "R/W Nulls Map<IntegerEnum,String>")
271 public void testComputeNulls(String description, Map<IntegerEnum, String> map) {
272 assertTrue(map.containsKey(null), "null key absent");
273 assertNull(map.get(null), "value not null");
274 assertSame(map.compute(null, (k, v) -> {
275 assertSame(k, null);
276 assertNull(v);
277 return EXTRA_VALUE;
278 }), EXTRA_VALUE, description);
279 assertTrue(map.containsKey(null));
280 assertSame(map.get(null), EXTRA_VALUE, description);
281 assertSame(map.remove(null), EXTRA_VALUE, "removed value not expected");
282 assertFalse(map.containsKey(null), "null key present");
283 assertSame(map.compute(null, (k, v) -> {
284 assertSame(k, null);
285 assertNull(v);
286 return null;
287 }), null, description);
288 }
289
290 @Test(dataProvider = "R/W Map<IntegerEnum,String>")
291 public void testCompute(String description, Map<IntegerEnum, String> map) {
292 assertTrue(map.containsKey(KEYS[1]));
293 Object value = map.get(KEYS[1]);
294 assertTrue(null == value || value == VALUES[1], description + String.valueOf(value));
295 assertSame(map.compute(KEYS[1], (k, v) -> {
296 assertSame(k, KEYS[1]);
297 assertSame(v, value);
298 return EXTRA_VALUE;
299 }), EXTRA_VALUE, description);
300 assertSame(map.get(KEYS[1]), EXTRA_VALUE, description);
301 assertNull(map.compute(KEYS[1], (k, v) -> {
302 assertSame(v, EXTRA_VALUE);
303 return null;
304 }), description);
305 assertFalse(map.containsKey(KEYS[1]));
306
307 assertFalse(map.containsKey(EXTRA_KEY));
308 assertSame(map.compute(EXTRA_KEY, (k, v) -> {
309 assertNull(v);
310 return EXTRA_VALUE;
311 }), EXTRA_VALUE);
312 assertTrue(map.containsKey(EXTRA_KEY));
313 assertSame(map.get(EXTRA_KEY), EXTRA_VALUE);
314 }
315
316
317 @Test(dataProvider = "R/W Nulls Map<IntegerEnum,String>")
318 public void testMergeNulls(String description, Map<IntegerEnum, String> map) {
319 assertTrue(map.containsKey(null), "null key absent");
320 assertNull(map.get(null), "value not null");
321 assertSame(map.merge(null, EXTRA_VALUE, (v, vv) -> {
322 assertNull(v);
323 assertSame(vv, EXTRA_VALUE);
324 return vv;
325 }), EXTRA_VALUE, description);
326 assertTrue(map.containsKey(null));
327 assertSame(map.get(null), EXTRA_VALUE, description);
328 }
329
330 @Test(dataProvider = "R/W Map<IntegerEnum,String>")
331 public void testMerge(String description, Map<IntegerEnum, String> map) {
332 assertTrue(map.containsKey(KEYS[1]));
333 Object value = map.get(KEYS[1]);
334 assertTrue(null == value || value == VALUES[1], description + String.valueOf(value));
335 assertSame(map.merge(KEYS[1], EXTRA_VALUE, (v, vv) -> {
336 assertSame(v, value);
337 assertSame(vv, EXTRA_VALUE);
338 return vv;
339 }), EXTRA_VALUE, description);
340 assertSame(map.get(KEYS[1]), EXTRA_VALUE, description);
341 assertNull(map.merge(KEYS[1], EXTRA_VALUE, (v, vv) -> {
342 assertSame(v, EXTRA_VALUE);
343 assertSame(vv, EXTRA_VALUE);
344 return null;
345 }), description);
346 assertFalse(map.containsKey(KEYS[1]));
347
348 assertFalse(map.containsKey(EXTRA_KEY));
349 assertSame(map.merge(EXTRA_KEY, EXTRA_VALUE, (v, vv) -> {
350 assertNull(v);
374 /**
375 * Realized keys ensure that there is always a hard ref to all test objects.
376 */
377 private static final IntegerEnum[] KEYS = new IntegerEnum[TEST_SIZE];
378 /**
379 * Realized values ensure that there is always a hard ref to all test
380 * objects.
381 */
382 private static final String[] VALUES = new String[TEST_SIZE];
383
384 static {
385 IntegerEnum[] keys = IntegerEnum.values();
386 for (int each = 0; each < TEST_SIZE; each++) {
387 KEYS[each] = keys[each];
388 VALUES[each] = String.valueOf(each);
389 }
390 }
391 private static final IntegerEnum EXTRA_KEY = IntegerEnum.EXTRA_KEY;
392 private static final String EXTRA_VALUE = String.valueOf(TEST_SIZE);
393
394 @DataProvider(name = "Map<IntegerEnum,String>", parallel = true)
395 public static Iterator<Object[]> allNullsMapProvider() {
396 return makeAllMaps().iterator();
397 }
398
399 @DataProvider(name = "Nulls Map<IntegerEnum,String>", parallel = true)
400 public static Iterator<Object[]> allMapProvider() {
401 return makeRWMaps(true).iterator();
402 }
403
404 @DataProvider(name = "R/W Map<IntegerEnum,String>", parallel = true)
405 public static Iterator<Object[]> rwMapProvider() {
406 return makeRWMapsNoNulls().iterator();
407 }
408
409 @DataProvider(name = "R/W Nulls Map<IntegerEnum,String>", parallel = true)
410 public static Iterator<Object[]> rwNullsMapProvider() {
411 return makeRWMaps(true).iterator();
412 }
413
414 private static Collection<Object[]> makeAllMapsNoNulls() {
415 Collection<Object[]> all = new ArrayList<>();
416
417 all.addAll(makeRWMaps(false));
418 all.addAll(makeRWNoNullsMaps());
419 all.addAll(makeROMaps(false));
420
421 return all;
422 }
423
424 private static Collection<Object[]> makeRWMapsNoNulls() {
425 Collection<Object[]> all = new ArrayList<>();
426
427 all.addAll(makeRWMaps(false));
428 all.addAll(makeRWNoNullsMaps());
429
430 return all;
431 }
432
433 private static Collection<Object[]> makeAllMaps() {
434 Collection<Object[]> all = new ArrayList<>();
435
436 all.addAll(makeROMaps(false));
437 all.addAll(makeRWMaps(false));
438 all.addAll(makeRWNoNullsMaps());
439 all.addAll(makeRWMaps(true));
440 all.addAll(makeROMaps(true));
441
442 return all;
443 }
444
445 private static Collection<Object[]> makeAllRWMaps() {
446 Collection<Object[]> all = new ArrayList<>();
447
448 all.addAll(makeRWMaps(false));
449 all.addAll(makeRWNoNullsMaps());
450 all.addAll(makeRWMaps(true));
451
452 return all;
453 }
454
455 private static Collection<Object[]> makeRWMaps(boolean nulls) {
456 return Arrays.asList(
457 new Object[]{"HashMap", makeMap(HashMap::new, nulls)},
458 new Object[]{"IdentityHashMap", makeMap(IdentityHashMap::new, nulls)},
459 new Object[]{"LinkedHashMap", makeMap(LinkedHashMap::new, nulls)},
460 new Object[]{"WeakHashMap", makeMap(WeakHashMap::new, nulls)},
461 new Object[]{"Collections.checkedMap(HashMap)", Collections.checkedMap(makeMap(HashMap::new, nulls), IntegerEnum.class, String.class)},
462 new Object[]{"Collections.synchronizedMap(HashMap)", Collections.synchronizedMap(makeMap(HashMap::new, nulls))},
463 new Object[]{"ExtendsAbstractMap", makeMap(ExtendsAbstractMap::new, nulls)});
464 }
465
466 private static Collection<Object[]> makeRWNoNullsMaps() {
467 return Arrays.asList(
468 // null hostile
469 new Object[]{"EnumMap", makeMap(() -> new EnumMap(IntegerEnum.class), false)},
470 new Object[]{"Hashtable", makeMap(Hashtable::new, false)},
471 new Object[]{"TreeMap", makeMap(TreeMap::new, false)},
472 new Object[]{"ConcurrentHashMap", makeMap(ConcurrentHashMap::new, false)},
473 new Object[]{"ConcurrentSkipListMap", makeMap(ConcurrentSkipListMap::new, false)},
474 new Object[]{"Collections.checkedMap(ConcurrentHashMap)", Collections.checkedMap(makeMap(ConcurrentHashMap::new, false), IntegerEnum.class, String.class)},
475 new Object[]{"Collections.synchronizedMap(EnumMap)", Collections.synchronizedMap(makeMap(() -> new EnumMap(IntegerEnum.class), false))},
476 new Object[]{"ImplementsConcurrentMap", makeMap(ImplementsConcurrentMap::new, false)});
477 }
478
479 private static Collection<Object[]> makeROMaps(boolean nulls) {
480 return Arrays.asList(new Object[][]{
481 new Object[]{"Collections.unmodifiableMap(HashMap)", Collections.unmodifiableMap(makeMap(HashMap::new, nulls))}
482 });
483 }
484
485 private static Map<IntegerEnum, String> makeMap(Supplier<Map<IntegerEnum, String>> supplier, boolean nulls) {
486 Map<IntegerEnum, String> result = supplier.get();
487
488 for (int each = 0; each < TEST_SIZE; each++) {
489 if (nulls) {
490 result.put((each == 0) ? null : KEYS[each], null);
491 } else {
492 result.put(KEYS[each], VALUES[each]);
493 }
494 }
495
496 return result;
497 }
498
499 public interface Thrower<T extends Throwable> {
500
501 public void run() throws T;
502 }
503
504 public static <T extends Throwable> void assertThrows(Thrower<T> thrower, Class<T> throwable) {
505 assertThrows(thrower, throwable, null);
506 }
507
508 public static <T extends Throwable> void assertThrows(Thrower<T> thrower, Class<T> throwable, String message) {
509 Throwable result;
510 try {
511 thrower.run();
512 result = null;
513 } catch (Throwable caught) {
514 result = caught;
515 }
516
517 assertInstance(result, throwable,
518 (null != message)
519 ? message
520 : "Failed to throw " + throwable.getCanonicalName());
521 }
522
523 public static <T> void assertInstance(T actual, Class<? extends T> expected) {
524 assertInstance(expected.isInstance(actual), null);
525 }
526
527 public static <T> void assertInstance(T actual, Class<? extends T> expected, String message) {
528 assertTrue(expected.isInstance(actual), message);
529 }
530
531 /**
532 * A simple mutable map implementation that provides only default
533 * implementations of all methods. ie. none of the Map interface default
534 * methods have overridden implementations.
535 *
536 * @param <K> Type of keys
537 * @param <V> Type of values
538 */
539 public static class ExtendsAbstractMap<M extends Map<K,V>, K, V> extends AbstractMap<K, V> {
540
|
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 8010122 8004518
27 * @summary Test Map default methods
28 * @author Mike Duigou
29 * @run testng Defaults
30 */
31 import java.util.AbstractMap;
32 import java.util.AbstractSet;
33 import java.util.ArrayList;
34 import java.util.Arrays;
35 import java.util.Collection;
36 import java.util.Collections;
37 import java.util.EnumMap;
38 import java.util.HashMap;
39 import java.util.HashSet;
40 import java.util.Hashtable;
41 import java.util.IdentityHashMap;
42 import java.util.Iterator;
43 import java.util.LinkedHashMap;
44 import java.util.Map;
45 import java.util.TreeMap;
46 import java.util.Set;
47 import java.util.WeakHashMap;
48 import java.util.concurrent.ConcurrentMap;
49 import java.util.concurrent.ConcurrentHashMap;
50 import java.util.concurrent.ConcurrentSkipListMap;
51 import java.util.function.BiFunction;
52 import java.util.function.Supplier;
53
54 import org.testng.annotations.Test;
55 import org.testng.annotations.DataProvider;
56 import static org.testng.Assert.fail;
57 import static org.testng.Assert.assertEquals;
58 import static org.testng.Assert.assertTrue;
59 import static org.testng.Assert.assertFalse;
60 import static org.testng.Assert.assertNull;
61 import static org.testng.Assert.assertSame;
62
63 public class Defaults {
64
65 @Test(dataProvider = "Map<IntegerEnum,String> rw=all keys=withNull values=withNull")
66 public void testGetOrDefaultNulls(String description, Map<IntegerEnum, String> map) {
67 assertTrue(map.containsKey(null), description + ": null key absent");
68 assertNull(map.get(null), description + ": value not null");
69 assertSame(map.get(null), map.getOrDefault(null, EXTRA_VALUE), description + ": values should match");
70 }
71
72 @Test(dataProvider = "Map<IntegerEnum,String> rw=all keys=all values=all")
73 public void testGetOrDefault(String description, Map<IntegerEnum, String> map) {
74 assertTrue(map.containsKey(KEYS[1]), "expected key missing");
75 assertSame(map.get(KEYS[1]), map.getOrDefault(KEYS[1], EXTRA_VALUE), "values should match");
76 assertFalse(map.containsKey(EXTRA_KEY), "expected absent key");
77 assertSame(map.getOrDefault(EXTRA_KEY, EXTRA_VALUE), EXTRA_VALUE, "value not returned as default");
78 assertNull(map.getOrDefault(EXTRA_KEY, null), "null not returned as default");
79 }
80
81 @Test(dataProvider = "Map<IntegerEnum,String> rw=true keys=withNull values=withNull")
82 public void testPutIfAbsentNulls(String description, Map<IntegerEnum, String> map) {
83 assertTrue(map.containsKey(null), "null key absent");
84 assertNull(map.get(null), "value not null");
85 assertNull(map.putIfAbsent(null, EXTRA_VALUE), "previous not null");
86 assertTrue(map.containsKey(null), "null key absent");
87 assertSame(map.get(null), EXTRA_VALUE, "unexpected value");
88 assertSame(map.putIfAbsent(null, null), EXTRA_VALUE, "previous not expected value");
89 assertTrue(map.containsKey(null), "null key absent");
90 assertSame(map.get(null), EXTRA_VALUE, "unexpected value");
91 assertSame(map.remove(null), EXTRA_VALUE, "removed unexpected value");
92
93 assertFalse(map.containsKey(null), description + ": key present after remove");
94 assertNull(map.putIfAbsent(null, null), "previous not null");
95 assertTrue(map.containsKey(null), "null key absent");
96 assertNull(map.get(null), "value not null");
97 assertNull(map.putIfAbsent(null, EXTRA_VALUE), "previous not null");
98 assertSame(map.get(null), EXTRA_VALUE, "value not expected");
99 }
100
101 @Test(dataProvider = "Map<IntegerEnum,String> rw=true keys=all values=all")
102 public void testPutIfAbsent(String description, Map<IntegerEnum, String> map) {
103 assertTrue(map.containsKey(KEYS[1]));
104 Object expected = map.get(KEYS[1]);
105 assertTrue(null == expected || expected == VALUES[1]);
106 assertSame(map.putIfAbsent(KEYS[1], EXTRA_VALUE), expected);
107 assertSame(map.get(KEYS[1]), expected);
108
109 assertFalse(map.containsKey(EXTRA_KEY));
110 assertSame(map.putIfAbsent(EXTRA_KEY, EXTRA_VALUE), null);
111 assertSame(map.get(EXTRA_KEY), EXTRA_VALUE);
112 }
113
114 @Test(dataProvider = "Map<IntegerEnum,String> rw=all keys=all values=all")
115 public void testForEach(String description, Map<IntegerEnum, String> map) {
116 IntegerEnum[] EACH_KEY = new IntegerEnum[map.size()];
117
118 map.forEach((k, v) -> {
119 int idx = (null == k) ? 0 : k.ordinal(); // substitute for index.
120 assertNull(EACH_KEY[idx]);
121 EACH_KEY[idx] = (idx == 0) ? KEYS[0] : k; // substitute for comparison.
122 assertSame(v, map.get(k));
123 });
124
125 assertEquals(KEYS, EACH_KEY, description);
126 }
127
128 @Test(dataProvider = "Map<IntegerEnum,String> rw=true keys=all values=all")
129 public static void testReplaceAll(String description, Map<IntegerEnum, String> map) {
130 IntegerEnum[] EACH_KEY = new IntegerEnum[map.size()];
131 Set<String> EACH_REPLACE = new HashSet<>(map.size());
132
133 map.replaceAll((k,v) -> {
134 int idx = (null == k) ? 0 : k.ordinal(); // substitute for index.
135 assertNull(EACH_KEY[idx]);
136 EACH_KEY[idx] = (idx == 0) ? KEYS[0] : k; // substitute for comparison.
137 assertSame(v, map.get(k));
138 String replacement = v + " replaced";
139 EACH_REPLACE.add(replacement);
140 return replacement;
141 });
142
143 assertEquals(KEYS, EACH_KEY, description);
144 assertEquals(map.values().size(), EACH_REPLACE.size(), description + EACH_REPLACE);
145 assertTrue(EACH_REPLACE.containsAll(map.values()), description + " : " + EACH_REPLACE + " != " + map.values());
146 assertTrue(map.values().containsAll(EACH_REPLACE), description + " : " + EACH_REPLACE + " != " + map.values());
147 }
148
149 @Test(dataProvider = "Map<IntegerEnum,String> rw=true keys=nonNull values=nonNull")
150 public static void testReplaceAllNoNullReplacement(String description, Map<IntegerEnum, String> map) {
151 assertThrows(
152 () -> { map.replaceAll(null); },
153 NullPointerException.class,
154 description);
155 assertThrows(
156 () -> { map.replaceAll((k,v) -> null); },
157 NullPointerException.class,
158 description);
159 }
160
161 @Test(dataProvider = "Map<IntegerEnum,String> rw=true keys=withNull values=withNull")
162 public static void testRemoveNulls(String description, Map<IntegerEnum, String> map) {
163 assertTrue(map.containsKey(null), "null key absent");
164 assertNull(map.get(null), "value not null");
165 assertFalse(map.remove(null, EXTRA_VALUE), description);
166 assertTrue(map.containsKey(null));
167 assertNull(map.get(null));
168 assertTrue(map.remove(null, null));
169 assertFalse(map.containsKey(null));
170 assertNull(map.get(null));
171 assertFalse(map.remove(null, null));
172 }
173
174 @Test(dataProvider = "Map<IntegerEnum,String> rw=true keys=all values=all")
175 public static void testRemove(String description, Map<IntegerEnum, String> map) {
176 assertTrue(map.containsKey(KEYS[1]));
177 Object expected = map.get(KEYS[1]);
178 assertTrue(null == expected || expected == VALUES[1]);
179 assertFalse(map.remove(KEYS[1], EXTRA_VALUE), description);
180 assertSame(map.get(KEYS[1]), expected);
181 assertTrue(map.remove(KEYS[1], expected));
182 assertNull(map.get(KEYS[1]));
183 assertFalse(map.remove(KEYS[1], expected));
184
185 assertFalse(map.containsKey(EXTRA_KEY));
186 assertFalse(map.remove(EXTRA_KEY, EXTRA_VALUE));
187 }
188
189 @Test(dataProvider = "Map<IntegerEnum,String> rw=true keys=withNull values=withNull")
190 public void testReplaceKVNulls(String description, Map<IntegerEnum, String> map) {
191 assertTrue(map.containsKey(null), "null key absent");
192 assertNull(map.get(null), "value not null");
193 assertSame(map.replace(null, EXTRA_VALUE), null);
194 assertSame(map.get(null), EXTRA_VALUE);
195 }
196
197 @Test(dataProvider = "Map<IntegerEnum,String> rw=true keys=all values=all")
198 public void testReplaceKV(String description, Map<IntegerEnum, String> map) {
199 assertTrue(map.containsKey(KEYS[1]));
200 Object expected = map.get(KEYS[1]);
201 assertTrue(null == expected || expected == VALUES[1]);
202 assertSame(map.replace(KEYS[1], EXTRA_VALUE), expected);
203 assertSame(map.get(KEYS[1]), EXTRA_VALUE);
204
205 assertFalse(map.containsKey(EXTRA_KEY));
206 assertNull(map.replace(EXTRA_KEY, EXTRA_VALUE));
207 assertFalse(map.containsKey(EXTRA_KEY));
208 assertNull(map.get(EXTRA_KEY));
209 assertNull(map.put(EXTRA_KEY, EXTRA_VALUE));
210 assertSame(map.get(EXTRA_KEY), EXTRA_VALUE);
211 assertSame(map.replace(EXTRA_KEY, (String)expected), EXTRA_VALUE);
212 assertSame(map.get(EXTRA_KEY), expected);
213 }
214
215 @Test(dataProvider = "Map<IntegerEnum,String> rw=true keys=withNull values=withNull")
216 public void testReplaceKVVNulls(String description, Map<IntegerEnum, String> map) {
217 assertTrue(map.containsKey(null), "null key absent");
218 assertNull(map.get(null), "value not null");
219 assertFalse(map.replace(null, EXTRA_VALUE, EXTRA_VALUE));
220 assertNull(map.get(null));
221 assertTrue(map.replace(null, null, EXTRA_VALUE));
222 assertSame(map.get(null), EXTRA_VALUE);
223 assertTrue(map.replace(null, EXTRA_VALUE, EXTRA_VALUE));
224 assertSame(map.get(null), EXTRA_VALUE);
225 }
226
227 @Test(dataProvider = "Map<IntegerEnum,String> rw=true keys=all values=all")
228 public void testReplaceKVV(String description, Map<IntegerEnum, String> map) {
229 assertTrue(map.containsKey(KEYS[1]));
230 Object expected = map.get(KEYS[1]);
231 assertTrue(null == expected || expected == VALUES[1]);
232 assertFalse(map.replace(KEYS[1], EXTRA_VALUE, EXTRA_VALUE));
233 assertSame(map.get(KEYS[1]), expected);
234 assertTrue(map.replace(KEYS[1], (String)expected, EXTRA_VALUE));
235 assertSame(map.get(KEYS[1]), EXTRA_VALUE);
236 assertTrue(map.replace(KEYS[1], EXTRA_VALUE, EXTRA_VALUE));
237 assertSame(map.get(KEYS[1]), EXTRA_VALUE);
238
239 assertFalse(map.containsKey(EXTRA_KEY));
240 assertFalse(map.replace(EXTRA_KEY, EXTRA_VALUE, EXTRA_VALUE));
241 assertFalse(map.containsKey(EXTRA_KEY));
242 assertNull(map.get(EXTRA_KEY));
243 assertNull(map.put(EXTRA_KEY, EXTRA_VALUE));
244 assertTrue(map.containsKey(EXTRA_KEY));
245 assertSame(map.get(EXTRA_KEY), EXTRA_VALUE);
246 assertTrue(map.replace(EXTRA_KEY, EXTRA_VALUE, EXTRA_VALUE));
247 assertSame(map.get(EXTRA_KEY), EXTRA_VALUE);
248 }
249
250 @Test(dataProvider = "Map<IntegerEnum,String> rw=true keys=withNull values=withNull")
251 public void testComputeIfAbsentNulls(String description, Map<IntegerEnum, String> map) {
252 assertTrue(map.containsKey(null), "null key absent");
253 assertNull(map.get(null), "value not null");
254 assertSame(map.computeIfAbsent(null, (k) -> EXTRA_VALUE), EXTRA_VALUE, description);
255 assertSame(map.get(null), EXTRA_VALUE, description);
256 }
257
258 @Test(dataProvider = "Map<IntegerEnum,String> rw=true keys=all values=all")
259 public void testComputeIfAbsent(String description, Map<IntegerEnum, String> map) {
260 assertTrue(map.containsKey(KEYS[1]));
261 Object expected = map.get(KEYS[1]);
262 assertTrue(null == expected || expected == VALUES[1], description + String.valueOf(expected));
263 expected = (null == expected) ? EXTRA_VALUE : expected;
264 assertSame(map.computeIfAbsent(KEYS[1], (k) -> EXTRA_VALUE), expected, description);
265 assertSame(map.get(KEYS[1]), expected, description);
266
267 assertFalse(map.containsKey(EXTRA_KEY));
268 assertSame(map.computeIfAbsent(EXTRA_KEY, (k) -> EXTRA_VALUE), EXTRA_VALUE);
269 assertSame(map.get(EXTRA_KEY), EXTRA_VALUE);
270 }
271
272 @Test(dataProvider = "Map<IntegerEnum,String> rw=true keys=withNull values=withNull")
273 public void testComputeIfPresentNulls(String description, Map<IntegerEnum, String> map) {
274 assertTrue(map.containsKey(null));
275 assertNull(map.get(null));
276 assertSame(map.computeIfPresent(null, (k, v) -> {
277 fail();
278 return EXTRA_VALUE;
279 }), null, description);
280 assertTrue(map.containsKey(null));
281 assertSame(map.get(null), null, description);
282 }
283
284 @Test(dataProvider = "Map<IntegerEnum,String> rw=true keys=all values=all")
285 public void testComputeIfPresent(String description, Map<IntegerEnum, String> map) {
286 assertTrue(map.containsKey(KEYS[1]));
287 Object value = map.get(KEYS[1]);
288 assertTrue(null == value || value == VALUES[1], description + String.valueOf(value));
289 Object expected = (null == value) ? null : EXTRA_VALUE;
290 assertSame(map.computeIfPresent(KEYS[1], (k, v) -> {
291 assertSame(v, value);
292 return EXTRA_VALUE;
293 }), expected, description);
294 assertSame(map.get(KEYS[1]), expected, description);
295
296 assertFalse(map.containsKey(EXTRA_KEY));
297 assertSame(map.computeIfPresent(EXTRA_KEY, (k, v) -> {
298 fail();
299 return EXTRA_VALUE;
300 }), null);
301 assertFalse(map.containsKey(EXTRA_KEY));
302 assertSame(map.get(EXTRA_KEY), null);
303 }
304
305 @Test(dataProvider = "Map<IntegerEnum,String> rw=true keys=withNull values=withNull")
306 public void testComputeNulls(String description, Map<IntegerEnum, String> map) {
307 assertTrue(map.containsKey(null), "null key absent");
308 assertNull(map.get(null), "value not null");
309 assertSame(map.compute(null, (k, v) -> {
310 assertSame(k, null);
311 assertNull(v);
312 return EXTRA_VALUE;
313 }), EXTRA_VALUE, description);
314 assertTrue(map.containsKey(null));
315 assertSame(map.get(null), EXTRA_VALUE, description);
316 assertSame(map.remove(null), EXTRA_VALUE, "removed value not expected");
317 assertFalse(map.containsKey(null), "null key present");
318 assertSame(map.compute(null, (k, v) -> {
319 assertSame(k, null);
320 assertNull(v);
321 return null;
322 }), null, description);
323 }
324
325 @Test(dataProvider = "Map<IntegerEnum,String> rw=true keys=all values=all")
326 public void testCompute(String description, Map<IntegerEnum, String> map) {
327 assertTrue(map.containsKey(KEYS[1]));
328 Object value = map.get(KEYS[1]);
329 assertTrue(null == value || value == VALUES[1], description + String.valueOf(value));
330 assertSame(map.compute(KEYS[1], (k, v) -> {
331 assertSame(k, KEYS[1]);
332 assertSame(v, value);
333 return EXTRA_VALUE;
334 }), EXTRA_VALUE, description);
335 assertSame(map.get(KEYS[1]), EXTRA_VALUE, description);
336 assertNull(map.compute(KEYS[1], (k, v) -> {
337 assertSame(v, EXTRA_VALUE);
338 return null;
339 }), description);
340 assertFalse(map.containsKey(KEYS[1]));
341
342 assertFalse(map.containsKey(EXTRA_KEY));
343 assertSame(map.compute(EXTRA_KEY, (k, v) -> {
344 assertNull(v);
345 return EXTRA_VALUE;
346 }), EXTRA_VALUE);
347 assertTrue(map.containsKey(EXTRA_KEY));
348 assertSame(map.get(EXTRA_KEY), EXTRA_VALUE);
349 }
350
351
352 @Test(dataProvider = "Map<IntegerEnum,String> rw=true keys=withNull values=withNull")
353 public void testMergeNulls(String description, Map<IntegerEnum, String> map) {
354 assertTrue(map.containsKey(null), "null key absent");
355 assertNull(map.get(null), "value not null");
356 assertSame(map.merge(null, EXTRA_VALUE, (v, vv) -> {
357 assertNull(v);
358 assertSame(vv, EXTRA_VALUE);
359 return vv;
360 }), EXTRA_VALUE, description);
361 assertTrue(map.containsKey(null));
362 assertSame(map.get(null), EXTRA_VALUE, description);
363 }
364
365 @Test(dataProvider = "Map<IntegerEnum,String> rw=true keys=all values=all")
366 public void testMerge(String description, Map<IntegerEnum, String> map) {
367 assertTrue(map.containsKey(KEYS[1]));
368 Object value = map.get(KEYS[1]);
369 assertTrue(null == value || value == VALUES[1], description + String.valueOf(value));
370 assertSame(map.merge(KEYS[1], EXTRA_VALUE, (v, vv) -> {
371 assertSame(v, value);
372 assertSame(vv, EXTRA_VALUE);
373 return vv;
374 }), EXTRA_VALUE, description);
375 assertSame(map.get(KEYS[1]), EXTRA_VALUE, description);
376 assertNull(map.merge(KEYS[1], EXTRA_VALUE, (v, vv) -> {
377 assertSame(v, EXTRA_VALUE);
378 assertSame(vv, EXTRA_VALUE);
379 return null;
380 }), description);
381 assertFalse(map.containsKey(KEYS[1]));
382
383 assertFalse(map.containsKey(EXTRA_KEY));
384 assertSame(map.merge(EXTRA_KEY, EXTRA_VALUE, (v, vv) -> {
385 assertNull(v);
409 /**
410 * Realized keys ensure that there is always a hard ref to all test objects.
411 */
412 private static final IntegerEnum[] KEYS = new IntegerEnum[TEST_SIZE];
413 /**
414 * Realized values ensure that there is always a hard ref to all test
415 * objects.
416 */
417 private static final String[] VALUES = new String[TEST_SIZE];
418
419 static {
420 IntegerEnum[] keys = IntegerEnum.values();
421 for (int each = 0; each < TEST_SIZE; each++) {
422 KEYS[each] = keys[each];
423 VALUES[each] = String.valueOf(each);
424 }
425 }
426 private static final IntegerEnum EXTRA_KEY = IntegerEnum.EXTRA_KEY;
427 private static final String EXTRA_VALUE = String.valueOf(TEST_SIZE);
428
429 @DataProvider(name = "Map<IntegerEnum,String> rw=all keys=all values=all", parallel = true)
430 public static Iterator<Object[]> allMapProvider() {
431 return makeAllMaps().iterator();
432 }
433
434 @DataProvider(name = "Map<IntegerEnum,String> rw=all keys=withNull values=withNull", parallel = true)
435 public static Iterator<Object[]> allMapWithNullsProvider() {
436 return makeAllMapsWithNulls().iterator();
437 }
438
439 @DataProvider(name = "Map<IntegerEnum,String> rw=true keys=nonNull values=nonNull", parallel = true)
440 public static Iterator<Object[]> rwNonNullMapProvider() {
441 return makeRWNoNullsMaps().iterator();
442 }
443
444 @DataProvider(name = "Map<IntegerEnum,String> rw=true keys=nonNull values=all", parallel = true)
445 public static Iterator<Object[]> rwNonNullKeysMapProvider() {
446 return makeRWMapsNoNulls().iterator();
447 }
448
449 @DataProvider(name = "Map<IntegerEnum,String> rw=true keys=all values=all", parallel = true)
450 public static Iterator<Object[]> rwMapProvider() {
451 return makeAllRWMaps().iterator();
452 }
453
454 @DataProvider(name = "Map<IntegerEnum,String> rw=true keys=withNull values=withNull", parallel = true)
455 public static Iterator<Object[]> rwNullsMapProvider() {
456 return makeAllRWMapsWithNulls().iterator();
457 }
458
459 private static Collection<Object[]> makeAllRWMapsWithNulls() {
460 Collection<Object[]> all = new ArrayList<>();
461
462 all.addAll(makeRWMaps(true, true));
463
464 return all;
465 }
466
467
468 private static Collection<Object[]> makeRWMapsNoNulls() {
469 Collection<Object[]> all = new ArrayList<>();
470
471 all.addAll(makeRWNoNullKeysMaps(false));
472 all.addAll(makeRWNoNullsMaps());
473
474 return all;
475 }
476
477 private static Collection<Object[]> makeAllROMaps() {
478 Collection<Object[]> all = new ArrayList<>();
479
480 all.addAll(makeROMaps(false));
481 all.addAll(makeROMaps(true));
482
483 return all;
484 }
485
486 private static Collection<Object[]> makeAllRWMaps() {
487 Collection<Object[]> all = new ArrayList<>();
488
489 all.addAll(makeRWNoNullsMaps());
490 all.addAll(makeRWMaps(false,true));
491 all.addAll(makeRWMaps(true,true));
492 all.addAll(makeRWNoNullKeysMaps(true));
493 return all;
494 }
495
496 private static Collection<Object[]> makeAllMaps() {
497 Collection<Object[]> all = new ArrayList<>();
498
499 all.addAll(makeAllROMaps());
500 all.addAll(makeAllRWMaps());
501
502 return all;
503 }
504
505 private static Collection<Object[]> makeAllMapsWithNulls() {
506 Collection<Object[]> all = new ArrayList<>();
507
508 all.addAll(makeROMaps(true));
509 all.addAll(makeRWMaps(true,true));
510
511 return all;
512 }
513 /**
514 *
515 * @param nullKeys include null keys
516 * @param nullValues include null values
517 * @return
518 */
519 private static Collection<Object[]> makeRWMaps(boolean nullKeys, boolean nullValues) {
520 return Arrays.asList(
521 new Object[]{"HashMap", makeMap(HashMap::new, nullKeys, nullValues)},
522 new Object[]{"IdentityHashMap", makeMap(IdentityHashMap::new, nullKeys, nullValues)},
523 new Object[]{"LinkedHashMap", makeMap(LinkedHashMap::new, nullKeys, nullValues)},
524 new Object[]{"WeakHashMap", makeMap(WeakHashMap::new, nullKeys, nullValues)},
525 new Object[]{"Collections.checkedMap(HashMap)", Collections.checkedMap(makeMap(HashMap::new, nullKeys, nullValues), IntegerEnum.class, String.class)},
526 new Object[]{"Collections.synchronizedMap(HashMap)", Collections.synchronizedMap(makeMap(HashMap::new, nullKeys, nullValues))},
527 new Object[]{"ExtendsAbstractMap", makeMap(ExtendsAbstractMap::new, nullKeys, nullValues)});
528 }
529
530 /**
531 *
532 * @param nulls include null values
533 * @return
534 */
535 private static Collection<Object[]> makeRWNoNullKeysMaps(boolean nulls) {
536 return Arrays.asList(
537 // null key hostile
538 new Object[]{"EnumMap", makeMap(() -> new EnumMap(IntegerEnum.class), false, nulls)},
539 new Object[]{"Collections.synchronizedMap(EnumMap)", Collections.synchronizedMap(makeMap(() -> new EnumMap(IntegerEnum.class), false, nulls))}
540 );
541 }
542
543 private static Collection<Object[]> makeRWNoNullsMaps() {
544 return Arrays.asList(
545 // null key and value hostile
546 new Object[]{"Hashtable", makeMap(Hashtable::new, false, false)},
547 new Object[]{"TreeMap", makeMap(TreeMap::new, false, false)},
548 new Object[]{"ConcurrentHashMap", makeMap(ConcurrentHashMap::new, false, false)},
549 new Object[]{"ConcurrentSkipListMap", makeMap(ConcurrentSkipListMap::new, false, false)},
550 new Object[]{"Collections.checkedMap(ConcurrentHashMap)", Collections.checkedMap(makeMap(ConcurrentHashMap::new, false, false), IntegerEnum.class, String.class)},
551 new Object[]{"ImplementsConcurrentMap", makeMap(ImplementsConcurrentMap::new, false, false)}
552 );
553 }
554
555 /**
556 *
557 * @param nulls include nulls
558 * @return
559 */
560 private static Collection<Object[]> makeROMaps(boolean nulls) {
561 return Arrays.asList(new Object[][]{
562 new Object[]{"Collections.unmodifiableMap(HashMap)", Collections.unmodifiableMap(makeMap(HashMap::new, nulls, nulls))}
563 });
564 }
565
566 /**
567 *
568 * @param supplier a supplier of mutable map instances.
569 *
570 * @param nullKeys include null keys
571 * @param nullValues include null values
572 * @return
573 */
574 private static Map<IntegerEnum, String> makeMap(Supplier<Map<IntegerEnum, String>> supplier, boolean nullKeys, boolean nullValues) {
575 Map<IntegerEnum, String> result = supplier.get();
576
577 for (int each = 0; each < TEST_SIZE; each++) {
578 IntegerEnum key = nullKeys ? (each == 0) ? null : KEYS[each] : KEYS[each];
579 String value = nullValues ? (each == 0) ? null : VALUES[each] : VALUES[each];
580
581 result.put(key, value);
582 }
583
584 return result;
585 }
586
587 public interface Thrower<T extends Throwable> {
588
589 public void run() throws T;
590 }
591
592 public static <T extends Throwable> void assertThrows(Thrower<T> thrower, Class<T> throwable) {
593 assertThrows(thrower, throwable, null);
594 }
595
596 public static <T extends Throwable> void assertThrows(Thrower<T> thrower, Class<T> throwable, String message) {
597 Throwable result;
598 try {
599 thrower.run();
600 result = null;
601 } catch (Throwable caught) {
602 result = caught;
603 }
604
605 assertInstance(result, throwable,
606 (null != message)
607 ? message
608 : "Failed to throw " + throwable.getCanonicalName());
609 }
610
611 public static <T extends Throwable> void assertThrows(Class<T> throwable, String message, Thrower<T>... throwers) {
612 for(Thrower<T> thrower : throwers) {
613 assertThrows(thrower, throwable, message);
614 }
615 }
616
617 public static <T> void assertInstance(T actual, Class<? extends T> expected) {
618 assertInstance(expected.isInstance(actual), null);
619 }
620
621 public static <T> void assertInstance(T actual, Class<? extends T> expected, String message) {
622 assertTrue(expected.isInstance(actual), message);
623 }
624
625 /**
626 * A simple mutable map implementation that provides only default
627 * implementations of all methods. ie. none of the Map interface default
628 * methods have overridden implementations.
629 *
630 * @param <K> Type of keys
631 * @param <V> Type of values
632 */
633 public static class ExtendsAbstractMap<M extends Map<K,V>, K, V> extends AbstractMap<K, V> {
634
|