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