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