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 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         assertNotNull(e);
290         assertNotNull(e.getCause());
291         assertEquals(NoSuchMethodException.class, e.getCause().getClass());
292     }
293 
294     @Test
295     public void testComparatorMedian() {
296         final CharSequenceComparator cmp = new CharSequenceComparator();
297         final NonComparableCharSequence foo = new NonComparableCharSequence("foo");
298         final NonComparableCharSequence bar = new NonComparableCharSequence("bar");
299         final NonComparableCharSequence baz = new NonComparableCharSequence("baz");
300         final NonComparableCharSequence blah = new NonComparableCharSequence("blah");
301         final NonComparableCharSequence wah = new NonComparableCharSequence("wah");
302         assertSame(foo, ObjectUtils.median(cmp, foo));
303         assertSame(bar, ObjectUtils.median(cmp, foo, bar));
304         assertSame(baz, ObjectUtils.median(cmp, foo, bar, baz));
305         assertSame(baz, ObjectUtils.median(cmp, foo, bar, baz, blah));
306         assertSame(blah, ObjectUtils.median(cmp, foo, bar, baz, blah, wah));
307     }
308 
309     @Test
310     public void testComparatorMedian_emptyItems() {
311         assertThrows(IllegalArgumentException.class, () -> ObjectUtils.median(new CharSequenceComparator()));
312     }
313 
314     @Test
315     public void testComparatorMedian_nullComparator() {
316         assertThrows(NullPointerException.class,
317                 () -> ObjectUtils.median((Comparator<CharSequence>) null, new NonComparableCharSequence("foo")));
318     }
319 
320     @Test
321     public void testComparatorMedian_nullItems() {
322         assertThrows(NullPointerException.class,
323                 () -> ObjectUtils.median(new CharSequenceComparator(), (CharSequence[]) null));
324     }
325 
326     /**
327      * Tests {@link ObjectUtils#compare(Comparable, Comparable, boolean)}.
328      */
329     @Test
330     public void testCompare() {
331         final Integer one = Integer.valueOf(1);
332         final Integer two = Integer.valueOf(2);
333         final Integer nullValue = null;
334 
335         assertEquals(0, ObjectUtils.compare(nullValue, nullValue), "Null Null false");
336         assertEquals(0, ObjectUtils.compare(nullValue, nullValue, true), "Null Null true");
337 
338         assertEquals(-1, ObjectUtils.compare(nullValue, one), "Null one false");
339         assertEquals(1, ObjectUtils.compare(nullValue, one, true), "Null one true");
340 
341         assertEquals(1, ObjectUtils.compare(one, nullValue), "one Null false");
342         assertEquals(-1, ObjectUtils.compare(one, nullValue, true), "one Null true");
343 
344         assertEquals(-1, ObjectUtils.compare(one, two), "one two false");
345         assertEquals(-1, ObjectUtils.compare(one, two, true), "one two true");
346     }
347 
348     @Test
349     public void testConstMethods() {
350 
351         // To truly test the CONST() method, we'd want to look in the
352         // bytecode to see if the literals were folded into the
353         // class, or if the bytecode kept the method call.
354 
355         assertTrue(ObjectUtils.CONST(true), "CONST(boolean)");
356         assertEquals((byte) 3, ObjectUtils.CONST((byte) 3), "CONST(byte)");
357         assertEquals((char) 3, ObjectUtils.CONST((char) 3), "CONST(char)");
358         assertEquals((short) 3, ObjectUtils.CONST((short) 3), "CONST(short)");
359         assertEquals(3, ObjectUtils.CONST(3), "CONST(int)");
360         assertEquals(3L, ObjectUtils.CONST(3L), "CONST(long)");
361         assertEquals(3f, ObjectUtils.CONST(3f), "CONST(float)");
362         assertEquals(3.0, ObjectUtils.CONST(3.0), "CONST(double)");
363         assertEquals("abc", ObjectUtils.CONST("abc"), "CONST(Object)");
364 
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 
385         assertTrue(MAGIC_FLAG);
386         assertEquals(127, MAGIC_BYTE1);
387         assertEquals(127, MAGIC_BYTE2);
388         assertEquals('a', MAGIC_CHAR);
389         assertEquals(123, MAGIC_SHORT1);
390         assertEquals(127, MAGIC_SHORT2);
391         assertEquals(123, MAGIC_INT);
392         assertEquals(123, MAGIC_LONG1);
393         assertEquals(3, MAGIC_LONG2);
394         assertEquals(1.0f, MAGIC_FLOAT);
395         assertEquals(1.0, MAGIC_DOUBLE);
396         assertEquals("abc", MAGIC_STRING);
397         assertThrows(
398                 IllegalArgumentException.class,
399                 () -> ObjectUtils.CONST_BYTE(-129),
400                 "CONST_BYTE(-129): IllegalArgumentException should have been thrown.");
401         assertThrows(
402                 IllegalArgumentException.class,
403                 () -> ObjectUtils.CONST_BYTE(128),
404                 "CONST_BYTE(128): IllegalArgumentException should have been thrown.");
405         assertThrows(
406                 IllegalArgumentException.class,
407                 () -> ObjectUtils.CONST_SHORT(-32769),
408                 "CONST_SHORT(-32769): IllegalArgumentException should have been thrown.");
409         assertThrows(
410                 IllegalArgumentException.class,
411                 () -> ObjectUtils.CONST_BYTE(32768),
412                 "CONST_SHORT(32768): IllegalArgumentException should have been thrown.");
413     }
414 
415     @Test
416     public void testConstructor() {
417         assertNotNull(new ObjectUtils());
418         final Constructor<?>[] cons = ObjectUtils.class.getDeclaredConstructors();
419         assertEquals(1, cons.length);
420         assertTrue(Modifier.isPublic(cons[0].getModifiers()));
421         assertTrue(Modifier.isPublic(ObjectUtils.class.getModifiers()));
422         assertFalse(Modifier.isFinal(ObjectUtils.class.getModifiers()));
423     }
424 
425     @Test
426     public void testDefaultIfNull() {
427         final Object o = FOO;
428         final Object dflt = BAR;
429         assertSame(dflt, ObjectUtils.defaultIfNull(null, dflt), "dflt was not returned when o was null");
430         assertSame(o, ObjectUtils.defaultIfNull(o, dflt), "dflt was returned when o was not null");
431         assertSame(dflt, ObjectUtils.getIfNull(null, () -> dflt), "dflt was not returned when o was null");
432         assertSame(o, ObjectUtils.getIfNull(o, () -> dflt), "dflt was returned when o was not null");
433         assertSame(o, ObjectUtils.getIfNull(FOO, () -> dflt), "dflt was returned when o was not null");
434         assertSame(o, ObjectUtils.getIfNull("foo", () -> dflt), "dflt was returned when o was not null");
435         final MutableInt callsCounter = new MutableInt(0);
436         final Supplier<Object> countingDefaultSupplier = () -> {
437             callsCounter.increment();
438             return dflt;
439         };
440         ObjectUtils.getIfNull(o, countingDefaultSupplier);
441         assertEquals(0, callsCounter.getValue());
442         ObjectUtils.getIfNull(null, countingDefaultSupplier);
443         assertEquals(1, callsCounter.getValue());
444     }
445 
446     @Test
447     public void testEquals() {
448         assertTrue(ObjectUtils.equals(null, null), "ObjectUtils.equals(null, null) returned false");
449         assertFalse(ObjectUtils.equals(FOO, null), "ObjectUtils.equals(\"foo\", null) returned true");
450         assertFalse(ObjectUtils.equals(null, BAR), "ObjectUtils.equals(null, \"bar\") returned true");
451         assertFalse(ObjectUtils.equals(FOO, BAR), "ObjectUtils.equals(\"foo\", \"bar\") returned true");
452         assertTrue(ObjectUtils.equals(FOO, FOO), "ObjectUtils.equals(\"foo\", \"foo\") returned false");
453     }
454 
455     @Test
456     public void testFirstNonNull() {
457         assertEquals("", ObjectUtils.firstNonNull(null, ""));
458         final String firstNonNullGenerics = ObjectUtils.firstNonNull(null, null, "123", "456");
459         assertEquals("123", firstNonNullGenerics);
460         assertEquals("123", ObjectUtils.firstNonNull("123", null, "456", null));
461         assertSame(Boolean.TRUE, ObjectUtils.firstNonNull(Boolean.TRUE));
462 
463         // Explicitly pass in an empty array of Object type to ensure compiler doesn't complain of unchecked generic array creation
464         assertNull(ObjectUtils.firstNonNull());
465 
466         // Cast to Object in line below ensures compiler doesn't complain of unchecked generic array creation
467         assertNull(ObjectUtils.firstNonNull(null, null));
468 
469         assertNull(ObjectUtils.firstNonNull((Object) null));
470         assertNull(ObjectUtils.firstNonNull((Object[]) null));
471     }
472 
473     @Test
474     public void testGetClass() {
475         final String[] newArray = ArrayUtils.EMPTY_STRING_ARRAY;
476         // No type-cast required.
477         final Class<String[]> cls = ObjectUtils.getClass(newArray);
478         assertEquals(String[].class, cls);
479         assertNull(ObjectUtils.getClass(null));
480     }
481 
482     @Test
483     public void testGetFirstNonNull() {
484         // first non-null
485         assertEquals("", ObjectUtils.getFirstNonNull(null, () -> ""));
486         assertEquals("", ObjectUtils.getFirstNonNull(Suppliers.nul(), () -> ""));
487         // first encountered value is used
488         assertEquals("1", ObjectUtils.getFirstNonNull(Suppliers.nul(), () -> "1", () -> "2", Suppliers.nul()));
489         assertEquals("123", ObjectUtils.getFirstNonNull(() -> "123", Suppliers.nul(), () -> "456"));
490         // don't evaluate suppliers after first value is found
491         assertEquals("123", ObjectUtils.getFirstNonNull(Suppliers.nul(), () -> "123", () -> fail("Supplier after first non-null value should not be evaluated")));
492         // supplier returning null and null supplier both result in null
493         assertNull(ObjectUtils.getFirstNonNull(null, Suppliers.nul()));
494         // Explicitly pass in an empty array of Object type to ensure compiler doesn't complain of unchecked generic array creation
495         assertNull(ObjectUtils.getFirstNonNull());
496         // supplier is null
497         assertNull(ObjectUtils.getFirstNonNull((Supplier<Object>) null));
498         // varargs array itself is null
499         assertNull(ObjectUtils.getFirstNonNull((Supplier<Object>[]) null));
500         // test different types
501         assertEquals(1, ObjectUtils.getFirstNonNull(Suppliers.nul(), () -> 1));
502         assertEquals(Boolean.TRUE, ObjectUtils.getFirstNonNull(Suppliers.nul(), () -> Boolean.TRUE));
503     }
504 
505     @Test
506     public void testHashCode() {
507         assertEquals(0, ObjectUtils.hashCode(null));
508         assertEquals("a".hashCode(), ObjectUtils.hashCode("a"));
509     }
510 
511     @Test
512     public void testHashCodeHex() {
513         final Integer i = Integer.valueOf(90);
514         assertEquals(Integer.toHexString(Objects.hashCode(i)), ObjectUtils.hashCodeHex(i));
515         final Integer zero = Integer.valueOf(0);
516         assertEquals(Integer.toHexString(Objects.hashCode(zero)), ObjectUtils.hashCodeHex(zero));
517         assertEquals(Integer.toHexString(Objects.hashCode(null)), ObjectUtils.hashCodeHex(null));
518     }
519 
520     @Test
521     public void testHashCodeMulti_multiple_emptyArray() {
522         final Object[] array = {};
523         assertEquals(1, ObjectUtils.hashCodeMulti(array));
524     }
525 
526     @Test
527     public void testHashCodeMulti_multiple_likeList() {
528         final List<Object> list0 = new ArrayList<>(Collections.emptyList());
529         assertEquals(list0.hashCode(), ObjectUtils.hashCodeMulti());
530 
531         final List<Object> list1 = new ArrayList<>(Collections.singletonList("a"));
532         assertEquals(list1.hashCode(), ObjectUtils.hashCodeMulti("a"));
533 
534         final List<Object> list2 = new ArrayList<>(Arrays.asList("a", "b"));
535         assertEquals(list2.hashCode(), ObjectUtils.hashCodeMulti("a", "b"));
536 
537         final List<Object> list3 = new ArrayList<>(Arrays.asList("a", "b", "c"));
538         assertEquals(list3.hashCode(), ObjectUtils.hashCodeMulti("a", "b", "c"));
539     }
540 
541     @Test
542     public void testHashCodeMulti_multiple_nullArray() {
543         final Object[] array = null;
544         assertEquals(1, ObjectUtils.hashCodeMulti(array));
545     }
546 
547     @Test
548     public void testIdentityHashCodeHex() {
549         final Integer i = Integer.valueOf(90);
550         assertEquals(Integer.toHexString(System.identityHashCode(i)), ObjectUtils.identityHashCodeHex(i));
551         final Integer zero = Integer.valueOf(0);
552         assertEquals(Integer.toHexString(System.identityHashCode(zero)), ObjectUtils.identityHashCodeHex(zero));
553         assertEquals(Integer.toHexString(System.identityHashCode(null)), ObjectUtils.identityHashCodeHex(null));
554     }
555 
556     @Test
557     public void testIdentityToStringAppendable() throws IOException {
558         final Integer i = Integer.valueOf(121);
559         final String expected = "java.lang.Integer@" + Integer.toHexString(System.identityHashCode(i));
560 
561         final Appendable appendable = new StringBuilder();
562         ObjectUtils.identityToString(appendable, i);
563         assertEquals(expected, appendable.toString());
564 
565         assertThrows(NullPointerException.class, () -> ObjectUtils.identityToString((Appendable) null, "tmp"));
566 
567         assertThrows(
568                 NullPointerException.class,
569                 () -> ObjectUtils.identityToString((Appendable) new StringBuilder(), null));
570     }
571 
572     @Test
573     public void testIdentityToStringInteger() {
574         final Integer i = Integer.valueOf(90);
575         final String expected = "java.lang.Integer@" + Integer.toHexString(System.identityHashCode(i));
576 
577         assertEquals(expected, ObjectUtils.identityToString(i));
578     }
579 
580     @Test
581     public void testIdentityToStringObjectNull() {
582         assertNull(ObjectUtils.identityToString(null));
583     }
584 
585     @Test
586     public void testIdentityToStringStrBuilder() {
587         final Integer i = Integer.valueOf(102);
588         final String expected = "java.lang.Integer@" + Integer.toHexString(System.identityHashCode(i));
589 
590         final StrBuilder builder = new StrBuilder();
591         ObjectUtils.identityToString(builder, i);
592         assertEquals(expected, builder.toString());
593 
594         assertThrows(NullPointerException.class, () -> ObjectUtils.identityToString((StrBuilder) null, "tmp"));
595 
596         assertThrows(NullPointerException.class, () -> ObjectUtils.identityToString(new StrBuilder(), null));
597     }
598 
599     @Test
600     public void testIdentityToStringString() {
601         assertEquals(
602                 "java.lang.String@" + Integer.toHexString(System.identityHashCode(FOO)),
603                 ObjectUtils.identityToString(FOO));
604     }
605 
606     @Test
607     public void testIdentityToStringStringBuffer() {
608         final Integer i = Integer.valueOf(45);
609         final String expected = "java.lang.Integer@" + Integer.toHexString(System.identityHashCode(i));
610 
611         final StringBuffer buffer = new StringBuffer();
612         ObjectUtils.identityToString(buffer, i);
613         assertEquals(expected, buffer.toString());
614 
615         assertThrows(NullPointerException.class, () -> ObjectUtils.identityToString((StringBuffer) null, "tmp"));
616         assertThrows(NullPointerException.class, () -> ObjectUtils.identityToString(new StringBuffer(), null));
617     }
618 
619     @Test
620     public void testIdentityToStringStringBuilder() {
621         final Integer i = Integer.valueOf(90);
622         final String expected = "java.lang.Integer@" + Integer.toHexString(System.identityHashCode(i));
623 
624         final StringBuilder builder = new StringBuilder();
625         ObjectUtils.identityToString(builder, i);
626         assertEquals(expected, builder.toString());
627     }
628 
629     @Test
630     public void testIdentityToStringStringBuilderInUse() {
631         final Integer i = Integer.valueOf(90);
632         final String expected = "ABC = java.lang.Integer@" + Integer.toHexString(System.identityHashCode(i));
633 
634         final StringBuilder builder = new StringBuilder("ABC = ");
635         ObjectUtils.identityToString(builder, i);
636         assertEquals(expected, builder.toString());
637     }
638 
639     @Test
640     public  void testIdentityToStringStringBuilderNullStringBuilder() {
641         assertThrows(NullPointerException.class, () -> ObjectUtils.identityToString((StringBuilder) null, "tmp"));
642     }
643 
644     @Test
645     public void testIdentityToStringStringBuilderNullValue() {
646         assertThrows(NullPointerException.class, () -> ObjectUtils.identityToString(new StringBuilder(), null));
647     }
648 
649     @Test
650     public void testIsEmpty() {
651         assertTrue(ObjectUtils.isEmpty(null));
652         assertTrue(ObjectUtils.isEmpty(""));
653         assertTrue(ObjectUtils.isEmpty(new int[] {}));
654         assertTrue(ObjectUtils.isEmpty(Collections.emptyList()));
655         assertTrue(ObjectUtils.isEmpty(Collections.emptySet()));
656         assertTrue(ObjectUtils.isEmpty(Collections.emptyMap()));
657         assertTrue(ObjectUtils.isEmpty(Optional.empty()));
658         assertTrue(ObjectUtils.isEmpty(Optional.ofNullable(null)));
659 
660         assertFalse(ObjectUtils.isEmpty("  "));
661         assertFalse(ObjectUtils.isEmpty("ab"));
662         assertFalse(ObjectUtils.isEmpty(NON_EMPTY_ARRAY));
663         assertFalse(ObjectUtils.isEmpty(NON_EMPTY_LIST));
664         assertFalse(ObjectUtils.isEmpty(NON_EMPTY_SET));
665         assertFalse(ObjectUtils.isEmpty(NON_EMPTY_MAP));
666         assertFalse(ObjectUtils.isEmpty(Optional.of(new Object())));
667         assertFalse(ObjectUtils.isEmpty(Optional.ofNullable(new Object())));
668     }
669 
670     @Test
671     public void testIsNotEmpty() {
672         assertFalse(ObjectUtils.isNotEmpty(null));
673         assertFalse(ObjectUtils.isNotEmpty(""));
674         assertFalse(ObjectUtils.isNotEmpty(new int[] {}));
675         assertFalse(ObjectUtils.isNotEmpty(Collections.emptyList()));
676         assertFalse(ObjectUtils.isNotEmpty(Collections.emptySet()));
677         assertFalse(ObjectUtils.isNotEmpty(Collections.emptyMap()));
678         assertFalse(ObjectUtils.isNotEmpty(Optional.empty()));
679         assertFalse(ObjectUtils.isNotEmpty(Optional.ofNullable(null)));
680 
681         assertTrue(ObjectUtils.isNotEmpty("  "));
682         assertTrue(ObjectUtils.isNotEmpty("ab"));
683         assertTrue(ObjectUtils.isNotEmpty(NON_EMPTY_ARRAY));
684         assertTrue(ObjectUtils.isNotEmpty(NON_EMPTY_LIST));
685         assertTrue(ObjectUtils.isNotEmpty(NON_EMPTY_SET));
686         assertTrue(ObjectUtils.isNotEmpty(NON_EMPTY_MAP));
687         assertTrue(ObjectUtils.isNotEmpty(Optional.of(new Object())));
688         assertTrue(ObjectUtils.isNotEmpty(Optional.ofNullable(new Object())));
689     }
690 
691     @Test
692     public void testMax() {
693         final Calendar calendar = Calendar.getInstance();
694         final Date nonNullComparable1 = calendar.getTime();
695         final Date nonNullComparable2 = calendar.getTime();
696         final String[] nullArray = null;
697 
698         calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR) - 1);
699         final Date minComparable = calendar.getTime();
700 
701         assertNotSame(nonNullComparable1, nonNullComparable2);
702 
703         assertNull(ObjectUtils.max((String) null));
704         assertNull(ObjectUtils.max(nullArray));
705         assertSame(nonNullComparable1, ObjectUtils.max(null, nonNullComparable1));
706         assertSame(nonNullComparable1, ObjectUtils.max(nonNullComparable1, null));
707         assertSame(nonNullComparable1, ObjectUtils.max(null, nonNullComparable1, null));
708         assertSame(nonNullComparable1, ObjectUtils.max(nonNullComparable1, nonNullComparable2));
709         assertSame(nonNullComparable2, ObjectUtils.max(nonNullComparable2, nonNullComparable1));
710         assertSame(nonNullComparable1, ObjectUtils.max(nonNullComparable1, minComparable));
711         assertSame(nonNullComparable1, ObjectUtils.max(minComparable, nonNullComparable1));
712         assertSame(nonNullComparable1, ObjectUtils.max(null, minComparable, null, nonNullComparable1));
713 
714         assertNull(ObjectUtils.max(null, null));
715     }
716 
717     @Test
718     public void testMedian() {
719         assertEquals("foo", ObjectUtils.median("foo"));
720         assertEquals("bar", ObjectUtils.median("foo", "bar"));
721         assertEquals("baz", ObjectUtils.median("foo", "bar", "baz"));
722         assertEquals("baz", ObjectUtils.median("foo", "bar", "baz", "blah"));
723         assertEquals("blah", ObjectUtils.median("foo", "bar", "baz", "blah", "wah"));
724         assertEquals(Integer.valueOf(5),
725             ObjectUtils.median(Integer.valueOf(1), Integer.valueOf(5), Integer.valueOf(10)));
726         assertEquals(
727             Integer.valueOf(7),
728             ObjectUtils.median(Integer.valueOf(5), Integer.valueOf(6), Integer.valueOf(7), Integer.valueOf(8),
729                 Integer.valueOf(9)));
730         assertEquals(Integer.valueOf(6),
731             ObjectUtils.median(Integer.valueOf(5), Integer.valueOf(6), Integer.valueOf(7), Integer.valueOf(8)));
732     }
733 
734     @Test
735     public void testMedian_emptyItems() {
736         assertThrows(IllegalArgumentException.class, ObjectUtils::<String>median);
737     }
738 
739     @Test
740     public void testMedian_nullItems() {
741         assertThrows(NullPointerException.class, () -> ObjectUtils.median((String[]) null));
742     }
743 
744     @Test
745     public void testMin() {
746         final Calendar calendar = Calendar.getInstance();
747         final Date nonNullComparable1 = calendar.getTime();
748         final Date nonNullComparable2 = calendar.getTime();
749         final String[] nullArray = null;
750 
751         calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR) - 1);
752         final Date minComparable = calendar.getTime();
753 
754         assertNotSame(nonNullComparable1, nonNullComparable2);
755 
756         assertNull(ObjectUtils.min((String) null));
757         assertNull(ObjectUtils.min(nullArray));
758         assertSame(nonNullComparable1, ObjectUtils.min(null, nonNullComparable1));
759         assertSame(nonNullComparable1, ObjectUtils.min(nonNullComparable1, null));
760         assertSame(nonNullComparable1, ObjectUtils.min(null, nonNullComparable1, null));
761         assertSame(nonNullComparable1, ObjectUtils.min(nonNullComparable1, nonNullComparable2));
762         assertSame(nonNullComparable2, ObjectUtils.min(nonNullComparable2, nonNullComparable1));
763         assertSame(minComparable, ObjectUtils.min(nonNullComparable1, minComparable));
764         assertSame(minComparable, ObjectUtils.min(minComparable, nonNullComparable1));
765         assertSame(minComparable, ObjectUtils.min(null, nonNullComparable1, null, minComparable));
766 
767         assertNull(ObjectUtils.min(null, null));
768     }
769 
770     @Test
771     public void testMode() {
772         assertNull(ObjectUtils.mode((Object[]) null));
773         assertNull(ObjectUtils.mode());
774         assertNull(ObjectUtils.mode("foo", "bar", "baz"));
775         assertNull(ObjectUtils.mode("foo", "bar", "baz", "foo", "bar"));
776         assertEquals("foo", ObjectUtils.mode("foo", "bar", "baz", "foo"));
777         assertEquals(Integer.valueOf(9),
778             ObjectUtils.mode("foo", "bar", "baz", Integer.valueOf(9), Integer.valueOf(10), Integer.valueOf(9)));
779     }
780 
781     @Test
782     public void testNotEqual() {
783         assertFalse(ObjectUtils.notEqual(null, null), "ObjectUtils.notEqual(null, null) returned false");
784         assertTrue(ObjectUtils.notEqual(FOO, null), "ObjectUtils.notEqual(\"foo\", null) returned true");
785         assertTrue(ObjectUtils.notEqual(null, BAR), "ObjectUtils.notEqual(null, \"bar\") returned true");
786         assertTrue(ObjectUtils.notEqual(FOO, BAR), "ObjectUtils.notEqual(\"foo\", \"bar\") returned true");
787         assertFalse(ObjectUtils.notEqual(FOO, FOO), "ObjectUtils.notEqual(\"foo\", \"foo\") returned false");
788     }
789 
790     @SuppressWarnings("cast") // 1 OK, because we are checking for code change
791     @Test
792     public void testNull() {
793         assertNotNull(ObjectUtils.NULL);
794         // 1 Check that NULL really is a Null i.e. the definition has not been changed
795         assertTrue(ObjectUtils.NULL instanceof ObjectUtils.Null);
796         assertSame(ObjectUtils.NULL, SerializationUtils.clone(ObjectUtils.NULL));
797     }
798 
799     /**
800      * Tests {@link ObjectUtils#cloneIfPossible(Object)} with a cloneable object.
801      */
802     @Test
803     public void testPossibleCloneOfCloneable() {
804         final CloneableString string = new CloneableString("apache");
805         final CloneableString stringClone = ObjectUtils.cloneIfPossible(string);
806         assertEquals("apache", stringClone.getValue());
807     }
808 
809     /**
810      * Tests {@link ObjectUtils#cloneIfPossible(Object)} with a not cloneable object.
811      */
812     @Test
813     public void testPossibleCloneOfNotCloneable() {
814         final String string = "apache";
815         assertSame(string, ObjectUtils.cloneIfPossible(string));
816     }
817 
818     /**
819      * Tests {@link ObjectUtils#cloneIfPossible(Object)} with an uncloneable object.
820      */
821     @Test
822     public void testPossibleCloneOfUncloneable() {
823         final UncloneableString string = new UncloneableString("apache");
824         final CloneFailedException e = assertThrows(CloneFailedException.class, () -> ObjectUtils.cloneIfPossible(string));
825         assertNotNull(e);
826         assertNotNull(e.getCause());
827         assertEquals(NoSuchMethodException.class, e.getCause().getClass());
828     }
829 
830     @Test
831     public void testRequireNonEmpty() {
832         assertEquals("foo", ObjectUtils.requireNonEmpty("foo"));
833         assertEquals("foo", ObjectUtils.requireNonEmpty("foo", "foo"));
834         //
835         assertThrows(NullPointerException.class, () -> ObjectUtils.requireNonEmpty(null));
836         assertThrows(NullPointerException.class, () -> ObjectUtils.requireNonEmpty(null, "foo"));
837         //
838         assertThrows(IllegalArgumentException.class, () -> ObjectUtils.requireNonEmpty(""));
839         assertThrows(IllegalArgumentException.class, () -> ObjectUtils.requireNonEmpty("", "foo"));
840     }
841 
842     @Test
843     public void testToString_Object() {
844         assertEquals("", ObjectUtils.toString(null) );
845         assertEquals(Boolean.TRUE.toString(), ObjectUtils.toString(Boolean.TRUE) );
846     }
847 
848     @Test
849     public void testToString_Object_String() {
850         assertEquals(BAR, ObjectUtils.toString(null, BAR) );
851         assertEquals(Boolean.TRUE.toString(), ObjectUtils.toString(Boolean.TRUE, BAR) );
852     }
853 
854     @Test
855     public void testToString_String_Supplier() {
856         assertNull(ObjectUtils.toString(null, (Supplier<String>) null));
857         assertNull(ObjectUtils.toString(null, Suppliers.nul()));
858         // Pretend computing BAR is expensive.
859         assertEquals(BAR, ObjectUtils.toString(null, () -> BAR));
860         assertEquals(Boolean.TRUE.toString(), ObjectUtils.toString(Boolean.TRUE, () -> BAR));
861     }
862 
863     @Test
864     public void testToString_Supplier_Supplier() {
865         assertNull(ObjectUtils.toString(NULL_SUPPLIER, (Supplier<String>) null));
866         assertNull(ObjectUtils.toString(Suppliers.nul(), (Supplier<String>) null));
867         assertNull(ObjectUtils.toString(NULL_SUPPLIER, Suppliers.nul()));
868         assertNull(ObjectUtils.toString(Suppliers.nul(), Suppliers.nul()));
869         // Pretend computing BAR is expensive.
870         assertEquals(BAR, ObjectUtils.toString(NULL_SUPPLIER, () -> BAR));
871         assertEquals(BAR, ObjectUtils.toString(Suppliers.nul(), () -> BAR));
872         assertEquals(Boolean.TRUE.toString(), ObjectUtils.toString(() -> Boolean.TRUE, () -> BAR));
873     }
874 
875     @Test
876     public void testWaitDuration() {
877         assertThrows(IllegalMonitorStateException.class, () -> ObjectUtils.wait(new Object(), Duration.ZERO));
878     }
879 
880 }