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