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    *      https://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.lang3;
18  
19  import static org.apache.commons.lang3.LangAssertions.assertIllegalArgumentException;
20  import static org.apache.commons.lang3.LangAssertions.assertNullPointerException;
21  import static org.junit.jupiter.api.Assertions.assertArrayEquals;
22  import static org.junit.jupiter.api.Assertions.assertEquals;
23  import static org.junit.jupiter.api.Assertions.assertFalse;
24  import static org.junit.jupiter.api.Assertions.assertInstanceOf;
25  import static org.junit.jupiter.api.Assertions.assertNotNull;
26  import static org.junit.jupiter.api.Assertions.assertNotSame;
27  import static org.junit.jupiter.api.Assertions.assertNull;
28  import static org.junit.jupiter.api.Assertions.assertSame;
29  import static org.junit.jupiter.api.Assertions.assertThrows;
30  import static org.junit.jupiter.api.Assertions.assertTrue;
31  import static org.junit.jupiter.api.Assertions.fail;
32  
33  import java.io.IOException;
34  import java.lang.reflect.Constructor;
35  import java.lang.reflect.Modifier;
36  import java.time.Duration;
37  import java.util.ArrayList;
38  import java.util.Arrays;
39  import java.util.Calendar;
40  import java.util.Collections;
41  import java.util.Comparator;
42  import java.util.Date;
43  import java.util.HashMap;
44  import java.util.HashSet;
45  import java.util.List;
46  import java.util.Map;
47  import java.util.Objects;
48  import java.util.Optional;
49  import java.util.Set;
50  import java.util.function.Supplier;
51  
52  import org.apache.commons.lang3.exception.CloneFailedException;
53  import org.apache.commons.lang3.function.Suppliers;
54  import org.apache.commons.lang3.mutable.MutableInt;
55  import org.apache.commons.lang3.mutable.MutableObject;
56  import org.apache.commons.lang3.text.StrBuilder;
57  import org.junit.jupiter.api.Test;
58  
59  /**
60   * Tests {@link ObjectUtils}.
61   */
62  @SuppressWarnings("deprecation") // deliberate use of deprecated code
63  class ObjectUtilsTest extends AbstractLangTest {
64  
65      static final class CharSequenceComparator implements Comparator<CharSequence> {
66  
67          @Override
68          public int compare(final CharSequence o1, final CharSequence o2) {
69              return o1.toString().compareTo(o2.toString());
70          }
71  
72      }
73  
74      /**
75       * String that is cloneable.
76       */
77      static final class CloneableString extends MutableObject<String> implements Cloneable {
78          private static final long serialVersionUID = 1L;
79          CloneableString(final String s) {
80              super(s);
81          }
82  
83          @Override
84          public CloneableString clone() throws CloneNotSupportedException {
85              return (CloneableString) super.clone();
86          }
87      }
88  
89      static final class NonComparableCharSequence implements CharSequence {
90          final String value;
91  
92          /**
93           * Create a new NonComparableCharSequence instance.
94           *
95           * @param value the CharSequence value
96           */
97          NonComparableCharSequence(final String value) {
98              Validate.notNull(value);
99              this.value = value;
100         }
101 
102         @Override
103         public char charAt(final int arg0) {
104             return value.charAt(arg0);
105         }
106 
107         @Override
108         public int length() {
109             return value.length();
110         }
111 
112         @Override
113         public CharSequence subSequence(final int arg0, final int arg1) {
114             return value.subSequence(arg0, arg1);
115         }
116 
117         @Override
118         public String toString() {
119             return value;
120         }
121     }
122 
123     /**
124      * String that is not cloneable.
125      */
126     static final class UncloneableString extends MutableObject<String> implements Cloneable {
127         private static final long serialVersionUID = 1L;
128         UncloneableString(final String s) {
129             super(s);
130         }
131     }
132 
133     private static final Supplier<?> NULL_SUPPLIER = null;
134 
135     private static final String FOO = "foo";
136     private static final String BAR = "bar";
137     private static final String[] NON_EMPTY_ARRAY = { FOO, BAR, };
138 
139     private static final List<String> NON_EMPTY_LIST = Arrays.asList(NON_EMPTY_ARRAY);
140 
141     private static final Set<String> NON_EMPTY_SET = new HashSet<>(NON_EMPTY_LIST);
142 
143     private static final Map<String, String> NON_EMPTY_MAP = new HashMap<>();
144 
145     static {
146         NON_EMPTY_MAP.put(FOO, BAR);
147     }
148 
149     /**
150      * Tests {@link ObjectUtils#allNotNull(Object...)}.
151      */
152     @Test
153     void testAllNotNull() {
154         assertFalse(ObjectUtils.allNotNull((Object) null));
155         assertFalse(ObjectUtils.allNotNull((Object[]) null));
156         assertFalse(ObjectUtils.allNotNull(null, null, null));
157         assertFalse(ObjectUtils.allNotNull(null, FOO, BAR));
158         assertFalse(ObjectUtils.allNotNull(FOO, BAR, null));
159         assertFalse(ObjectUtils.allNotNull(FOO, BAR, null, FOO, BAR));
160 
161         assertTrue(ObjectUtils.allNotNull());
162         assertTrue(ObjectUtils.allNotNull(FOO));
163         assertTrue(ObjectUtils.allNotNull(FOO, BAR, 1, Boolean.TRUE, new Object(), new Object[]{}));
164     }
165 
166     /**
167      * Tests {@link ObjectUtils#allNull(Object...)}.
168      */
169     @Test
170     void testAllNull() {
171         assertTrue(ObjectUtils.allNull());
172         assertTrue(ObjectUtils.allNull((Object) null));
173         assertTrue(ObjectUtils.allNull((Object[]) null));
174         assertTrue(ObjectUtils.allNull(null, null, null));
175 
176         assertFalse(ObjectUtils.allNull(FOO));
177         assertFalse(ObjectUtils.allNull(null, FOO, null));
178         assertFalse(ObjectUtils.allNull(null, null, null, null, FOO, BAR));
179     }
180 
181     /**
182      * Tests {@link ObjectUtils#anyNotNull(Object...)}.
183      */
184     @Test
185     void testAnyNotNull() {
186         assertFalse(ObjectUtils.anyNotNull());
187         assertFalse(ObjectUtils.anyNotNull((Object) null));
188         assertFalse(ObjectUtils.anyNotNull((Object[]) null));
189         assertFalse(ObjectUtils.anyNotNull(null, null, null));
190 
191         assertTrue(ObjectUtils.anyNotNull(FOO));
192         assertTrue(ObjectUtils.anyNotNull(null, FOO, null));
193         assertTrue(ObjectUtils.anyNotNull(null, null, null, null, FOO, BAR));
194     }
195 
196     /**
197      * Tests {@link ObjectUtils#anyNull(Object...)}.
198      */
199     @Test
200     void testAnyNull() {
201         assertTrue(ObjectUtils.anyNull((Object) null));
202         assertTrue(ObjectUtils.anyNull(null, null, null));
203         assertTrue(ObjectUtils.anyNull(null, FOO, BAR));
204         assertTrue(ObjectUtils.anyNull(FOO, BAR, null));
205         assertTrue(ObjectUtils.anyNull(FOO, BAR, null, FOO, BAR));
206 
207         assertFalse(ObjectUtils.anyNull());
208         assertFalse(ObjectUtils.anyNull(FOO));
209         assertFalse(ObjectUtils.anyNull(FOO, BAR, 1, Boolean.TRUE, new Object(), new Object[]{}));
210     }
211 
212     /**
213      * Test for {@link ObjectUtils#isArray(Object)}.
214      */
215     @Test
216     void testArray() {
217         assertFalse(ObjectUtils.isArray(null));
218         assertFalse(ObjectUtils.isArray(""));
219         assertFalse(ObjectUtils.isArray("abg"));
220         assertFalse(ObjectUtils.isArray(123));
221         assertTrue(ObjectUtils.isArray(NON_EMPTY_ARRAY));
222         assertTrue(ObjectUtils.isArray(new int[]{1, 2, 3}));
223         assertTrue(ObjectUtils.isArray(ArrayUtils.EMPTY_BOOLEAN_ARRAY));
224         assertTrue(ObjectUtils.isArray(ArrayUtils.EMPTY_BOOLEAN_ARRAY));
225         assertTrue(ObjectUtils.isArray(ArrayUtils.EMPTY_BOOLEAN_OBJECT_ARRAY));
226         assertTrue(ObjectUtils.isArray(ArrayUtils.EMPTY_BYTE_ARRAY));
227         assertTrue(ObjectUtils.isArray(ArrayUtils.EMPTY_BYTE_OBJECT_ARRAY));
228         assertTrue(ObjectUtils.isArray(ArrayUtils.EMPTY_CHAR_ARRAY));
229         assertTrue(ObjectUtils.isArray(ArrayUtils.EMPTY_CHARACTER_OBJECT_ARRAY));
230         assertTrue(ObjectUtils.isArray(ArrayUtils.EMPTY_CLASS_ARRAY));
231         assertTrue(ObjectUtils.isArray(ArrayUtils.EMPTY_DOUBLE_ARRAY));
232         assertTrue(ObjectUtils.isArray(ArrayUtils.EMPTY_DOUBLE_OBJECT_ARRAY));
233         assertTrue(ObjectUtils.isArray(ArrayUtils.EMPTY_FIELD_ARRAY));
234         assertTrue(ObjectUtils.isArray(ArrayUtils.EMPTY_FLOAT_ARRAY));
235         assertTrue(ObjectUtils.isArray(ArrayUtils.EMPTY_FLOAT_OBJECT_ARRAY));
236         assertTrue(ObjectUtils.isArray(ArrayUtils.EMPTY_INT_ARRAY));
237         assertTrue(ObjectUtils.isArray(ArrayUtils.EMPTY_INTEGER_OBJECT_ARRAY));
238         assertTrue(ObjectUtils.isArray(ArrayUtils.EMPTY_LONG_ARRAY));
239         assertTrue(ObjectUtils.isArray(ArrayUtils.EMPTY_LONG_OBJECT_ARRAY));
240         assertTrue(ObjectUtils.isArray(ArrayUtils.EMPTY_METHOD_ARRAY));
241         assertTrue(ObjectUtils.isArray(ArrayUtils.EMPTY_OBJECT_ARRAY));
242         assertTrue(ObjectUtils.isArray(ArrayUtils.EMPTY_SHORT_ARRAY));
243         assertTrue(ObjectUtils.isArray(ArrayUtils.EMPTY_SHORT_OBJECT_ARRAY));
244         assertTrue(ObjectUtils.isArray(ArrayUtils.EMPTY_STRING_ARRAY));
245         assertTrue(ObjectUtils.isArray(ArrayUtils.EMPTY_THROWABLE_ARRAY));
246         assertTrue(ObjectUtils.isArray(ArrayUtils.EMPTY_TYPE_ARRAY));
247     }
248 
249     /**
250      * Tests {@link ObjectUtils#clone(Object)} with a cloneable object.
251      */
252     @Test
253     void testCloneOfCloneable() {
254         final CloneableString string = new CloneableString("apache");
255         final CloneableString stringClone = ObjectUtils.clone(string);
256         assertEquals("apache", stringClone.get());
257     }
258 
259     /**
260      * Tests {@link ObjectUtils#clone(Object)} with a not cloneable object.
261      */
262     @Test
263     void testCloneOfNotCloneable() {
264         final String string = "apache";
265         assertNull(ObjectUtils.clone(string));
266     }
267 
268     /**
269      * Tests {@link ObjectUtils#clone(Object)} with an array of primitives.
270      */
271     @Test
272     void testCloneOfPrimitiveArray() {
273         assertArrayEquals(new int[]{1}, ObjectUtils.clone(new int[]{1}));
274     }
275 
276     /**
277      * Tests {@link ObjectUtils#clone(Object)} with an object array.
278      */
279     @Test
280     void testCloneOfStringArray() {
281         assertTrue(Arrays.deepEquals(
282             new String[]{"string"}, ObjectUtils.clone(new String[]{"string"})));
283     }
284 
285     /**
286      * Tests {@link ObjectUtils#clone(Object)} with an uncloneable object.
287      */
288     @Test
289     void testCloneOfUncloneable() {
290         final UncloneableString string = new UncloneableString("apache");
291         final CloneFailedException e = assertThrows(CloneFailedException.class, () -> ObjectUtils.clone(string));
292         assertNotNull(e);
293         assertNotNull(e.getCause());
294         assertEquals(NoSuchMethodException.class, e.getCause().getClass());
295     }
296 
297     @Test
298     void testComparatorMedian() {
299         final CharSequenceComparator cmp = new CharSequenceComparator();
300         final NonComparableCharSequence foo = new NonComparableCharSequence("foo");
301         final NonComparableCharSequence bar = new NonComparableCharSequence("bar");
302         final NonComparableCharSequence baz = new NonComparableCharSequence("baz");
303         final NonComparableCharSequence blah = new NonComparableCharSequence("blah");
304         final NonComparableCharSequence wah = new NonComparableCharSequence("wah");
305         assertSame(foo, ObjectUtils.median(cmp, foo));
306         assertSame(bar, ObjectUtils.median(cmp, foo, bar));
307         assertSame(baz, ObjectUtils.median(cmp, foo, bar, baz));
308         assertSame(baz, ObjectUtils.median(cmp, foo, bar, baz, blah));
309         assertSame(blah, ObjectUtils.median(cmp, foo, bar, baz, blah, wah));
310     }
311 
312     @Test
313     void testComparatorMedian_emptyItems() {
314         assertIllegalArgumentException(() -> ObjectUtils.median(new CharSequenceComparator()));
315     }
316 
317     @Test
318     void testComparatorMedian_nullComparator() {
319         assertNullPointerException(
320                 () -> ObjectUtils.median((Comparator<CharSequence>) null, new NonComparableCharSequence("foo")));
321     }
322 
323     @Test
324     void testComparatorMedian_nullItems() {
325         assertNullPointerException(
326                 () -> ObjectUtils.median(new CharSequenceComparator(), (CharSequence[]) null));
327     }
328 
329     /**
330      * Tests {@link ObjectUtils#compare(Comparable, Comparable, boolean)}.
331      */
332     @Test
333     void testCompare() {
334         final Integer one = Integer.valueOf(1);
335         final Integer two = Integer.valueOf(2);
336         final Integer nullValue = null;
337 
338         assertEquals(0, ObjectUtils.compare(nullValue, nullValue), "Null Null false");
339         assertEquals(0, ObjectUtils.compare(nullValue, nullValue, true), "Null Null true");
340 
341         assertEquals(-1, ObjectUtils.compare(nullValue, one), "Null one false");
342         assertEquals(1, ObjectUtils.compare(nullValue, one, true), "Null one true");
343 
344         assertEquals(1, ObjectUtils.compare(one, nullValue), "one Null false");
345         assertEquals(-1, ObjectUtils.compare(one, nullValue, true), "one Null true");
346 
347         assertEquals(-1, ObjectUtils.compare(one, two), "one two false");
348         assertEquals(-1, ObjectUtils.compare(one, two, true), "one two true");
349     }
350 
351     @Test
352     void testConstMethods() {
353         // To truly test the CONST() method, we'd want to look in the
354         // bytecode to see if the literals were folded into the
355         // class, or if the bytecode kept the method call.
356         assertTrue(ObjectUtils.CONST(true), "CONST(boolean)");
357         assertEquals((byte) 3, ObjectUtils.CONST((byte) 3), "CONST(byte)");
358         assertEquals((char) 3, ObjectUtils.CONST((char) 3), "CONST(char)");
359         assertEquals((short) 3, ObjectUtils.CONST((short) 3), "CONST(short)");
360         assertEquals(3, ObjectUtils.CONST(3), "CONST(int)");
361         assertEquals(3L, ObjectUtils.CONST(3L), "CONST(long)");
362         assertEquals(3f, ObjectUtils.CONST(3f), "CONST(float)");
363         assertEquals(3.0, ObjectUtils.CONST(3.0), "CONST(double)");
364         assertEquals("abc", ObjectUtils.CONST("abc"), "CONST(Object)");
365         // Make sure documentation examples from Javadoc all work
366         // (this fixed a lot of my bugs when I these!)
367         //
368         // My bugs should be in a software engineering textbook
369         // for "Can you screw this up?" The answer is, yes,
370         // you can even screw this up. (When you == Julius)
371         // .
372         final boolean MAGIC_FLAG = ObjectUtils.CONST(true);
373         final byte MAGIC_BYTE1 = ObjectUtils.CONST((byte) 127);
374         final byte MAGIC_BYTE2 = ObjectUtils.CONST_BYTE(127);
375         final char MAGIC_CHAR = ObjectUtils.CONST('a');
376         final short MAGIC_SHORT1 = ObjectUtils.CONST((short) 123);
377         final short MAGIC_SHORT2 = ObjectUtils.CONST_SHORT(127);
378         final int MAGIC_INT = ObjectUtils.CONST(123);
379         final long MAGIC_LONG1 = ObjectUtils.CONST(123L);
380         final long MAGIC_LONG2 = ObjectUtils.CONST(3);
381         final float MAGIC_FLOAT = ObjectUtils.CONST(1.0f);
382         final double MAGIC_DOUBLE = ObjectUtils.CONST(1.0);
383         final String MAGIC_STRING = ObjectUtils.CONST("abc");
384         assertTrue(MAGIC_FLAG);
385         assertEquals(127, MAGIC_BYTE1);
386         assertEquals(127, MAGIC_BYTE2);
387         assertEquals('a', MAGIC_CHAR);
388         assertEquals(123, MAGIC_SHORT1);
389         assertEquals(127, MAGIC_SHORT2);
390         assertEquals(123, MAGIC_INT);
391         assertEquals(123, MAGIC_LONG1);
392         assertEquals(3, MAGIC_LONG2);
393         assertEquals(1.0f, MAGIC_FLOAT);
394         assertEquals(1.0, MAGIC_DOUBLE);
395         assertEquals("abc", MAGIC_STRING);
396         assertIllegalArgumentException(() -> ObjectUtils.CONST_BYTE(-129), "CONST_BYTE(-129): IllegalArgumentException should have been thrown.");
397         assertIllegalArgumentException(() -> ObjectUtils.CONST_BYTE(128), "CONST_BYTE(128): IllegalArgumentException should have been thrown.");
398         assertIllegalArgumentException(() -> ObjectUtils.CONST_SHORT(-32769),
399                 "CONST_SHORT(-32769): IllegalArgumentException should have been thrown.");
400         assertIllegalArgumentException(() -> ObjectUtils.CONST_BYTE(32768),
401                 "CONST_SHORT(32768): IllegalArgumentException should have been thrown.");
402     }
403 
404     @Test
405     void testConstructor() {
406         assertNotNull(new ObjectUtils());
407         final Constructor<?>[] cons = ObjectUtils.class.getDeclaredConstructors();
408         assertEquals(1, cons.length);
409         assertTrue(Modifier.isPublic(cons[0].getModifiers()));
410         assertTrue(Modifier.isPublic(ObjectUtils.class.getModifiers()));
411         assertFalse(Modifier.isFinal(ObjectUtils.class.getModifiers()));
412     }
413 
414     @Test
415     void testDefaultIfNull() {
416         final Object o = FOO;
417         final Object dflt = BAR;
418         assertSame(dflt, ObjectUtils.defaultIfNull(null, dflt), "dflt was not returned when o was null");
419         assertSame(o, ObjectUtils.defaultIfNull(o, dflt), "dflt was returned when o was not null");
420         assertSame(dflt, ObjectUtils.getIfNull(null, () -> dflt), "dflt was not returned when o was null");
421         assertSame(o, ObjectUtils.getIfNull(o, () -> dflt), "dflt was returned when o was not null");
422         assertSame(o, ObjectUtils.getIfNull(FOO, () -> dflt), "dflt was returned when o was not null");
423         assertSame(o, ObjectUtils.getIfNull("foo", () -> dflt), "dflt was returned when o was not null");
424         final MutableInt callsCounter = new MutableInt(0);
425         final Supplier<Object> countingDefaultSupplier = () -> {
426             callsCounter.increment();
427             return dflt;
428         };
429         ObjectUtils.getIfNull(o, countingDefaultSupplier);
430         assertEquals(0, callsCounter.get());
431         ObjectUtils.getIfNull(null, countingDefaultSupplier);
432         assertEquals(1, callsCounter.get());
433     }
434 
435     @Test
436     void testEquals() {
437         assertTrue(ObjectUtils.equals(null, null), "ObjectUtils.equals(null, null) returned false");
438         assertFalse(ObjectUtils.equals(FOO, null), "ObjectUtils.equals(\"foo\", null) returned true");
439         assertFalse(ObjectUtils.equals(null, BAR), "ObjectUtils.equals(null, \"bar\") returned true");
440         assertFalse(ObjectUtils.equals(FOO, BAR), "ObjectUtils.equals(\"foo\", \"bar\") returned true");
441         assertTrue(ObjectUtils.equals(FOO, FOO), "ObjectUtils.equals(\"foo\", \"foo\") returned false");
442     }
443 
444     @Test
445     void testFirstNonNull() {
446         assertEquals("", ObjectUtils.firstNonNull(null, ""));
447         final String firstNonNullGenerics = ObjectUtils.firstNonNull(null, null, "123", "456");
448         assertEquals("123", firstNonNullGenerics);
449         assertEquals("123", ObjectUtils.firstNonNull("123", null, "456", null));
450         assertSame(Boolean.TRUE, ObjectUtils.firstNonNull(Boolean.TRUE));
451 
452         // Explicitly pass in an empty array of Object type to ensure compiler doesn't complain of unchecked generic array creation
453         assertNull(ObjectUtils.firstNonNull());
454 
455         // Cast to Object in line below ensures compiler doesn't complain of unchecked generic array creation
456         assertNull(ObjectUtils.firstNonNull(null, null));
457 
458         assertNull(ObjectUtils.firstNonNull((Object) null));
459         assertNull(ObjectUtils.firstNonNull((Object[]) null));
460     }
461 
462     @Test
463     void testGetClass() {
464         final String[] newArray = ArrayUtils.EMPTY_STRING_ARRAY;
465         // No type-cast required.
466         final Class<String[]> cls = ObjectUtils.getClass(newArray);
467         assertEquals(String[].class, cls);
468         assertNull(ObjectUtils.getClass(null));
469     }
470 
471     @Test
472     void testGetFirstNonNull() {
473         // first non-null
474         assertEquals("", ObjectUtils.getFirstNonNull(null, () -> ""));
475         assertEquals("", ObjectUtils.getFirstNonNull(Suppliers.nul(), () -> ""));
476         // first encountered value is used
477         assertEquals("1", ObjectUtils.getFirstNonNull(Suppliers.nul(), () -> "1", () -> "2", Suppliers.nul()));
478         assertEquals("123", ObjectUtils.getFirstNonNull(() -> "123", Suppliers.nul(), () -> "456"));
479         // don't evaluate suppliers after first value is found
480         assertEquals("123", ObjectUtils.getFirstNonNull(Suppliers.nul(), () -> "123", () -> fail("Supplier after first non-null value should not be evaluated")));
481         // supplier returning null and null supplier both result in null
482         assertNull(ObjectUtils.getFirstNonNull(null, Suppliers.nul()));
483         // Explicitly pass in an empty array of Object type to ensure compiler doesn't complain of unchecked generic array creation
484         assertNull(ObjectUtils.getFirstNonNull());
485         // supplier is null
486         assertNull(ObjectUtils.getFirstNonNull((Supplier<Object>) null));
487         // varargs array itself is null
488         assertNull(ObjectUtils.getFirstNonNull((Supplier<Object>[]) null));
489         // test different types
490         assertEquals(1, ObjectUtils.getFirstNonNull(Suppliers.nul(), () -> 1));
491         assertEquals(Boolean.TRUE, ObjectUtils.getFirstNonNull(Suppliers.nul(), () -> Boolean.TRUE));
492     }
493 
494     @Test
495     void testGetIfNullObject() {
496         final Object o = FOO;
497         final Object defaultObject = BAR;
498         assertNull(ObjectUtils.getIfNull(null, (Object) null));
499         assertSame(defaultObject, ObjectUtils.getIfNull(null, defaultObject), "dflt was not returned when o was null");
500         assertSame(o, ObjectUtils.getIfNull(o, defaultObject), "dflt was returned when o was not null");
501     }
502 
503     @Test
504     void testGetIfNullSupplier() {
505         final Object o = FOO;
506         final Object defaultObject = BAR;
507         assertNull(ObjectUtils.getIfNull(null, (Supplier<Object>) null));
508         assertSame(defaultObject, ObjectUtils.getIfNull(null, () -> defaultObject), "dflt was not returned when o was null");
509         assertSame(o, ObjectUtils.getIfNull(o, () -> defaultObject), "dflt was returned when o was not null");
510         assertSame(o, ObjectUtils.getIfNull(FOO, () -> defaultObject), "dflt was returned when o was not null");
511         assertSame(o, ObjectUtils.getIfNull("foo", () -> defaultObject), "dflt was returned when o was not null");
512         final MutableInt callsCounter = new MutableInt(0);
513         final Supplier<Object> countingDefaultSupplier = () -> {
514             callsCounter.increment();
515             return defaultObject;
516         };
517         ObjectUtils.getIfNull(o, countingDefaultSupplier);
518         assertEquals(0, callsCounter.get());
519         ObjectUtils.getIfNull(null, countingDefaultSupplier);
520         assertEquals(1, callsCounter.get());
521     }
522 
523     @Test
524     void testHashCode() {
525         assertEquals(0, ObjectUtils.hashCode(null));
526         assertEquals("a".hashCode(), ObjectUtils.hashCode("a"));
527     }
528 
529     @Test
530     void testHashCodeHex() {
531         final Integer i = Integer.valueOf(90);
532         assertEquals(Integer.toHexString(Objects.hashCode(i)), ObjectUtils.hashCodeHex(i));
533         final Integer zero = Integer.valueOf(0);
534         assertEquals(Integer.toHexString(Objects.hashCode(zero)), ObjectUtils.hashCodeHex(zero));
535         assertEquals(Integer.toHexString(Objects.hashCode(null)), ObjectUtils.hashCodeHex(null));
536     }
537 
538     @Test
539     void testHashCodeMulti_multiple_emptyArray() {
540         final Object[] array = {};
541         assertEquals(1, ObjectUtils.hashCodeMulti(array));
542     }
543 
544     @Test
545     void testHashCodeMulti_multiple_likeList() {
546         final List<Object> list0 = new ArrayList<>(Collections.emptyList());
547         assertEquals(list0.hashCode(), ObjectUtils.hashCodeMulti());
548 
549         final List<Object> list1 = new ArrayList<>(Collections.singletonList("a"));
550         assertEquals(list1.hashCode(), ObjectUtils.hashCodeMulti("a"));
551 
552         final List<Object> list2 = new ArrayList<>(Arrays.asList("a", "b"));
553         assertEquals(list2.hashCode(), ObjectUtils.hashCodeMulti("a", "b"));
554 
555         final List<Object> list3 = new ArrayList<>(Arrays.asList("a", "b", "c"));
556         assertEquals(list3.hashCode(), ObjectUtils.hashCodeMulti("a", "b", "c"));
557     }
558 
559     @Test
560     void testHashCodeMulti_multiple_nullArray() {
561         final Object[] array = null;
562         assertEquals(1, ObjectUtils.hashCodeMulti(array));
563     }
564 
565     @Test
566     void testIdentityHashCodeHex() {
567         final Integer i = Integer.valueOf(90);
568         assertEquals(Integer.toHexString(System.identityHashCode(i)), ObjectUtils.identityHashCodeHex(i));
569         final Integer zero = Integer.valueOf(0);
570         assertEquals(Integer.toHexString(System.identityHashCode(zero)), ObjectUtils.identityHashCodeHex(zero));
571         assertEquals(Integer.toHexString(System.identityHashCode(null)), ObjectUtils.identityHashCodeHex(null));
572     }
573 
574     @Test
575     void testIdentityToStringAppendable() throws IOException {
576         final Integer i = Integer.valueOf(121);
577         final String expected = "java.lang.Integer@" + Integer.toHexString(System.identityHashCode(i));
578         final Appendable appendable = new StringBuilder();
579         ObjectUtils.identityToString(appendable, i);
580         assertEquals(expected, appendable.toString());
581         assertNullPointerException(() -> ObjectUtils.identityToString((Appendable) null, "tmp"));
582         assertNullPointerException(() -> ObjectUtils.identityToString((Appendable) new StringBuilder(), null));
583     }
584 
585     @Test
586     void testIdentityToStringInteger() {
587         final Integer i = Integer.valueOf(90);
588         final String expected = "java.lang.Integer@" + Integer.toHexString(System.identityHashCode(i));
589 
590         assertEquals(expected, ObjectUtils.identityToString(i));
591     }
592 
593     @Test
594     void testIdentityToStringObjectNull() {
595         assertNull(ObjectUtils.identityToString(null));
596     }
597 
598     @Test
599     void testIdentityToStringStrBuilder() {
600         final Integer i = Integer.valueOf(102);
601         final String expected = "java.lang.Integer@" + Integer.toHexString(System.identityHashCode(i));
602         final StrBuilder builder = new StrBuilder();
603         ObjectUtils.identityToString(builder, i);
604         assertEquals(expected, builder.toString());
605         assertNullPointerException(() -> ObjectUtils.identityToString((StrBuilder) null, "tmp"));
606         assertNullPointerException(() -> ObjectUtils.identityToString(new StrBuilder(), null));
607     }
608 
609     @Test
610     void testIdentityToStringString() {
611         assertEquals(
612                 "java.lang.String@" + Integer.toHexString(System.identityHashCode(FOO)),
613                 ObjectUtils.identityToString(FOO));
614     }
615 
616     @Test
617     void testIdentityToStringStringBuffer() {
618         final Integer i = Integer.valueOf(45);
619         final String expected = "java.lang.Integer@" + Integer.toHexString(System.identityHashCode(i));
620         final StringBuffer buffer = new StringBuffer();
621         ObjectUtils.identityToString(buffer, i);
622         assertEquals(expected, buffer.toString());
623         assertNullPointerException(() -> ObjectUtils.identityToString((StringBuffer) null, "tmp"));
624         assertNullPointerException(() -> ObjectUtils.identityToString(new StringBuffer(), null));
625     }
626 
627     @Test
628     void testIdentityToStringStringBuilder() {
629         final Integer i = Integer.valueOf(90);
630         final String expected = "java.lang.Integer@" + Integer.toHexString(System.identityHashCode(i));
631 
632         final StringBuilder builder = new StringBuilder();
633         ObjectUtils.identityToString(builder, i);
634         assertEquals(expected, builder.toString());
635     }
636 
637     @Test
638     void testIdentityToStringStringBuilderInUse() {
639         final Integer i = Integer.valueOf(90);
640         final String expected = "ABC = java.lang.Integer@" + Integer.toHexString(System.identityHashCode(i));
641         final StringBuilder builder = new StringBuilder("ABC = ");
642         ObjectUtils.identityToString(builder, i);
643         assertEquals(expected, builder.toString());
644     }
645 
646     @Test
647     public  void testIdentityToStringStringBuilderNullStringBuilder() {
648         assertNullPointerException(() -> ObjectUtils.identityToString((StringBuilder) null, "tmp"));
649     }
650 
651     @Test
652     void testIdentityToStringStringBuilderNullValue() {
653         assertNullPointerException(() -> ObjectUtils.identityToString(new StringBuilder(), null));
654     }
655 
656     @Test
657     void testIsEmpty() {
658         assertTrue(ObjectUtils.isEmpty(null));
659         assertTrue(ObjectUtils.isEmpty(""));
660         assertTrue(ObjectUtils.isEmpty(new int[] {}));
661         assertTrue(ObjectUtils.isEmpty(Collections.emptyList()));
662         assertTrue(ObjectUtils.isEmpty(Collections.emptySet()));
663         assertTrue(ObjectUtils.isEmpty(Collections.emptyMap()));
664         assertTrue(ObjectUtils.isEmpty(Optional.empty()));
665         assertTrue(ObjectUtils.isEmpty(Optional.ofNullable(null)));
666 
667         assertFalse(ObjectUtils.isEmpty("  "));
668         assertFalse(ObjectUtils.isEmpty("ab"));
669         assertFalse(ObjectUtils.isEmpty(NON_EMPTY_ARRAY));
670         assertFalse(ObjectUtils.isEmpty(NON_EMPTY_LIST));
671         assertFalse(ObjectUtils.isEmpty(NON_EMPTY_SET));
672         assertFalse(ObjectUtils.isEmpty(NON_EMPTY_MAP));
673         assertFalse(ObjectUtils.isEmpty(Optional.of(new Object())));
674         assertFalse(ObjectUtils.isEmpty(Optional.ofNullable(new Object())));
675     }
676 
677     @Test
678     void testIsNotEmpty() {
679         assertFalse(ObjectUtils.isNotEmpty(null));
680         assertFalse(ObjectUtils.isNotEmpty(""));
681         assertFalse(ObjectUtils.isNotEmpty(new int[] {}));
682         assertFalse(ObjectUtils.isNotEmpty(Collections.emptyList()));
683         assertFalse(ObjectUtils.isNotEmpty(Collections.emptySet()));
684         assertFalse(ObjectUtils.isNotEmpty(Collections.emptyMap()));
685         assertFalse(ObjectUtils.isNotEmpty(Optional.empty()));
686         assertFalse(ObjectUtils.isNotEmpty(Optional.ofNullable(null)));
687 
688         assertTrue(ObjectUtils.isNotEmpty("  "));
689         assertTrue(ObjectUtils.isNotEmpty("ab"));
690         assertTrue(ObjectUtils.isNotEmpty(NON_EMPTY_ARRAY));
691         assertTrue(ObjectUtils.isNotEmpty(NON_EMPTY_LIST));
692         assertTrue(ObjectUtils.isNotEmpty(NON_EMPTY_SET));
693         assertTrue(ObjectUtils.isNotEmpty(NON_EMPTY_MAP));
694         assertTrue(ObjectUtils.isNotEmpty(Optional.of(new Object())));
695         assertTrue(ObjectUtils.isNotEmpty(Optional.ofNullable(new Object())));
696     }
697 
698     @Test
699     void testMax() {
700         final Calendar calendar = Calendar.getInstance();
701         final Date nonNullComparable1 = calendar.getTime();
702         final Date nonNullComparable2 = calendar.getTime();
703         final String[] nullArray = null;
704 
705         calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR) - 1);
706         final Date minComparable = calendar.getTime();
707 
708         assertNotSame(nonNullComparable1, nonNullComparable2);
709 
710         assertNull(ObjectUtils.max((String) null));
711         assertNull(ObjectUtils.max(nullArray));
712         assertSame(nonNullComparable1, ObjectUtils.max(null, nonNullComparable1));
713         assertSame(nonNullComparable1, ObjectUtils.max(nonNullComparable1, null));
714         assertSame(nonNullComparable1, ObjectUtils.max(null, nonNullComparable1, null));
715         assertSame(nonNullComparable1, ObjectUtils.max(nonNullComparable1, nonNullComparable2));
716         assertSame(nonNullComparable2, ObjectUtils.max(nonNullComparable2, nonNullComparable1));
717         assertSame(nonNullComparable1, ObjectUtils.max(nonNullComparable1, minComparable));
718         assertSame(nonNullComparable1, ObjectUtils.max(minComparable, nonNullComparable1));
719         assertSame(nonNullComparable1, ObjectUtils.max(null, minComparable, null, nonNullComparable1));
720 
721         assertNull(ObjectUtils.max(null, null));
722     }
723 
724     @Test
725     void testMedian() {
726         assertEquals("foo", ObjectUtils.median("foo"));
727         assertEquals("bar", ObjectUtils.median("foo", "bar"));
728         assertEquals("baz", ObjectUtils.median("foo", "bar", "baz"));
729         assertEquals("baz", ObjectUtils.median("foo", "bar", "baz", "blah"));
730         assertEquals("blah", ObjectUtils.median("foo", "bar", "baz", "blah", "wah"));
731         assertEquals(Integer.valueOf(5),
732             ObjectUtils.median(Integer.valueOf(1), Integer.valueOf(5), Integer.valueOf(10)));
733         assertEquals(
734             Integer.valueOf(7),
735             ObjectUtils.median(Integer.valueOf(5), Integer.valueOf(6), Integer.valueOf(7), Integer.valueOf(8),
736                 Integer.valueOf(9)));
737         assertEquals(Integer.valueOf(6),
738             ObjectUtils.median(Integer.valueOf(5), Integer.valueOf(6), Integer.valueOf(7), Integer.valueOf(8)));
739     }
740 
741     @Test
742     void testMedian_emptyItems() {
743         assertIllegalArgumentException(ObjectUtils::<String>median);
744     }
745 
746     @Test
747     void testMedian_nullItems() {
748         assertNullPointerException(() -> ObjectUtils.median((String[]) null));
749     }
750 
751     @Test
752     void testMin() {
753         final Calendar calendar = Calendar.getInstance();
754         final Date nonNullComparable1 = calendar.getTime();
755         final Date nonNullComparable2 = calendar.getTime();
756         final String[] nullArray = null;
757 
758         calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR) - 1);
759         final Date minComparable = calendar.getTime();
760 
761         assertNotSame(nonNullComparable1, nonNullComparable2);
762 
763         assertNull(ObjectUtils.min((String) null));
764         assertNull(ObjectUtils.min(nullArray));
765         assertSame(nonNullComparable1, ObjectUtils.min(null, nonNullComparable1));
766         assertSame(nonNullComparable1, ObjectUtils.min(nonNullComparable1, null));
767         assertSame(nonNullComparable1, ObjectUtils.min(null, nonNullComparable1, null));
768         assertSame(nonNullComparable1, ObjectUtils.min(nonNullComparable1, nonNullComparable2));
769         assertSame(nonNullComparable2, ObjectUtils.min(nonNullComparable2, nonNullComparable1));
770         assertSame(minComparable, ObjectUtils.min(nonNullComparable1, minComparable));
771         assertSame(minComparable, ObjectUtils.min(minComparable, nonNullComparable1));
772         assertSame(minComparable, ObjectUtils.min(null, nonNullComparable1, null, minComparable));
773 
774         assertNull(ObjectUtils.min(null, null));
775     }
776 
777     @Test
778     void testMode() {
779         assertNull(ObjectUtils.mode((Object[]) null));
780         assertNull(ObjectUtils.mode());
781         assertNull(ObjectUtils.mode("foo", "bar", "baz"));
782         assertNull(ObjectUtils.mode("foo", "bar", "baz", "foo", "bar"));
783         assertEquals("foo", ObjectUtils.mode("foo", "bar", "baz", "foo"));
784         assertEquals(Integer.valueOf(9),
785             ObjectUtils.mode("foo", "bar", "baz", Integer.valueOf(9), Integer.valueOf(10), Integer.valueOf(9)));
786     }
787 
788     @Test
789     void testNotEqual() {
790         assertFalse(ObjectUtils.notEqual(null, null), "ObjectUtils.notEqual(null, null) returned false");
791         assertTrue(ObjectUtils.notEqual(FOO, null), "ObjectUtils.notEqual(\"foo\", null) returned true");
792         assertTrue(ObjectUtils.notEqual(null, BAR), "ObjectUtils.notEqual(null, \"bar\") returned true");
793         assertTrue(ObjectUtils.notEqual(FOO, BAR), "ObjectUtils.notEqual(\"foo\", \"bar\") returned true");
794         assertFalse(ObjectUtils.notEqual(FOO, FOO), "ObjectUtils.notEqual(\"foo\", \"foo\") returned false");
795     }
796 
797     @SuppressWarnings("cast") // 1 OK, because we are checking for code change
798     @Test
799     void testNull() {
800         assertNotNull(ObjectUtils.NULL);
801         // 1 Check that NULL really is a Null i.e. the definition has not been changed
802         assertInstanceOf(ObjectUtils.Null.class, ObjectUtils.NULL);
803         assertSame(ObjectUtils.NULL, SerializationUtils.clone(ObjectUtils.NULL));
804     }
805 
806     /**
807      * Tests {@link ObjectUtils#cloneIfPossible(Object)} with a cloneable object.
808      */
809     @Test
810     void testPossibleCloneOfCloneable() {
811         final CloneableString string = new CloneableString("apache");
812         final CloneableString stringClone = ObjectUtils.cloneIfPossible(string);
813         assertEquals("apache", stringClone.get());
814     }
815 
816     /**
817      * Tests {@link ObjectUtils#cloneIfPossible(Object)} with a not cloneable object.
818      */
819     @Test
820     void testPossibleCloneOfNotCloneable() {
821         final String string = "apache";
822         assertSame(string, ObjectUtils.cloneIfPossible(string));
823     }
824 
825     /**
826      * Tests {@link ObjectUtils#cloneIfPossible(Object)} with an uncloneable object.
827      */
828     @Test
829     void testPossibleCloneOfUncloneable() {
830         final UncloneableString string = new UncloneableString("apache");
831         final CloneFailedException e = assertThrows(CloneFailedException.class, () -> ObjectUtils.cloneIfPossible(string));
832         assertNotNull(e);
833         assertNotNull(e.getCause());
834         assertEquals(NoSuchMethodException.class, e.getCause().getClass());
835     }
836 
837     @Test
838     void testRequireNonEmpty() {
839         assertEquals("foo", ObjectUtils.requireNonEmpty("foo"));
840         assertEquals("foo", ObjectUtils.requireNonEmpty("foo", "foo"));
841         //
842         assertNullPointerException(() -> ObjectUtils.requireNonEmpty(null));
843         assertNullPointerException(() -> ObjectUtils.requireNonEmpty(null, "foo"));
844         //
845         assertIllegalArgumentException(() -> ObjectUtils.requireNonEmpty(""));
846         assertIllegalArgumentException(() -> ObjectUtils.requireNonEmpty("", "foo"));
847     }
848 
849     @Test
850     void testToString_Object() {
851         assertEquals("", ObjectUtils.toString(null));
852         assertEquals(Boolean.TRUE.toString(), ObjectUtils.toString(Boolean.TRUE));
853     }
854 
855     @Test
856     void testToString_Object_String() {
857         assertEquals(BAR, ObjectUtils.toString(null, BAR));
858         assertEquals(Boolean.TRUE.toString(), ObjectUtils.toString(Boolean.TRUE, BAR));
859     }
860 
861     @Test
862     void testToString_String_Supplier() {
863         assertNull(ObjectUtils.toString(null, (Supplier<String>) null));
864         assertNull(ObjectUtils.toString(null, Suppliers.nul()));
865         // Pretend computing BAR is expensive.
866         assertEquals(BAR, ObjectUtils.toString(null, () -> BAR));
867         assertEquals(Boolean.TRUE.toString(), ObjectUtils.toString(Boolean.TRUE, () -> BAR));
868     }
869 
870     @Test
871     void testToString_Supplier_Supplier() {
872         assertNull(ObjectUtils.toString(NULL_SUPPLIER, (Supplier<String>) null));
873         assertNull(ObjectUtils.toString(Suppliers.nul(), (Supplier<String>) null));
874         assertNull(ObjectUtils.toString(NULL_SUPPLIER, Suppliers.nul()));
875         assertNull(ObjectUtils.toString(Suppliers.nul(), Suppliers.nul()));
876         // Pretend computing BAR is expensive.
877         assertEquals(BAR, ObjectUtils.toString(NULL_SUPPLIER, () -> BAR));
878         assertEquals(BAR, ObjectUtils.toString(Suppliers.nul(), () -> BAR));
879         assertEquals(Boolean.TRUE.toString(), ObjectUtils.toString(() -> Boolean.TRUE, () -> BAR));
880     }
881 
882     @Test
883     void testWaitDuration() {
884         assertThrows(IllegalMonitorStateException.class, () -> ObjectUtils.wait(new Object(), Duration.ZERO));
885     }
886 
887 }