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