1 /* 2 * Copyright (C) 2014 The Guava Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.common.base; 18 19 import com.google.common.annotations.GwtCompatible; 20 import com.google.common.annotations.GwtIncompatible; 21 import com.google.common.annotations.J2ktIncompatible; 22 import com.google.common.collect.ImmutableMap; 23 import com.google.common.testing.NullPointerTester; 24 import java.util.Arrays; 25 import java.util.Map; 26 import junit.framework.TestCase; 27 28 /** Tests for {@link MoreObjects}. */ 29 @GwtCompatible(emulated = true) 30 public class MoreObjectsTest extends TestCase { testFirstNonNull_withNonNull()31 public void testFirstNonNull_withNonNull() { 32 String s1 = "foo"; 33 String s2 = MoreObjects.firstNonNull(s1, "bar"); 34 assertSame(s1, s2); 35 36 Long n1 = 42L; 37 Long n2 = MoreObjects.firstNonNull(null, n1); 38 assertSame(n1, n2); 39 40 Boolean b1 = true; 41 Boolean b2 = MoreObjects.firstNonNull(b1, null); 42 assertSame(b1, b2); 43 } 44 testFirstNonNull_throwsNullPointerException()45 public void testFirstNonNull_throwsNullPointerException() { 46 try { 47 MoreObjects.firstNonNull(null, null); 48 fail(); 49 } catch (NullPointerException expected) { 50 } 51 } 52 testToStringHelperWithArrays()53 public void testToStringHelperWithArrays() { 54 String[] strings = {"hello", "world"}; 55 int[] ints = {2, 42}; 56 Object[] objects = {"obj"}; 57 String[] arrayWithNull = {null}; 58 Object[] empty = {}; 59 String toTest = 60 MoreObjects.toStringHelper("TSH") 61 .add("strings", strings) 62 .add("ints", ints) 63 .add("objects", objects) 64 .add("arrayWithNull", arrayWithNull) 65 .add("empty", empty) 66 .toString(); 67 assertEquals( 68 "TSH{strings=[hello, world], ints=[2, 42], objects=[obj], arrayWithNull=[null], empty=[]}", 69 toTest); 70 } 71 72 @J2ktIncompatible 73 @GwtIncompatible // Class names are obfuscated in GWT testConstructor_instance()74 public void testConstructor_instance() { 75 String toTest = MoreObjects.toStringHelper(this).toString(); 76 assertEquals("MoreObjectsTest{}", toTest); 77 } 78 testConstructorLenient_instance()79 public void testConstructorLenient_instance() { 80 String toTest = MoreObjects.toStringHelper(this).toString(); 81 assertTrue(toTest, toTest.matches(".*\\{\\}")); 82 } 83 84 @J2ktIncompatible 85 @GwtIncompatible // Class names are obfuscated in GWT testConstructor_innerClass()86 public void testConstructor_innerClass() { 87 String toTest = MoreObjects.toStringHelper(new TestClass()).toString(); 88 assertEquals("TestClass{}", toTest); 89 } 90 testConstructorLenient_innerClass()91 public void testConstructorLenient_innerClass() { 92 String toTest = MoreObjects.toStringHelper(new TestClass()).toString(); 93 assertTrue(toTest, toTest.matches(".*\\{\\}")); 94 } 95 96 @J2ktIncompatible 97 @GwtIncompatible // Class names are obfuscated in GWT testConstructor_anonymousClass()98 public void testConstructor_anonymousClass() { 99 String toTest = MoreObjects.toStringHelper(new Object() {}).toString(); 100 assertEquals("{}", toTest); 101 } 102 testConstructorLenient_anonymousClass()103 public void testConstructorLenient_anonymousClass() { 104 String toTest = MoreObjects.toStringHelper(new Object() {}).toString(); 105 assertTrue(toTest, toTest.matches(".*\\{\\}")); 106 } 107 108 @J2ktIncompatible 109 @GwtIncompatible // Class names are obfuscated in GWT testConstructor_classObject()110 public void testConstructor_classObject() { 111 String toTest = MoreObjects.toStringHelper(TestClass.class).toString(); 112 assertEquals("TestClass{}", toTest); 113 } 114 testConstructorLenient_classObject()115 public void testConstructorLenient_classObject() { 116 String toTest = MoreObjects.toStringHelper(TestClass.class).toString(); 117 assertTrue(toTest, toTest.matches(".*\\{\\}")); 118 } 119 testConstructor_stringObject()120 public void testConstructor_stringObject() { 121 String toTest = MoreObjects.toStringHelper("FooBar").toString(); 122 assertEquals("FooBar{}", toTest); 123 } 124 125 @J2ktIncompatible 126 @GwtIncompatible // Class names are obfuscated in GWT testToStringHelper_localInnerClass()127 public void testToStringHelper_localInnerClass() { 128 // Local inner classes have names ending like "Outer.$1Inner" 129 class LocalInnerClass {} 130 String toTest = MoreObjects.toStringHelper(new LocalInnerClass()).toString(); 131 assertEquals("LocalInnerClass{}", toTest); 132 } 133 testToStringHelperLenient_localInnerClass()134 public void testToStringHelperLenient_localInnerClass() { 135 class LocalInnerClass {} 136 String toTest = MoreObjects.toStringHelper(new LocalInnerClass()).toString(); 137 assertTrue(toTest, toTest.matches(".*\\{\\}")); 138 } 139 140 @J2ktIncompatible 141 @GwtIncompatible // Class names are obfuscated in GWT testToStringHelper_localInnerNestedClass()142 public void testToStringHelper_localInnerNestedClass() { 143 class LocalInnerClass { 144 class LocalInnerNestedClass {} 145 } 146 String toTest = 147 MoreObjects.toStringHelper(new LocalInnerClass().new LocalInnerNestedClass()).toString(); 148 assertEquals("LocalInnerNestedClass{}", toTest); 149 } 150 testToStringHelperLenient_localInnerNestedClass()151 public void testToStringHelperLenient_localInnerNestedClass() { 152 class LocalInnerClass { 153 class LocalInnerNestedClass {} 154 } 155 String toTest = 156 MoreObjects.toStringHelper(new LocalInnerClass().new LocalInnerNestedClass()).toString(); 157 assertTrue(toTest, toTest.matches(".*\\{\\}")); 158 } 159 160 @J2ktIncompatible 161 @GwtIncompatible // Class names are obfuscated in GWT testToStringHelper_moreThanNineAnonymousClasses()162 public void testToStringHelper_moreThanNineAnonymousClasses() { 163 // The nth anonymous class has a name ending like "Outer.$n" 164 Object o1 = new Object() {}; 165 Object o2 = new Object() {}; 166 Object o3 = new Object() {}; 167 Object o4 = new Object() {}; 168 Object o5 = new Object() {}; 169 Object o6 = new Object() {}; 170 Object o7 = new Object() {}; 171 Object o8 = new Object() {}; 172 Object o9 = new Object() {}; 173 Object o10 = new Object() {}; 174 String toTest = MoreObjects.toStringHelper(o10).toString(); 175 assertEquals("{}", toTest); 176 } 177 testToStringHelperLenient_moreThanNineAnonymousClasses()178 public void testToStringHelperLenient_moreThanNineAnonymousClasses() { 179 // The nth anonymous class has a name ending like "Outer.$n" 180 Object o1 = new Object() {}; 181 Object o2 = new Object() {}; 182 Object o3 = new Object() {}; 183 Object o4 = new Object() {}; 184 Object o5 = new Object() {}; 185 Object o6 = new Object() {}; 186 Object o7 = new Object() {}; 187 Object o8 = new Object() {}; 188 Object o9 = new Object() {}; 189 Object o10 = new Object() {}; 190 String toTest = MoreObjects.toStringHelper(o10).toString(); 191 assertTrue(toTest, toTest.matches(".*\\{\\}")); 192 } 193 194 // all remaining test are on an inner class with various fields 195 @J2ktIncompatible 196 @GwtIncompatible // Class names are obfuscated in GWT testToString_oneField()197 public void testToString_oneField() { 198 String toTest = MoreObjects.toStringHelper(new TestClass()).add("field1", "Hello").toString(); 199 assertEquals("TestClass{field1=Hello}", toTest); 200 } 201 202 @J2ktIncompatible 203 @GwtIncompatible // Class names are obfuscated in GWT testToString_oneIntegerField()204 public void testToString_oneIntegerField() { 205 String toTest = 206 MoreObjects.toStringHelper(new TestClass()).add("field1", new Integer(42)).toString(); 207 assertEquals("TestClass{field1=42}", toTest); 208 } 209 210 @J2ktIncompatible 211 @GwtIncompatible // Class names are obfuscated in GWT testToString_nullInteger()212 public void testToString_nullInteger() { 213 String toTest = 214 MoreObjects.toStringHelper(new TestClass()).add("field1", (Integer) null).toString(); 215 assertEquals("TestClass{field1=null}", toTest); 216 } 217 testToStringLenient_oneField()218 public void testToStringLenient_oneField() { 219 String toTest = MoreObjects.toStringHelper(new TestClass()).add("field1", "Hello").toString(); 220 assertTrue(toTest, toTest.matches(".*\\{field1\\=Hello\\}")); 221 } 222 testToStringLenient_oneIntegerField()223 public void testToStringLenient_oneIntegerField() { 224 String toTest = 225 MoreObjects.toStringHelper(new TestClass()).add("field1", new Integer(42)).toString(); 226 assertTrue(toTest, toTest.matches(".*\\{field1\\=42\\}")); 227 } 228 testToStringLenient_nullInteger()229 public void testToStringLenient_nullInteger() { 230 String toTest = 231 MoreObjects.toStringHelper(new TestClass()).add("field1", (Integer) null).toString(); 232 assertTrue(toTest, toTest.matches(".*\\{field1\\=null\\}")); 233 } 234 235 @J2ktIncompatible 236 @GwtIncompatible // Class names are obfuscated in GWT testToString_complexFields()237 public void testToString_complexFields() { 238 Map<String, Integer> map = 239 ImmutableMap.<String, Integer>builder().put("abc", 1).put("def", 2).put("ghi", 3).build(); 240 String toTest = 241 MoreObjects.toStringHelper(new TestClass()) 242 .add("field1", "This is string.") 243 .add("field2", Arrays.asList("abc", "def", "ghi")) 244 .add("field3", map) 245 .toString(); 246 final String expected = 247 "TestClass{" 248 + "field1=This is string., field2=[abc, def, ghi], field3={abc=1, def=2, ghi=3}}"; 249 250 assertEquals(expected, toTest); 251 } 252 testToStringLenient_complexFields()253 public void testToStringLenient_complexFields() { 254 Map<String, Integer> map = 255 ImmutableMap.<String, Integer>builder().put("abc", 1).put("def", 2).put("ghi", 3).build(); 256 String toTest = 257 MoreObjects.toStringHelper(new TestClass()) 258 .add("field1", "This is string.") 259 .add("field2", Arrays.asList("abc", "def", "ghi")) 260 .add("field3", map) 261 .toString(); 262 final String expectedRegex = 263 ".*\\{" 264 + "field1\\=This is string\\., " 265 + "field2\\=\\[abc, def, ghi\\], " 266 + "field3=\\{abc\\=1, def\\=2, ghi\\=3\\}\\}"; 267 268 assertTrue(toTest, toTest.matches(expectedRegex)); 269 } 270 testToString_addWithNullName()271 public void testToString_addWithNullName() { 272 MoreObjects.ToStringHelper helper = MoreObjects.toStringHelper(new TestClass()); 273 try { 274 helper.add(null, "Hello"); 275 fail("No exception was thrown."); 276 } catch (NullPointerException expected) { 277 } 278 } 279 280 @J2ktIncompatible 281 @GwtIncompatible // Class names are obfuscated in GWT testToString_addWithNullValue()282 public void testToString_addWithNullValue() { 283 final String result = MoreObjects.toStringHelper(new TestClass()).add("Hello", null).toString(); 284 285 assertEquals("TestClass{Hello=null}", result); 286 } 287 testToStringLenient_addWithNullValue()288 public void testToStringLenient_addWithNullValue() { 289 final String result = MoreObjects.toStringHelper(new TestClass()).add("Hello", null).toString(); 290 assertTrue(result, result.matches(".*\\{Hello\\=null\\}")); 291 } 292 293 @J2ktIncompatible 294 @GwtIncompatible // Class names are obfuscated in GWT testToString_ToStringTwice()295 public void testToString_ToStringTwice() { 296 MoreObjects.ToStringHelper helper = 297 MoreObjects.toStringHelper(new TestClass()) 298 .add("field1", 1) 299 .addValue("value1") 300 .add("field2", "value2"); 301 final String expected = "TestClass{field1=1, value1, field2=value2}"; 302 303 assertEquals(expected, helper.toString()); 304 // Call toString again 305 assertEquals(expected, helper.toString()); 306 307 // Make sure the cached value is reset when we modify the helper at all 308 final String expected2 = "TestClass{field1=1, value1, field2=value2, 2}"; 309 helper.addValue(2); 310 assertEquals(expected2, helper.toString()); 311 } 312 313 @J2ktIncompatible 314 @GwtIncompatible // Class names are obfuscated in GWT testToString_addValue()315 public void testToString_addValue() { 316 String toTest = 317 MoreObjects.toStringHelper(new TestClass()) 318 .add("field1", 1) 319 .addValue("value1") 320 .add("field2", "value2") 321 .addValue(2) 322 .toString(); 323 final String expected = "TestClass{field1=1, value1, field2=value2, 2}"; 324 325 assertEquals(expected, toTest); 326 } 327 testToStringLenient_addValue()328 public void testToStringLenient_addValue() { 329 String toTest = 330 MoreObjects.toStringHelper(new TestClass()) 331 .add("field1", 1) 332 .addValue("value1") 333 .add("field2", "value2") 334 .addValue(2) 335 .toString(); 336 final String expected = ".*\\{field1\\=1, value1, field2\\=value2, 2\\}"; 337 338 assertTrue(toTest, toTest.matches(expected)); 339 } 340 341 @J2ktIncompatible 342 @GwtIncompatible // Class names are obfuscated in GWT testToString_addValueWithNullValue()343 public void testToString_addValueWithNullValue() { 344 final String result = 345 MoreObjects.toStringHelper(new TestClass()) 346 .addValue(null) 347 .addValue("Hello") 348 .addValue(null) 349 .toString(); 350 final String expected = "TestClass{null, Hello, null}"; 351 352 assertEquals(expected, result); 353 } 354 testToStringLenient_addValueWithNullValue()355 public void testToStringLenient_addValueWithNullValue() { 356 final String result = 357 MoreObjects.toStringHelper(new TestClass()) 358 .addValue(null) 359 .addValue("Hello") 360 .addValue(null) 361 .toString(); 362 final String expected = ".*\\{null, Hello, null\\}"; 363 364 assertTrue(result, result.matches(expected)); 365 } 366 367 @J2ktIncompatible 368 @GwtIncompatible // Class names are obfuscated in GWT testToStringOmitNullValues_oneField()369 public void testToStringOmitNullValues_oneField() { 370 String toTest = 371 MoreObjects.toStringHelper(new TestClass()).omitNullValues().add("field1", null).toString(); 372 assertEquals("TestClass{}", toTest); 373 } 374 375 @J2ktIncompatible 376 @GwtIncompatible // Class names are obfuscated in GWT testToStringOmitNullValues_manyFieldsFirstNull()377 public void testToStringOmitNullValues_manyFieldsFirstNull() { 378 String toTest = 379 MoreObjects.toStringHelper(new TestClass()) 380 .omitNullValues() 381 .add("field1", null) 382 .add("field2", "Googley") 383 .add("field3", "World") 384 .toString(); 385 assertEquals("TestClass{field2=Googley, field3=World}", toTest); 386 } 387 388 @J2ktIncompatible 389 @GwtIncompatible // Class names are obfuscated in GWT testToStringOmitNullValues_manyFieldsOmitAfterNull()390 public void testToStringOmitNullValues_manyFieldsOmitAfterNull() { 391 String toTest = 392 MoreObjects.toStringHelper(new TestClass()) 393 .add("field1", null) 394 .add("field2", "Googley") 395 .add("field3", "World") 396 .omitNullValues() 397 .toString(); 398 assertEquals("TestClass{field2=Googley, field3=World}", toTest); 399 } 400 401 @J2ktIncompatible 402 @GwtIncompatible // Class names are obfuscated in GWT testToStringOmitNullValues_manyFieldsLastNull()403 public void testToStringOmitNullValues_manyFieldsLastNull() { 404 String toTest = 405 MoreObjects.toStringHelper(new TestClass()) 406 .omitNullValues() 407 .add("field1", "Hello") 408 .add("field2", "Googley") 409 .add("field3", null) 410 .toString(); 411 assertEquals("TestClass{field1=Hello, field2=Googley}", toTest); 412 } 413 414 @J2ktIncompatible 415 @GwtIncompatible // Class names are obfuscated in GWT testToStringOmitNullValues_oneValue()416 public void testToStringOmitNullValues_oneValue() { 417 String toTest = 418 MoreObjects.toStringHelper(new TestClass()).omitNullValues().addValue(null).toString(); 419 assertEquals("TestClass{}", toTest); 420 } 421 422 @J2ktIncompatible 423 @GwtIncompatible // Class names are obfuscated in GWT testToStringOmitNullValues_manyValuesFirstNull()424 public void testToStringOmitNullValues_manyValuesFirstNull() { 425 String toTest = 426 MoreObjects.toStringHelper(new TestClass()) 427 .omitNullValues() 428 .addValue(null) 429 .addValue("Googley") 430 .addValue("World") 431 .toString(); 432 assertEquals("TestClass{Googley, World}", toTest); 433 } 434 435 @J2ktIncompatible 436 @GwtIncompatible // Class names are obfuscated in GWT testToStringOmitNullValues_manyValuesLastNull()437 public void testToStringOmitNullValues_manyValuesLastNull() { 438 String toTest = 439 MoreObjects.toStringHelper(new TestClass()) 440 .omitNullValues() 441 .addValue("Hello") 442 .addValue("Googley") 443 .addValue(null) 444 .toString(); 445 assertEquals("TestClass{Hello, Googley}", toTest); 446 } 447 448 @J2ktIncompatible 449 @GwtIncompatible // Class names are obfuscated in GWT testToStringOmitNullValues_differentOrder()450 public void testToStringOmitNullValues_differentOrder() { 451 String expected = "TestClass{field1=Hello, field2=Googley, field3=World}"; 452 String toTest1 = 453 MoreObjects.toStringHelper(new TestClass()) 454 .omitNullValues() 455 .add("field1", "Hello") 456 .add("field2", "Googley") 457 .add("field3", "World") 458 .toString(); 459 String toTest2 = 460 MoreObjects.toStringHelper(new TestClass()) 461 .add("field1", "Hello") 462 .add("field2", "Googley") 463 .omitNullValues() 464 .add("field3", "World") 465 .toString(); 466 assertEquals(expected, toTest1); 467 assertEquals(expected, toTest2); 468 } 469 470 @J2ktIncompatible 471 @GwtIncompatible // Class names are obfuscated in GWT testToStringOmitNullValues_canBeCalledManyTimes()472 public void testToStringOmitNullValues_canBeCalledManyTimes() { 473 String toTest = 474 MoreObjects.toStringHelper(new TestClass()) 475 .omitNullValues() 476 .omitNullValues() 477 .add("field1", "Hello") 478 .omitNullValues() 479 .add("field2", "Googley") 480 .omitNullValues() 481 .add("field3", "World") 482 .toString(); 483 assertEquals("TestClass{field1=Hello, field2=Googley, field3=World}", toTest); 484 } 485 486 @J2ktIncompatible 487 @GwtIncompatible("NullPointerTester") testNulls()488 public void testNulls() throws Exception { 489 NullPointerTester tester = new NullPointerTester(); 490 tester.ignore(MoreObjects.class.getMethod("firstNonNull", Object.class, Object.class)); 491 tester.testAllPublicStaticMethods(MoreObjects.class); 492 tester.testAllPublicInstanceMethods(MoreObjects.toStringHelper(new TestClass())); 493 } 494 495 /** Test class for testing formatting of inner classes. */ 496 private static class TestClass {} 497 } 498