View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.collections4;
18  
19  import static org.junit.jupiter.api.Assertions.assertEquals;
20  import static org.junit.jupiter.api.Assertions.assertFalse;
21  import static org.junit.jupiter.api.Assertions.assertInstanceOf;
22  import static org.junit.jupiter.api.Assertions.assertNotSame;
23  import static org.junit.jupiter.api.Assertions.assertNull;
24  import static org.junit.jupiter.api.Assertions.assertSame;
25  import static org.junit.jupiter.api.Assertions.assertThrows;
26  import static org.junit.jupiter.api.Assertions.assertTrue;
27  
28  import java.io.ByteArrayOutputStream;
29  import java.io.PrintStream;
30  import java.text.DecimalFormat;
31  import java.text.NumberFormat;
32  import java.util.AbstractMap;
33  import java.util.ArrayList;
34  import java.util.HashMap;
35  import java.util.HashSet;
36  import java.util.List;
37  import java.util.ListResourceBundle;
38  import java.util.Map;
39  import java.util.Properties;
40  import java.util.ResourceBundle;
41  import java.util.Set;
42  import java.util.SortedMap;
43  import java.util.TreeMap;
44  
45  import org.apache.commons.collections4.collection.TransformedCollectionTest;
46  import org.apache.commons.collections4.keyvalue.DefaultKeyValue;
47  import org.apache.commons.collections4.keyvalue.DefaultMapEntry;
48  import org.apache.commons.collections4.map.HashedMap;
49  import org.apache.commons.collections4.map.LazyMap;
50  import org.apache.commons.collections4.map.MultiValueMap;
51  import org.apache.commons.collections4.map.PredicatedMap;
52  import org.apache.commons.lang3.StringUtils;
53  import org.junit.jupiter.api.Test;
54  
55  /**
56   * Tests for MapUtils.
57   */
58  @SuppressWarnings("boxing")
59  public class MapUtilsTest {
60  
61      /**
62       * Test class for populateMap(MultiMap).
63       */
64      static class X implements Comparable<X> {
65  
66          int key;
67          String name;
68  
69          X(final int key, final String name) {
70              this.key = key;
71              this.name = name;
72          }
73  
74          @Override
75          public int compareTo(final X o) {
76              return key - o.key | name.compareTo(o.name);
77          }
78  
79      }
80      private static final String THREE = "Three";
81  
82      private static final String TWO = "Two";
83  
84      private char getDecimalSeparator() {
85          final NumberFormat numberFormat = NumberFormat.getInstance();
86          if (numberFormat instanceof DecimalFormat) {
87              return ((DecimalFormat) numberFormat).getDecimalFormatSymbols().getDecimalSeparator();
88          }
89          return '.';
90      }
91  
92      public Predicate<Object> getPredicate() {
93          return String.class::isInstance;
94      }
95  
96      @Test
97      public void testConvertResourceBundle() {
98          final Map<String, String> in = new HashMap<>(5, 1);
99          in.put("1", "A");
100         in.put("2", "B");
101         in.put("3", "C");
102         in.put("4", "D");
103         in.put("5", "E");
104 
105         final ResourceBundle b = new ListResourceBundle() {
106             @Override
107             public Object[][] getContents() {
108                 final Object[][] contents = new Object[in.size()][2];
109                 int n = 0;
110                 for (final Object key : in.keySet()) {
111                     final Object val = in.get(key);
112                     contents[n][0] = key;
113                     contents[n][1] = val;
114                     ++n;
115                 }
116                 return contents;
117             }
118         };
119 
120         final Map<String, Object> out = MapUtils.toMap(b);
121 
122         assertEquals(in, out);
123     }
124 
125     @Test
126     public void testDebugAndVerbosePrintCasting() {
127         final Map<Integer, String> inner = new HashMap<>(2, 1);
128         inner.put(2, "B");
129         inner.put(3, "C");
130         final Map<Integer, Object> outer = new HashMap<>(2, 1);
131         outer.put(0, inner);
132         outer.put(1, "A");
133         final ByteArrayOutputStream out = new ByteArrayOutputStream();
134         final PrintStream outPrint = new PrintStream(out);
135         MapUtils.debugPrint(outPrint, "Print Map", outer);
136     }
137 
138     @Test
139     public void testDebugAndVerbosePrintNullMap() {
140         final ByteArrayOutputStream out = new ByteArrayOutputStream();
141         final PrintStream outPrint = new PrintStream(out);
142 
143         final String LABEL = "Print Map";
144         outPrint.println(LABEL + " = " + String.valueOf((Object) null));
145         final String EXPECTED_OUT = out.toString();
146 
147         out.reset();
148 
149         MapUtils.debugPrint(outPrint, LABEL, null);
150         assertEquals(EXPECTED_OUT, out.toString());
151 
152         out.reset();
153 
154         MapUtils.verbosePrint(outPrint, LABEL, null);
155         assertEquals(EXPECTED_OUT, out.toString());
156     }
157 
158     @Test
159     public void testDebugPrint() {
160         final ByteArrayOutputStream out = new ByteArrayOutputStream();
161         final PrintStream outPrint = new PrintStream(out);
162 
163         final String LABEL = "Print Map";
164         final String INDENT = "    ";
165 
166         outPrint.println(LABEL + " = ");
167         outPrint.println("{");
168         outPrint.println(INDENT + "0 = A " + String.class.getName());
169         outPrint.println(INDENT + "1 = ");
170         outPrint.println(INDENT + "{");
171         outPrint.println(INDENT + INDENT + "2 = B " + String.class.getName());
172         outPrint.println(INDENT + INDENT + "3 = C " + String.class.getName());
173         outPrint.println(INDENT + "} " + TreeMap.class.getName());
174         outPrint.println(INDENT + "7 = (this Map) " + TreeMap.class.getName());
175         outPrint.println("} " + TreeMap.class.getName());
176 
177         final String EXPECTED_OUT = out.toString();
178 
179         out.reset();
180 
181         final Map<Integer, String> inner = new TreeMap<>(); // treeMap guarantees order across JDKs for test
182         inner.put(2, "B");
183         inner.put(3, "C");
184 
185         final Map<Integer, Object> outer = new TreeMap<>();
186         outer.put(1, inner);
187         outer.put(0, "A");
188         outer.put(7, outer);
189 
190         MapUtils.debugPrint(outPrint, "Print Map", outer);
191         assertEquals(EXPECTED_OUT, out.toString());
192     }
193 
194     @Test
195     public void testDebugPrintNullKey() {
196         final ByteArrayOutputStream out = new ByteArrayOutputStream();
197         final PrintStream outPrint = new PrintStream(out);
198 
199         final String INDENT = "    ";
200 
201         final Map<Object, String> map = new HashMap<>();
202         map.put(null, "A");
203 
204         outPrint.println("{");
205         outPrint.println(INDENT + "null = A " + String.class.getName());
206         outPrint.println("} " + HashMap.class.getName());
207         final String EXPECTED_OUT = out.toString();
208         out.reset();
209 
210         MapUtils.debugPrint(outPrint, null, map);
211         assertEquals(EXPECTED_OUT, out.toString());
212     }
213 
214     @Test
215     public void testDebugPrintNullKeyToMap1() {
216         final ByteArrayOutputStream out = new ByteArrayOutputStream();
217         final PrintStream outPrint = new PrintStream(out);
218 
219         final String INDENT = "    ";
220 
221         final Map<Object, Map<?, ?>> map = new HashMap<>();
222         map.put(null, map);
223 
224         outPrint.println("{");
225         outPrint.println(INDENT + "null = (this Map) " + HashMap.class.getName());
226         outPrint.println("} " + HashMap.class.getName());
227         final String EXPECTED_OUT = out.toString();
228         out.reset();
229 
230         MapUtils.debugPrint(outPrint, null, map);
231         assertEquals(EXPECTED_OUT, out.toString());
232     }
233 
234     @Test
235     public void testDebugPrintNullKeyToMap2() {
236         final ByteArrayOutputStream out = new ByteArrayOutputStream();
237         final PrintStream outPrint = new PrintStream(out);
238 
239         final String INDENT = "    ";
240 
241         final Map<Object, Object> map = new HashMap<>();
242         final Map<Object, Object> map2 = new HashMap<>();
243         map.put(null, map2);
244         map2.put("2", "B");
245 
246         outPrint.println("{");
247         outPrint.println(INDENT + "null = ");
248         outPrint.println(INDENT + "{");
249         outPrint.println(INDENT + INDENT + "2 = B " + String.class.getName());
250         outPrint.println(INDENT + "} " + HashMap.class.getName());
251         outPrint.println("} " + HashMap.class.getName());
252         final String EXPECTED_OUT = out.toString();
253         out.reset();
254 
255         MapUtils.debugPrint(outPrint, null, map);
256         assertEquals(EXPECTED_OUT, out.toString());
257     }
258 
259     @Test
260     public void testDebugPrintNullLabel() {
261         final ByteArrayOutputStream out = new ByteArrayOutputStream();
262         final PrintStream outPrint = new PrintStream(out);
263 
264         final String INDENT = "    ";
265 
266         final Map<Integer, String> map = new TreeMap<>(); // treeMap guarantees order across JDKs for test
267         map.put(2, "B");
268         map.put(3, "C");
269         map.put(4, null);
270 
271         outPrint.println("{");
272         outPrint.println(INDENT + "2 = B " + String.class.getName());
273         outPrint.println(INDENT + "3 = C " + String.class.getName());
274         outPrint.println(INDENT + "4 = null");
275         outPrint.println("} " + TreeMap.class.getName());
276         final String EXPECTED_OUT = out.toString();
277         out.reset();
278 
279         MapUtils.debugPrint(outPrint, null, map);
280         assertEquals(EXPECTED_OUT, out.toString());
281     }
282 
283     @Test
284     public void testDebugPrintNullLabelAndMap() {
285         final ByteArrayOutputStream out = new ByteArrayOutputStream();
286         final PrintStream outPrint = new PrintStream(out);
287 
288         outPrint.println("null");
289         final String EXPECTED_OUT = out.toString();
290         out.reset();
291 
292         MapUtils.debugPrint(outPrint, null, null);
293         assertEquals(EXPECTED_OUT, out.toString());
294     }
295 
296     @Test
297     public void testDebugPrintNullStream() {
298         assertThrows(NullPointerException.class, () -> MapUtils.debugPrint(null, "Map", new HashMap<>()),
299                 "Should generate NullPointerException");
300     }
301 
302     @Test
303     public void testDebugPrintSelfReference() {
304         final ByteArrayOutputStream out = new ByteArrayOutputStream();
305         final PrintStream outPrint = new PrintStream(out);
306 
307         final String LABEL = "Print Map";
308         final String INDENT = "    ";
309 
310         final Map<Integer, Object> grandfather = new TreeMap<>(); // treeMap guarantees order across JDKs for test
311         final Map<Integer, Object> father = new TreeMap<>();
312         final Map<Integer, Object> son    = new TreeMap<>();
313 
314         grandfather.put(0, "A");
315         grandfather.put(1, father);
316 
317         father.put(2, "B");
318         father.put(3, grandfather);
319         father.put(4, son);
320 
321         son.put(5, "C");
322         son.put(6, grandfather);
323         son.put(7, father);
324 
325         outPrint.println(LABEL + " = ");
326         outPrint.println("{");
327         outPrint.println(INDENT + "0 = A " + String.class.getName());
328         outPrint.println(INDENT + "1 = ");
329         outPrint.println(INDENT + "{");
330         outPrint.println(INDENT + INDENT + "2 = B " + String.class.getName());
331         outPrint.println(INDENT + INDENT + "3 = (ancestor[0] Map) " + TreeMap.class.getName());
332         outPrint.println(INDENT + INDENT + "4 = ");
333         outPrint.println(INDENT + INDENT + "{");
334         outPrint.println(INDENT + INDENT + INDENT + "5 = C " + String.class.getName());
335         outPrint.println(INDENT + INDENT + INDENT + "6 = (ancestor[1] Map) " + TreeMap.class.getName());
336         outPrint.println(INDENT + INDENT + INDENT + "7 = (ancestor[0] Map) " + TreeMap.class.getName());
337         outPrint.println(INDENT + INDENT + "} " + TreeMap.class.getName());
338         outPrint.println(INDENT + "} " + TreeMap.class.getName());
339         outPrint.println("} " + TreeMap.class.getName());
340 
341         final String EXPECTED_OUT = out.toString();
342 
343         out.reset();
344         MapUtils.debugPrint(outPrint, "Print Map", grandfather);
345 
346         assertEquals(EXPECTED_OUT, out.toString());
347     }
348 
349     @Test
350     public void testEmptyIfNull() {
351         assertTrue(MapUtils.emptyIfNull(null).isEmpty());
352 
353         final Map<Long, Long> map = new HashMap<>();
354         assertSame(map, MapUtils.emptyIfNull(map));
355     }
356 
357     @Test
358     public void testFixedSizeMap() {
359         final Exception exception = assertThrows(IllegalArgumentException.class, () -> MapUtils.fixedSizeMap(new HashMap<>()).put(new Object(), new Object()));
360     }
361 
362     @Test
363     public void testFixedSizeSortedMap() {
364         final Exception exception = assertThrows(IllegalArgumentException.class, () -> MapUtils.fixedSizeSortedMap(new TreeMap<>()).put(1L, 1L));
365     }
366 
367     @Test
368     public void testGetBooleanValue() {
369         final Map<String, Object> in = new HashMap<>();
370         in.put("key", true);
371         in.put("keyNumberTrue", 1);
372         in.put("keyNumberFalse", 0);
373         in.put("keyUnmapped", new Object());
374 
375         assertFalse(MapUtils.getBooleanValue(null, "keyString", null));
376         assertFalse(MapUtils.getBooleanValue(in, null, null));
377         assertFalse(MapUtils.getBooleanValue(null, null, null));
378         assertTrue(MapUtils.getBooleanValue(in, "key", true));
379         assertTrue(MapUtils.getBooleanValue(in, "key"));
380         assertTrue(MapUtils.getBooleanValue(in, "noKey", true));
381         assertTrue(MapUtils.getBooleanValue(in, "noKey", key -> true));
382         assertFalse(MapUtils.getBooleanValue(in, "noKey"));
383         assertTrue(MapUtils.getBoolean(in, "key", true));
384         assertTrue(MapUtils.getBoolean(in, "noKey", true));
385         assertTrue(MapUtils.getBoolean(in, "noKey", key -> {
386             if (System.currentTimeMillis() > 0) {
387                 return true;
388             }
389             return false;
390         }));
391         assertNull(MapUtils.getBoolean(in, "noKey", key -> null));
392         assertFalse(MapUtils.getBooleanValue(in, "noKey", key -> null));
393         assertNull(MapUtils.getBoolean(null, "noKey"));
394         // Values are Numbers
395         assertFalse(MapUtils.getBoolean(in, "keyNumberFalse"));
396         assertTrue(MapUtils.getBoolean(in, "keyNumberTrue"));
397         assertNull(MapUtils.getBoolean(in, "keyString"));
398         assertNull(MapUtils.getBoolean(null, "keyString"));
399         assertNull(MapUtils.getBoolean(in, null));
400         assertNull(MapUtils.getBoolean(null, null));
401 
402         final Map<String, String> inStr = new HashMap<>();
403         inStr.put("str1", "true");
404 
405         assertTrue(MapUtils.getBooleanValue(inStr, "str1", true));
406         assertTrue(MapUtils.getBoolean(inStr, "str1", true));
407     }
408 
409     @Test
410     public void testGetByteValue() {
411         final Map<String, Byte> in = new HashMap<>();
412         final byte val = 100;
413         in.put("key", val);
414 
415         assertEquals(val, MapUtils.getByteValue(in, "key", val), 0);
416         assertEquals(val, MapUtils.getByteValue(in, "key"), 0);
417         assertEquals(val, MapUtils.getByteValue(in, "noKey", val), 0);
418         assertEquals(val, MapUtils.getByteValue(in, "noKey", key -> (byte) 100), 0);
419         assertEquals(0, MapUtils.getByteValue(in, "noKey"), 0);
420         assertEquals(val, MapUtils.getByte(in, "key", val), 0);
421         assertEquals(val, MapUtils.getByte(in, "noKey", val), 0);
422         assertEquals(val, MapUtils.getByte(in, "noKey", key -> val), 0);
423 
424         final Map<String, String> inStr = new HashMap<>();
425         inStr.put("str1", "100");
426 
427         assertEquals(MapUtils.getByteValue(inStr, "str1", val), val, 0);
428     }
429 
430     @Test
431     public void testGetDoubleValue() {
432         final Map<String, Double> in = new HashMap<>();
433         in.put("key", 2.0);
434 
435         assertEquals(2.0, MapUtils.getDoubleValue(in, "key", 0.0), 0);
436         assertEquals(2.0, MapUtils.getDoubleValue(in, "key"), 0);
437         assertEquals(1.0, MapUtils.getDoubleValue(in, "noKey", 1.0), 0);
438         assertEquals(5.0, MapUtils.getDoubleValue(in, "noKey", key -> 5.0D), 0);
439 
440         assertEquals(0, MapUtils.getDoubleValue(in, "noKey"), 0);
441         assertEquals(2.0, MapUtils.getDouble(in, "key", 0.0), 0);
442         assertEquals(1.0, MapUtils.getDouble(in, "noKey", 1.0), 0);
443         assertEquals(1.0, MapUtils.getDouble(in, "noKey", key -> 1.0), 0);
444 
445         final Map<String, String> inStr = new HashMap<>();
446         final char decimalSeparator = getDecimalSeparator();
447         inStr.put("str1", "2" + decimalSeparator + "0");
448 
449         assertEquals(MapUtils.getDoubleValue(inStr, "str1", 0.0), 2.0, 0);
450     }
451 
452     @Test
453     public void testGetFloatValue() {
454         final Map<String, Float> in = new HashMap<>();
455         in.put("key", 2.0f);
456 
457         assertEquals(2.0, MapUtils.getFloatValue(in, "key", 0.0f), 0);
458         assertEquals(2.0, MapUtils.getFloatValue(in, "key"), 0);
459         assertEquals(1.0, MapUtils.getFloatValue(in, "noKey", 1.0f), 0);
460         assertEquals(1.0, MapUtils.getFloatValue(in, "noKey", key -> 1.0F), 0);
461         assertEquals(0, MapUtils.getFloatValue(in, "noKey"), 0);
462         assertEquals(2.0, MapUtils.getFloat(in, "key", 0.0f), 0);
463         assertEquals(1.0, MapUtils.getFloat(in, "noKey", 1.0f), 0);
464         assertEquals(1.0, MapUtils.getFloat(in, "noKey", key -> 1.0F), 0);
465 
466         final Map<String, String> inStr = new HashMap<>();
467         final char decimalSeparator = getDecimalSeparator();
468         inStr.put("str1", "2" + decimalSeparator + "0");
469 
470         assertEquals(MapUtils.getFloatValue(inStr, "str1", 0.0f), 2.0, 0);
471     }
472 
473     @Test
474     public void testGetIntValue() {
475         final Map<String, Integer> in = new HashMap<>();
476         in.put("key", 2);
477 
478         assertEquals(2, MapUtils.getIntValue(in, "key", 0), 0);
479         assertEquals(2, MapUtils.getIntValue(in, "key"), 0);
480         assertEquals(0, MapUtils.getIntValue(in, "noKey", 0), 0);
481         assertEquals(0, MapUtils.getIntValue(in, "noKey", key -> 0), 0);
482         assertEquals(0, MapUtils.getIntValue(in, "noKey"), 0);
483         assertEquals(2, MapUtils.getInteger(in, "key", 0), 0);
484         assertEquals(0, MapUtils.getInteger(in, "noKey", 0), 0);
485         assertEquals(0, MapUtils.getInteger(in, "noKey", key -> 0), 0);
486 
487         final Map<String, String> inStr = new HashMap<>();
488         inStr.put("str1", "2");
489 
490         assertEquals(MapUtils.getIntValue(inStr, "str1", 0), 2, 0);
491     }
492 
493     @Test
494     public void testGetLongValue() {
495         final Map<String, Long> in = new HashMap<>();
496         in.put("key", 2L);
497 
498         assertEquals(2.0, MapUtils.getLongValue(in, "key", 0L), 0);
499         assertEquals(2.0, MapUtils.getLongValue(in, "key"), 0);
500         assertEquals(1, MapUtils.getLongValue(in, "noKey", 1L), 0);
501         assertEquals(1, MapUtils.getLongValue(in, "noKey", key -> 1L), 0);
502         assertEquals(0, MapUtils.getLongValue(in, "noKey"), 0);
503         assertEquals(2.0, MapUtils.getLong(in, "key", 0L), 0);
504         assertEquals(1, MapUtils.getLong(in, "noKey", 1L), 0);
505         assertEquals(1, MapUtils.getLong(in, "noKey", key -> 1L), 0);
506 
507         final Map<String, Number> in1 = new HashMap<>();
508         in1.put("key", 2);
509 
510         assertEquals(Long.valueOf(2), MapUtils.getLong(in1, "key"));
511 
512         final Map<String, String> inStr = new HashMap<>();
513         inStr.put("str1", "2");
514 
515         assertEquals(MapUtils.getLongValue(inStr, "str1", 0L), 2, 0);
516         assertEquals(MapUtils.getLong(inStr, "str1", 1L), 2, 0);
517     }
518 
519     @Test
520     public void testGetMap() {
521         final Map<String, Map<String, String>> in = new HashMap<>();
522         final Map<String, String> valMap = new HashMap<>();
523         valMap.put("key1", "value1");
524         in.put("key1", valMap);
525         final Map<?, ?> outValue =  MapUtils.getMap(in, "key1", (Map<?, ?>) null);
526 
527         assertEquals("value1", outValue.get("key1"));
528         assertNull(outValue.get("key2"));
529         assertNull(MapUtils.getMap(in, "key2", (Map<?, ?>) null));
530         assertNull(MapUtils.getMap(null, "key2", (Map<?, ?>) null));
531     }
532 
533     @Test
534     public void testGetNumber() {
535         final Map<String, Number> in = new HashMap<>();
536         final Number val = 1000;
537         in.put("key", val);
538 
539         assertEquals(val.intValue(), MapUtils.getNumber(in, "key", val).intValue(), 0);
540         assertEquals(val.intValue(), MapUtils.getNumber(in, "noKey", val).intValue(), 0);
541         assertEquals(val.intValue(), MapUtils.getNumber(in, "noKey", key -> {
542             if (true) {
543                 return val;
544             }
545             return null;
546         }).intValue(), 0);
547     }
548 
549     @Test
550     public void testGetNumberValueWithInvalidString() {
551         final Map<String, String> map = new HashMap<>();
552         map.put("key", "one");
553 
554         assertNull(MapUtils.getNumber(map, "key"));
555     }
556 
557     @Test
558     public void testGetObject() {
559         final Map<String, Object> in = new HashMap<>();
560         in.put("key", "str");
561 
562         assertEquals("str", MapUtils.getObject(in, "key", "default"));
563         assertEquals("str", MapUtils.getObject(in, "key"));
564         assertNull(MapUtils.getObject(null, "key"));
565         assertEquals("default", MapUtils.getObject(in, "noKey", "default"));
566         assertEquals("default", MapUtils.getObject(null, "noKey", "default"));
567     }
568 
569     @Test
570     public void testGetShortValue() {
571         final Map<String, Short> in = new HashMap<>();
572         final short val = 10;
573         in.put("key", val);
574 
575         assertEquals(val, MapUtils.getShortValue(in, "key", val), 0);
576         assertEquals(val, MapUtils.getShortValue(in, "key"), 0);
577         assertEquals(val, MapUtils.getShortValue(in, "noKey", val), 0);
578         assertEquals(val, MapUtils.getShortValue(in, "noKey", key -> val), 0);
579         assertEquals(0, MapUtils.getShortValue(in, "noKey"), 0);
580         assertEquals(val, MapUtils.getShort(in, "key", val), 0);
581         assertEquals(val, MapUtils.getShort(in, "noKey", val), 0);
582         assertEquals(val, MapUtils.getShort(in, "noKey", key -> val), 0);
583 
584         final Map<String, String> inStr = new HashMap<>();
585         inStr.put("str1", "10");
586 
587         assertEquals(MapUtils.getShortValue(inStr, "str1", val), val, 0);
588     }
589 
590     @Test
591     public void testGetString() {
592         final Map<String, String> in = new HashMap<>();
593         in.put("key", "str");
594 
595         assertEquals("str", MapUtils.getString(in, "key", "default"));
596         assertEquals("str", MapUtils.getString(in, "key"));
597         assertNull(MapUtils.getString(null, "key"));
598         assertEquals("default", MapUtils.getString(in, "noKey", "default"));
599         assertEquals("default", MapUtils.getString(in, "noKey", key -> {
600             if ("noKey".equals(key)) {
601                 return "default";
602             }
603             return StringUtils.EMPTY;
604         }));
605         assertEquals("default", MapUtils.getString(null, "noKey", "default"));
606     }
607 
608     @Test
609     public void testInvertEmptyMap() {
610         final Map<String, String> emptyMap = new HashMap<>();
611         final Map<String, String> resultMap = MapUtils.invertMap(emptyMap);
612         assertEquals(emptyMap, resultMap);
613     }
614 
615     @Test
616     public void testInvertMap() {
617         final Map<String, String> in = new HashMap<>(5, 1);
618         in.put("1", "A");
619         in.put("2", "B");
620         in.put("3", "C");
621         in.put("4", "D");
622         in.put("5", "E");
623 
624         final Set<String> inKeySet = new HashSet<>(in.keySet());
625         final Set<String> inValSet = new HashSet<>(in.values());
626 
627         final Map<String, String> out = MapUtils.invertMap(in);
628 
629         final Set<String> outKeySet = new HashSet<>(out.keySet());
630         final Set<String> outValSet = new HashSet<>(out.values());
631 
632         assertEquals(inKeySet, outValSet);
633         assertEquals(inValSet, outKeySet);
634 
635         assertEquals("1", out.get("A"));
636         assertEquals("2", out.get("B"));
637         assertEquals("3", out.get("C"));
638         assertEquals("4", out.get("D"));
639         assertEquals("5", out.get("E"));
640     }
641 
642     @Test
643     public void testInvertMapNull() {
644         final Map<String, String> nullMap = null;
645         final Exception exception = assertThrows(NullPointerException.class, () -> MapUtils.invertMap(nullMap));
646         final String actualMessage = exception.getMessage();
647         assertTrue(actualMessage.contains("map"));
648     }
649 
650     @Test
651     public void testIsEmptyWithEmptyMap() {
652         final Map<Object, Object> map = new HashMap<>();
653         assertTrue(MapUtils.isEmpty(map));
654     }
655 
656     @Test
657     public void testIsEmptyWithNonEmptyMap() {
658         final Map<String, String> map = new HashMap<>();
659         map.put("item", "value");
660         assertFalse(MapUtils.isEmpty(map));
661     }
662 
663     @Test
664     public void testIsEmptyWithNull() {
665         final Map<Object, Object> map = null;
666         assertTrue(MapUtils.isEmpty(map));
667     }
668 
669     @Test
670     public void testIsNotEmptyWithEmptyMap() {
671         final Map<Object, Object> map = new HashMap<>();
672         assertFalse(MapUtils.isNotEmpty(map));
673     }
674 
675     @Test
676     public void testIsNotEmptyWithNonEmptyMap() {
677         final Map<String, String> map = new HashMap<>();
678         map.put("item", "value");
679         assertTrue(MapUtils.isNotEmpty(map));
680     }
681 
682     @Test
683     public void testIsNotEmptyWithNull() {
684         final Map<Object, Object> map = null;
685         assertFalse(MapUtils.isNotEmpty(map));
686     }
687 
688     @Test
689     public void testIterableMap() {
690         assertThrows(NullPointerException.class, () -> MapUtils.iterableMap(null),
691                 "Should throw NullPointerException");
692 
693         final HashMap<String, String> map = new HashMap<>();
694         map.put("foo", "foov");
695         map.put("bar", "barv");
696         map.put("baz", "bazv");
697         final IterableMap<String, String> iMap = MapUtils.iterableMap(map);
698         assertEquals(map, iMap);
699         assertNotSame(map, iMap);
700         final HashedMap<String, String> hMap = new HashedMap<>(map);
701         assertSame(hMap, MapUtils.iterableMap(hMap));
702     }
703 
704     @Test
705     public void testIterableSortedMap() {
706         assertThrows(NullPointerException.class, () -> MapUtils.iterableSortedMap(null),
707                 "Should throw NullPointerException");
708 
709         final TreeMap<String, String> map = new TreeMap<>();
710         map.put("foo", "foov");
711         map.put("bar", "barv");
712         map.put("baz", "bazv");
713         final IterableSortedMap<String, String> iMap = MapUtils.iterableSortedMap(map);
714         assertEquals(map, iMap);
715         assertNotSame(map, iMap);
716         assertSame(iMap, MapUtils.iterableMap(iMap));
717     }
718 
719     @Test
720     public void testLazyMap() {
721         final Map<String, Integer> lazyMap = MapUtils.lazyMap(new HashMap<>(), () -> 1);
722         lazyMap.put(TWO, 2);
723 
724         assertEquals(Integer.valueOf(2), lazyMap.get(TWO));
725         assertEquals(Integer.valueOf(1), lazyMap.get(THREE));
726     }
727 
728     @Test
729     public void testLazyMapFactory() {
730         final Factory<Integer> factory = FactoryUtils.constantFactory(Integer.valueOf(5));
731         Map<Object, Object> map = MapUtils.lazyMap(new HashMap<>(), factory);
732         assertInstanceOf(LazyMap.class, map);
733         assertThrows(NullPointerException.class, () -> MapUtils.lazyMap(new HashMap<>(), (Factory<Object>) null),
734                 "Expecting NullPointerException for null factory");
735         assertThrows(NullPointerException.class, () -> MapUtils.lazyMap((Map<Object, Object>) null, factory), "Expecting NullPointerException for null map");
736         final Transformer<Object, Integer> transformer = TransformerUtils.asTransformer(factory);
737         map = MapUtils.lazyMap(new HashMap<>(), transformer);
738         assertInstanceOf(LazyMap.class, map);
739         assertThrows(NullPointerException.class, () -> MapUtils.lazyMap(new HashMap<>(), (Transformer<Object, Object>) null),
740                 "Expecting NullPointerException for null transformer");
741         assertThrows(NullPointerException.class, () -> MapUtils.lazyMap((Map<Object, Object>) null, transformer),
742                 "Expecting NullPointerException for null map");
743     }
744 
745     @Test
746     public void testLazyMapTransformer() {
747         final Map<Object, Object> map = MapUtils.lazyMap(new HashMap<>(), (Transformer<Object, Object>) mapKey -> {
748             if (mapKey instanceof String) {
749                 return Integer.valueOf((String) mapKey);
750             }
751             return null;
752         });
753 
754         assertEquals(0, map.size());
755         final Integer i1 = (Integer) map.get("5");
756         assertEquals(Integer.valueOf(5), i1);
757         assertEquals(1, map.size());
758         final Integer i2 = (Integer) map.get(new String(new char[] {'5'}));
759         assertEquals(Integer.valueOf(5), i2);
760         assertEquals(1, map.size());
761         assertSame(i1, i2);
762     }
763 
764     @Test
765     public void testLazySortedMapFactory() {
766         final SortedMap<String, Integer> lazySortedMap = MapUtils.lazySortedMap(new TreeMap<>(), () -> 1);
767         lazySortedMap.put(TWO, 2);
768 
769         assertEquals(Integer.valueOf(2), lazySortedMap.get(TWO));
770         assertEquals(Integer.valueOf(1), lazySortedMap.get(THREE));
771 
772         final Set<Map.Entry<String, Integer>> entrySet = new HashSet<>();
773         entrySet.add(new AbstractMap.SimpleEntry<>(THREE, 1));
774         entrySet.add(new AbstractMap.SimpleEntry<>(TWO, 2));
775 
776         assertEquals(entrySet, lazySortedMap.entrySet());
777     }
778 
779     @Test
780     public void testLazySortedMapTransformer() {
781         final SortedMap<String, Integer> lazySortedMap = MapUtils.lazySortedMap(new TreeMap<>(), s -> 1);
782         lazySortedMap.put(TWO, 2);
783 
784         assertEquals(Integer.valueOf(2), lazySortedMap.get(TWO));
785         assertEquals(Integer.valueOf(1), lazySortedMap.get(THREE));
786 
787         final Set<Map.Entry<String, Integer>> entrySet = new HashSet<>();
788         entrySet.add(new AbstractMap.SimpleEntry<>(THREE, 1));
789         entrySet.add(new AbstractMap.SimpleEntry<>(TWO, 2));
790 
791         assertEquals(entrySet, lazySortedMap.entrySet());
792     }
793 
794     @Test
795     public void testOrderedMap() {
796         final Map<String, String> inMap = new HashMap<>();
797         inMap.put("key1", "value1");
798         inMap.put("key2", "value2");
799         final Map<String, String> map = MapUtils.orderedMap(inMap);
800         assertInstanceOf(OrderedMap.class, map);
801     }
802 
803     @Test
804     public void testPopulateMap() {
805         // Setup Test Data
806         final List<String> list = new ArrayList<>();
807         list.add("1");
808         list.add("3");
809         list.add("5");
810         list.add("7");
811         list.add("2");
812         list.add("4");
813         list.add("6");
814 
815         // Now test key transform population
816         Map<Object, Object> map = new HashMap<>();
817         MapUtils.populateMap(map, list, TransformedCollectionTest.STRING_TO_INTEGER_TRANSFORMER);
818         assertEquals(list.size(), map.size());
819 
820         for (final String element : list) {
821             assertTrue(map.containsKey(Integer.valueOf(element)));
822             assertFalse(map.containsKey(element));
823             assertTrue(map.containsValue(element));
824             assertEquals(element, map.get(Integer.valueOf(element)));
825         }
826 
827         // Now test both Key-Value transform population
828         map = new HashMap<>();
829         MapUtils.populateMap(map, list, TransformedCollectionTest.STRING_TO_INTEGER_TRANSFORMER, TransformedCollectionTest.STRING_TO_INTEGER_TRANSFORMER);
830 
831         assertEquals(list.size(), map.size());
832         for (final String element : list) {
833             assertTrue(map.containsKey(Integer.valueOf(element)));
834             assertFalse(map.containsKey(element));
835             assertTrue(map.containsValue(Integer.valueOf(element)));
836             assertEquals(Integer.valueOf(element), map.get(Integer.valueOf(element)));
837         }
838     }
839 
840     @Test
841     public void testPopulateMultiMap() {
842         // Setup Test Data
843         final List<X> list = new ArrayList<>();
844         list.add(new X(1, "x1"));
845         list.add(new X(2, "x2"));
846         list.add(new X(2, "x3"));
847         list.add(new X(5, "x4"));
848         list.add(new X(5, "x5"));
849 
850         // Now test key transform population
851         final MultiValueMap<Integer, X> map = MultiValueMap.multiValueMap(new TreeMap<>());
852         MapUtils.populateMap(map, list, (Transformer<X, Integer>) input -> input.key, TransformerUtils.<X>nopTransformer());
853         assertEquals(list.size(), map.totalSize());
854 
855         for (final X element : list) {
856             assertTrue(map.containsKey(element.key));
857             assertTrue(map.containsValue(element));
858         }
859     }
860 
861     @Test
862     public void testPredicatedMap() {
863         final Predicate<Object> p = getPredicate();
864         final Map<Object, Object> map = MapUtils.predicatedMap(new HashMap<>(), p, p);
865         assertInstanceOf(PredicatedMap.class, map);
866 
867         assertThrows(NullPointerException.class, () -> MapUtils.predicatedMap(null, p, p),
868                 "Expecting NullPointerException for null map.");
869     }
870 
871     @Test
872     public void testPutAll_Map_array() {
873 
874         assertThrows(NullPointerException.class, () -> MapUtils.putAll(null, null));
875         assertThrows(NullPointerException.class, () -> MapUtils.putAll(null, new Object[0]));
876         Map<String, String> test = MapUtils.putAll(new HashMap<>(), org.apache.commons.lang3.ArrayUtils.EMPTY_STRING_ARRAY);
877         assertEquals(0, test.size());
878 
879         // sub array
880         test = MapUtils.putAll(new HashMap<>(), new String[][] {
881                 {"RED", "#FF0000"},
882                 {"GREEN", "#00FF00"},
883                 {"BLUE", "#0000FF"}
884         });
885         assertTrue(test.containsKey("RED"));
886         assertEquals("#FF0000", test.get("RED"));
887         assertTrue(test.containsKey("GREEN"));
888         assertEquals("#00FF00", test.get("GREEN"));
889         assertTrue(test.containsKey("BLUE"));
890         assertEquals("#0000FF", test.get("BLUE"));
891         assertEquals(3, test.size());
892 
893         assertThrows(IllegalArgumentException.class,
894                 () -> MapUtils.putAll(new HashMap<>(), new String[][] { { "RED", "#FF0000" }, null, { "BLUE", "#0000FF" } }));
895         assertThrows(IllegalArgumentException.class,
896                 () -> MapUtils.putAll(new HashMap<>(), new String[][] { { "RED", "#FF0000" }, { "GREEN" }, { "BLUE", "#0000FF" } }));
897         assertThrows(IllegalArgumentException.class,
898                 () -> MapUtils.putAll(new HashMap<>(), new String[][] { { "RED", "#FF0000" }, {}, { "BLUE", "#0000FF" } }));
899         // flat array
900         test = MapUtils.putAll(new HashMap<>(), new String[] {
901             "RED", "#FF0000",
902             "GREEN", "#00FF00",
903             "BLUE", "#0000FF"
904         });
905         assertTrue(test.containsKey("RED"));
906         assertEquals("#FF0000", test.get("RED"));
907         assertTrue(test.containsKey("GREEN"));
908         assertEquals("#00FF00", test.get("GREEN"));
909         assertTrue(test.containsKey("BLUE"));
910         assertEquals("#0000FF", test.get("BLUE"));
911         assertEquals(3, test.size());
912 
913         test = MapUtils.putAll(new HashMap<>(), new String[] {
914             "RED", "#FF0000",
915             "GREEN", "#00FF00",
916             "BLUE", "#0000FF",
917             "PURPLE" // ignored
918         });
919         assertTrue(test.containsKey("RED"));
920         assertEquals("#FF0000", test.get("RED"));
921         assertTrue(test.containsKey("GREEN"));
922         assertEquals("#00FF00", test.get("GREEN"));
923         assertTrue(test.containsKey("BLUE"));
924         assertEquals("#0000FF", test.get("BLUE"));
925         assertEquals(3, test.size());
926 
927         test = MapUtils.putAll(new HashMap<>(), null);
928         assertEquals(0, test.size());
929 
930         // map entry
931         test = MapUtils.putAll(new HashMap<>(), new Object[] {
932             new DefaultMapEntry<>("RED", "#FF0000"),
933             new DefaultMapEntry<>("GREEN", "#00FF00"),
934             new DefaultMapEntry<>("BLUE", "#0000FF")
935         });
936         assertTrue(test.containsKey("RED"));
937         assertEquals("#FF0000", test.get("RED"));
938         assertTrue(test.containsKey("GREEN"));
939         assertEquals("#00FF00", test.get("GREEN"));
940         assertTrue(test.containsKey("BLUE"));
941         assertEquals("#0000FF", test.get("BLUE"));
942         assertEquals(3, test.size());
943 
944         // key value
945         test = MapUtils.putAll(new HashMap<>(), new Object[] {
946             new DefaultKeyValue<>("RED", "#FF0000"),
947             new DefaultKeyValue<>("GREEN", "#00FF00"),
948             new DefaultKeyValue<>("BLUE", "#0000FF")
949         });
950         assertTrue(test.containsKey("RED"));
951         assertEquals("#FF0000", test.get("RED"));
952         assertTrue(test.containsKey("GREEN"));
953         assertEquals("#00FF00", test.get("GREEN"));
954         assertTrue(test.containsKey("BLUE"));
955         assertEquals("#0000FF", test.get("BLUE"));
956         assertEquals(3, test.size());
957     }
958 
959     @Test
960     public void testSafeAddToMap() {
961 
962         final Map<String, Object> inMap = new HashMap<>();
963 
964         MapUtils.safeAddToMap(inMap, "key1", "value1");
965         MapUtils.safeAddToMap(inMap, "key2", null);
966         assertEquals("value1", inMap.get("key1"));
967         assertEquals(StringUtils.EMPTY, inMap.get("key2"));
968     }
969 
970     @Test
971     public void testSize() {
972         final HashMap<Object, Object> map = new HashMap<>();
973         map.put("A", "1");
974         map.put("B", "2");
975         assertEquals(2, MapUtils.size(map));
976     }
977 
978     @Test
979     public void testSize0() {
980         assertEquals(0, MapUtils.size(new HashMap<>()));
981     }
982 
983     @Test
984     public void testSizeNull() {
985         assertEquals(0, MapUtils.size(null));
986     }
987 
988     @Test
989     public void testToProperties() {
990         final Map<String, String> in = new HashMap<>();
991         in.put("key1", "A");
992         in.put("key2", "B");
993         in.put("key3", "C");
994 
995         final Properties out =  MapUtils.toProperties(in);
996 
997         assertEquals(in.get("key1"), out.get("key1"));
998         assertEquals(in.get("key2"), out.get("key2"));
999         assertEquals(in.get("key3"), out.get("key3"));
1000     }
1001 
1002     @Test
1003     public void testToPropertiesEmpty() {
1004         final Map<String, String> in = null;
1005         final Properties out =  MapUtils.toProperties(in);
1006 
1007         assertEquals(out.size(), 0);
1008     }
1009 
1010     @Test
1011     public void testTransformedMap() {
1012         final Map<Long, Long> map = new HashMap<>();
1013 
1014         final Map<Long, Long> transformedMap = MapUtils.transformedMap(map, i -> i + 1, i -> i + 10);
1015         transformedMap.put(1L, 100L);
1016 
1017         final Set<Map.Entry<Long, Long>> entrySet = new HashSet<>();
1018         entrySet.add(new AbstractMap.SimpleEntry<>(2L, 110L));
1019 
1020         assertEquals(entrySet, transformedMap.entrySet());
1021     }
1022 
1023     @Test
1024     public void testTransformedSortedMap() {
1025         final SortedMap<Long, Long> sortedMap = new TreeMap<>();
1026 
1027         final SortedMap<Long, Long> transformedSortedMap = MapUtils.transformedSortedMap(sortedMap, i -> i + 1, i -> i + 10);
1028         transformedSortedMap.put(2L, 200L);
1029         transformedSortedMap.put(1L, 100L);
1030 
1031         final Set<Map.Entry<Long, Long>> entrySet = new HashSet<>();
1032         entrySet.add(new AbstractMap.SimpleEntry<>(2L, 110L));
1033         entrySet.add(new AbstractMap.SimpleEntry<>(3L, 210L));
1034 
1035         assertEquals(entrySet, transformedSortedMap.entrySet());
1036     }
1037 
1038     @Test
1039     public void testUnmodifiableMap() {
1040         final Exception exception = assertThrows(UnsupportedOperationException.class, () -> MapUtils.unmodifiableMap(new HashMap<>()).clear());
1041     }
1042 
1043     @Test
1044     public void testUnmodifiableSortedMap() {
1045         final Exception exception = assertThrows(UnsupportedOperationException.class, () -> MapUtils.unmodifiableSortedMap(new TreeMap<>()).clear());
1046     }
1047 
1048     @Test
1049     public void testVerbosePrint() {
1050         final ByteArrayOutputStream out = new ByteArrayOutputStream();
1051         final PrintStream outPrint = new PrintStream(out);
1052 
1053         final String LABEL = "Print Map";
1054         final String INDENT = "    ";
1055 
1056         outPrint.println(LABEL + " = ");
1057         outPrint.println("{");
1058         outPrint.println(INDENT + "0 = A");
1059         outPrint.println(INDENT + "1 = ");
1060         outPrint.println(INDENT + "{");
1061         outPrint.println(INDENT + INDENT + "2 = B");
1062         outPrint.println(INDENT + INDENT + "3 = C");
1063         outPrint.println(INDENT + "}");
1064         outPrint.println(INDENT + "7 = (this Map)");
1065         outPrint.println("}");
1066 
1067         final String EXPECTED_OUT = out.toString();
1068 
1069         out.reset();
1070 
1071         final Map<Integer, String> inner = new TreeMap<>(); // treeMap guarantees order across JDKs for test
1072         inner.put(2, "B");
1073         inner.put(3, "C");
1074 
1075         final Map<Integer, Object> outer = new TreeMap<>();
1076         outer.put(1, inner);
1077         outer.put(0, "A");
1078         outer.put(7, outer);
1079 
1080         MapUtils.verbosePrint(outPrint, "Print Map", outer);
1081         assertEquals(EXPECTED_OUT, out.toString());
1082     }
1083 
1084     @Test
1085     public void testVerbosePrintNullKey() {
1086         final ByteArrayOutputStream out = new ByteArrayOutputStream();
1087         final PrintStream outPrint = new PrintStream(out);
1088 
1089         final String INDENT = "    ";
1090 
1091         final Map<Object, String> map = new HashMap<>();
1092         map.put(null, "A");
1093 
1094         outPrint.println("{");
1095         outPrint.println(INDENT + "null = A");
1096         outPrint.println("}");
1097         final String EXPECTED_OUT = out.toString();
1098         out.reset();
1099 
1100         MapUtils.verbosePrint(outPrint, null, map);
1101         assertEquals(EXPECTED_OUT, out.toString());
1102     }
1103 
1104     @Test
1105     public void testVerbosePrintNullKeyToMap1() {
1106         final ByteArrayOutputStream out = new ByteArrayOutputStream();
1107         final PrintStream outPrint = new PrintStream(out);
1108 
1109         final String INDENT = "    ";
1110 
1111         final Map<Object, Map<?, ?>> map = new HashMap<>();
1112         map.put(null, map);
1113 
1114         outPrint.println("{");
1115         outPrint.println(INDENT + "null = (this Map)");
1116         outPrint.println("}");
1117         final String EXPECTED_OUT = out.toString();
1118         out.reset();
1119 
1120         MapUtils.verbosePrint(outPrint, null, map);
1121         assertEquals(EXPECTED_OUT, out.toString());
1122     }
1123 
1124     @Test
1125     public void testVerbosePrintNullKeyToMap2() {
1126         final ByteArrayOutputStream out = new ByteArrayOutputStream();
1127         final PrintStream outPrint = new PrintStream(out);
1128 
1129         final String INDENT = "    ";
1130 
1131         final Map<Object, Object> map = new HashMap<>();
1132         final Map<Object, Object> map2 = new HashMap<>();
1133         map.put(null, map2);
1134         map2.put("2", "B");
1135 
1136         outPrint.println("{");
1137         outPrint.println(INDENT + "null = ");
1138         outPrint.println(INDENT + "{");
1139         outPrint.println(INDENT + INDENT + "2 = B");
1140         outPrint.println(INDENT + "}");
1141         outPrint.println("}");
1142         final String EXPECTED_OUT = out.toString();
1143         out.reset();
1144 
1145         MapUtils.verbosePrint(outPrint, null, map);
1146         assertEquals(EXPECTED_OUT, out.toString());
1147     }
1148 
1149     @Test
1150     public void testVerbosePrintNullLabel() {
1151         final ByteArrayOutputStream out = new ByteArrayOutputStream();
1152         final PrintStream outPrint = new PrintStream(out);
1153 
1154         final String INDENT = "    ";
1155 
1156         final Map<Integer, String> map = new TreeMap<>(); // treeMap guarantees order across JDKs for test
1157         map.put(2, "B");
1158         map.put(3, "C");
1159         map.put(4, null);
1160 
1161         outPrint.println("{");
1162         outPrint.println(INDENT + "2 = B");
1163         outPrint.println(INDENT + "3 = C");
1164         outPrint.println(INDENT + "4 = null");
1165         outPrint.println("}");
1166         final String EXPECTED_OUT = out.toString();
1167         out.reset();
1168 
1169         MapUtils.verbosePrint(outPrint, null, map);
1170         assertEquals(EXPECTED_OUT, out.toString());
1171     }
1172 
1173     @Test
1174     public void testVerbosePrintNullLabelAndMap() {
1175         final ByteArrayOutputStream out = new ByteArrayOutputStream();
1176         final PrintStream outPrint = new PrintStream(out);
1177 
1178         outPrint.println("null");
1179         final String EXPECTED_OUT = out.toString();
1180         out.reset();
1181 
1182         MapUtils.verbosePrint(outPrint, null, null);
1183         assertEquals(EXPECTED_OUT, out.toString());
1184     }
1185 
1186     @Test
1187     public void testVerbosePrintNullStream() {
1188         assertThrows(NullPointerException.class, () -> MapUtils.verbosePrint(null, "Map", new HashMap<>()),
1189                 "Should generate NullPointerException");
1190     }
1191 
1192     @Test
1193     public void testVerbosePrintSelfReference() {
1194         final ByteArrayOutputStream out = new ByteArrayOutputStream();
1195         final PrintStream outPrint = new PrintStream(out);
1196 
1197         final String LABEL = "Print Map";
1198         final String INDENT = "    ";
1199 
1200         final Map<Integer, Object> grandfather = new TreeMap<>(); // treeMap guarantees order across JDKs for test
1201         final Map<Integer, Object> father = new TreeMap<>();
1202         final Map<Integer, Object> son    = new TreeMap<>();
1203 
1204         grandfather.put(0, "A");
1205         grandfather.put(1, father);
1206 
1207         father.put(2, "B");
1208         father.put(3, grandfather);
1209         father.put(4, son);
1210 
1211         son.put(5, "C");
1212         son.put(6, grandfather);
1213         son.put(7, father);
1214 
1215         outPrint.println(LABEL + " = ");
1216         outPrint.println("{");
1217         outPrint.println(INDENT + "0 = A");
1218         outPrint.println(INDENT + "1 = ");
1219         outPrint.println(INDENT + "{");
1220         outPrint.println(INDENT + INDENT + "2 = B");
1221         outPrint.println(INDENT + INDENT + "3 = (ancestor[0] Map)");
1222         outPrint.println(INDENT + INDENT + "4 = ");
1223         outPrint.println(INDENT + INDENT + "{");
1224         outPrint.println(INDENT + INDENT + INDENT + "5 = C");
1225         outPrint.println(INDENT + INDENT + INDENT + "6 = (ancestor[1] Map)");
1226         outPrint.println(INDENT + INDENT + INDENT + "7 = (ancestor[0] Map)");
1227         outPrint.println(INDENT + INDENT + "}");
1228         outPrint.println(INDENT + "}");
1229         outPrint.println("}");
1230 
1231         final String EXPECTED_OUT = out.toString();
1232 
1233         out.reset();
1234         MapUtils.verbosePrint(outPrint, "Print Map", grandfather);
1235 
1236         assertEquals(EXPECTED_OUT, out.toString());
1237     }
1238 
1239 }