1 /* 2 * Copyright (C) 2009 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.collect.ImmutableMap; 22 import java.util.Arrays; 23 import java.util.Map; 24 import junit.framework.TestCase; 25 26 /** 27 * Tests for {@link MoreObjects#toStringHelper(Object)}. 28 * 29 * @author Jason Lee 30 */ 31 @GwtCompatible 32 public class ToStringHelperTest extends TestCase { 33 34 @GwtIncompatible // Class names are obfuscated in GWT testConstructor_instance()35 public void testConstructor_instance() { 36 String toTest = MoreObjects.toStringHelper(this).toString(); 37 assertEquals("ToStringHelperTest{}", toTest); 38 } 39 testConstructorLenient_instance()40 public void testConstructorLenient_instance() { 41 String toTest = MoreObjects.toStringHelper(this).toString(); 42 assertTrue(toTest, toTest.matches(".*\\{\\}")); 43 } 44 45 @GwtIncompatible // Class names are obfuscated in GWT testConstructor_innerClass()46 public void testConstructor_innerClass() { 47 String toTest = MoreObjects.toStringHelper(new TestClass()).toString(); 48 assertEquals("TestClass{}", toTest); 49 } 50 testConstructorLenient_innerClass()51 public void testConstructorLenient_innerClass() { 52 String toTest = MoreObjects.toStringHelper(new TestClass()).toString(); 53 assertTrue(toTest, toTest.matches(".*\\{\\}")); 54 } 55 56 @GwtIncompatible // Class names are obfuscated in GWT testConstructor_anonymousClass()57 public void testConstructor_anonymousClass() { 58 String toTest = MoreObjects.toStringHelper(new Object() {}).toString(); 59 assertEquals("{}", toTest); 60 } 61 testConstructorLenient_anonymousClass()62 public void testConstructorLenient_anonymousClass() { 63 String toTest = MoreObjects.toStringHelper(new Object() {}).toString(); 64 assertTrue(toTest, toTest.matches(".*\\{\\}")); 65 } 66 67 @GwtIncompatible // Class names are obfuscated in GWT testConstructor_classObject()68 public void testConstructor_classObject() { 69 String toTest = MoreObjects.toStringHelper(TestClass.class).toString(); 70 assertEquals("TestClass{}", toTest); 71 } 72 testConstructorLenient_classObject()73 public void testConstructorLenient_classObject() { 74 String toTest = MoreObjects.toStringHelper(TestClass.class).toString(); 75 assertTrue(toTest, toTest.matches(".*\\{\\}")); 76 } 77 testConstructor_stringObject()78 public void testConstructor_stringObject() { 79 String toTest = MoreObjects.toStringHelper("FooBar").toString(); 80 assertEquals("FooBar{}", toTest); 81 } 82 83 @GwtIncompatible // Class names are obfuscated in GWT testToStringHelper_localInnerClass()84 public void testToStringHelper_localInnerClass() { 85 // Local inner classes have names ending like "Outer.$1Inner" 86 class LocalInnerClass {} 87 String toTest = MoreObjects.toStringHelper(new LocalInnerClass()).toString(); 88 assertEquals("LocalInnerClass{}", toTest); 89 } 90 testToStringHelperLenient_localInnerClass()91 public void testToStringHelperLenient_localInnerClass() { 92 class LocalInnerClass {} 93 String toTest = MoreObjects.toStringHelper(new LocalInnerClass()).toString(); 94 assertTrue(toTest, toTest.matches(".*\\{\\}")); 95 } 96 97 @GwtIncompatible // Class names are obfuscated in GWT testToStringHelper_localInnerNestedClass()98 public void testToStringHelper_localInnerNestedClass() { 99 class LocalInnerClass { 100 class LocalInnerNestedClass {} 101 } 102 String toTest = 103 MoreObjects.toStringHelper(new LocalInnerClass().new LocalInnerNestedClass()).toString(); 104 assertEquals("LocalInnerNestedClass{}", toTest); 105 } 106 testToStringHelperLenient_localInnerNestedClass()107 public void testToStringHelperLenient_localInnerNestedClass() { 108 class LocalInnerClass { 109 class LocalInnerNestedClass {} 110 } 111 String toTest = 112 MoreObjects.toStringHelper(new LocalInnerClass().new LocalInnerNestedClass()).toString(); 113 assertTrue(toTest, toTest.matches(".*\\{\\}")); 114 } 115 116 @GwtIncompatible // Class names are obfuscated in GWT testToStringHelper_moreThanNineAnonymousClasses()117 public void testToStringHelper_moreThanNineAnonymousClasses() { 118 // The nth anonymous class has a name ending like "Outer.$n" 119 Object unused1 = new Object() {}; 120 Object unused2 = new Object() {}; 121 Object unused3 = new Object() {}; 122 Object unused4 = new Object() {}; 123 Object unused5 = new Object() {}; 124 Object unused6 = new Object() {}; 125 Object unused7 = new Object() {}; 126 Object unused8 = new Object() {}; 127 Object unused9 = new Object() {}; 128 Object o10 = new Object() {}; 129 String toTest = MoreObjects.toStringHelper(o10).toString(); 130 assertEquals("{}", toTest); 131 } 132 testToStringHelperLenient_moreThanNineAnonymousClasses()133 public void testToStringHelperLenient_moreThanNineAnonymousClasses() { 134 // The nth anonymous class has a name ending like "Outer.$n" 135 Object unused1 = new Object() {}; 136 Object unused2 = new Object() {}; 137 Object unused3 = new Object() {}; 138 Object unused4 = new Object() {}; 139 Object unused5 = new Object() {}; 140 Object unused6 = new Object() {}; 141 Object unused7 = new Object() {}; 142 Object unused8 = new Object() {}; 143 Object unused9 = new Object() {}; 144 Object o10 = new Object() {}; 145 String toTest = MoreObjects.toStringHelper(o10).toString(); 146 assertTrue(toTest, toTest.matches(".*\\{\\}")); 147 } 148 149 // all remaining test are on an inner class with various fields 150 @GwtIncompatible // Class names are obfuscated in GWT testToString_oneField()151 public void testToString_oneField() { 152 String toTest = MoreObjects.toStringHelper(new TestClass()).add("field1", "Hello").toString(); 153 assertEquals("TestClass{field1=Hello}", toTest); 154 } 155 156 @GwtIncompatible // Class names are obfuscated in GWT testToString_oneIntegerField()157 public void testToString_oneIntegerField() { 158 String toTest = 159 MoreObjects.toStringHelper(new TestClass()).add("field1", new Integer(42)).toString(); 160 assertEquals("TestClass{field1=42}", toTest); 161 } 162 163 @GwtIncompatible // Class names are obfuscated in GWT testToString_nullInteger()164 public void testToString_nullInteger() { 165 String toTest = 166 MoreObjects.toStringHelper(new TestClass()).add("field1", (Integer) null).toString(); 167 assertEquals("TestClass{field1=null}", toTest); 168 } 169 testToStringLenient_oneField()170 public void testToStringLenient_oneField() { 171 String toTest = MoreObjects.toStringHelper(new TestClass()).add("field1", "Hello").toString(); 172 assertTrue(toTest, toTest.matches(".*\\{field1\\=Hello\\}")); 173 } 174 testToStringLenient_oneIntegerField()175 public void testToStringLenient_oneIntegerField() { 176 String toTest = 177 MoreObjects.toStringHelper(new TestClass()).add("field1", new Integer(42)).toString(); 178 assertTrue(toTest, toTest.matches(".*\\{field1\\=42\\}")); 179 } 180 testToStringLenient_nullInteger()181 public void testToStringLenient_nullInteger() { 182 String toTest = 183 MoreObjects.toStringHelper(new TestClass()).add("field1", (Integer) null).toString(); 184 assertTrue(toTest, toTest.matches(".*\\{field1\\=null\\}")); 185 } 186 187 @GwtIncompatible // Class names are obfuscated in GWT testToString_complexFields()188 public void testToString_complexFields() { 189 190 Map<String, Integer> map = 191 ImmutableMap.<String, Integer>builder().put("abc", 1).put("def", 2).put("ghi", 3).build(); 192 String toTest = 193 MoreObjects.toStringHelper(new TestClass()) 194 .add("field1", "This is string.") 195 .add("field2", Arrays.asList("abc", "def", "ghi")) 196 .add("field3", map) 197 .toString(); 198 final String expected = 199 "TestClass{" 200 + "field1=This is string., field2=[abc, def, ghi], field3={abc=1, def=2, ghi=3}}"; 201 202 assertEquals(expected, toTest); 203 } 204 testToStringLenient_complexFields()205 public void testToStringLenient_complexFields() { 206 207 Map<String, Integer> map = 208 ImmutableMap.<String, Integer>builder().put("abc", 1).put("def", 2).put("ghi", 3).build(); 209 String toTest = 210 MoreObjects.toStringHelper(new TestClass()) 211 .add("field1", "This is string.") 212 .add("field2", Arrays.asList("abc", "def", "ghi")) 213 .add("field3", map) 214 .toString(); 215 final String expectedRegex = 216 ".*\\{" 217 + "field1\\=This is string\\., " 218 + "field2\\=\\[abc, def, ghi\\], " 219 + "field3=\\{abc\\=1, def\\=2, ghi\\=3\\}\\}"; 220 221 assertTrue(toTest, toTest.matches(expectedRegex)); 222 } 223 testToString_addWithNullName()224 public void testToString_addWithNullName() { 225 MoreObjects.ToStringHelper helper = MoreObjects.toStringHelper(new TestClass()); 226 try { 227 helper.add(null, "Hello"); 228 fail("No exception was thrown."); 229 } catch (NullPointerException expected) { 230 } 231 } 232 233 @GwtIncompatible // Class names are obfuscated in GWT testToString_addWithNullValue()234 public void testToString_addWithNullValue() { 235 final String result = MoreObjects.toStringHelper(new TestClass()).add("Hello", null).toString(); 236 237 assertEquals("TestClass{Hello=null}", result); 238 } 239 testToStringLenient_addWithNullValue()240 public void testToStringLenient_addWithNullValue() { 241 final String result = MoreObjects.toStringHelper(new TestClass()).add("Hello", null).toString(); 242 assertTrue(result, result.matches(".*\\{Hello\\=null\\}")); 243 } 244 245 @GwtIncompatible // Class names are obfuscated in GWT testToString_ToStringTwice()246 public void testToString_ToStringTwice() { 247 MoreObjects.ToStringHelper helper = 248 MoreObjects.toStringHelper(new TestClass()) 249 .add("field1", 1) 250 .addValue("value1") 251 .add("field2", "value2"); 252 final String expected = "TestClass{field1=1, value1, field2=value2}"; 253 254 assertEquals(expected, helper.toString()); 255 // Call toString again 256 assertEquals(expected, helper.toString()); 257 258 // Make sure the cached value is reset when we modify the helper at all 259 final String expected2 = "TestClass{field1=1, value1, field2=value2, 2}"; 260 helper.addValue(2); 261 assertEquals(expected2, helper.toString()); 262 } 263 264 @GwtIncompatible // Class names are obfuscated in GWT testToString_addValue()265 public void testToString_addValue() { 266 String toTest = 267 MoreObjects.toStringHelper(new TestClass()) 268 .add("field1", 1) 269 .addValue("value1") 270 .add("field2", "value2") 271 .addValue(2) 272 .toString(); 273 final String expected = "TestClass{field1=1, value1, field2=value2, 2}"; 274 275 assertEquals(expected, toTest); 276 } 277 testToStringLenient_addValue()278 public void testToStringLenient_addValue() { 279 String toTest = 280 MoreObjects.toStringHelper(new TestClass()) 281 .add("field1", 1) 282 .addValue("value1") 283 .add("field2", "value2") 284 .addValue(2) 285 .toString(); 286 final String expected = ".*\\{field1\\=1, value1, field2\\=value2, 2\\}"; 287 288 assertTrue(toTest, toTest.matches(expected)); 289 } 290 291 @GwtIncompatible // Class names are obfuscated in GWT testToString_addValueWithNullValue()292 public void testToString_addValueWithNullValue() { 293 final String result = 294 MoreObjects.toStringHelper(new TestClass()) 295 .addValue(null) 296 .addValue("Hello") 297 .addValue(null) 298 .toString(); 299 final String expected = "TestClass{null, Hello, null}"; 300 301 assertEquals(expected, result); 302 } 303 testToStringLenient_addValueWithNullValue()304 public void testToStringLenient_addValueWithNullValue() { 305 final String result = 306 MoreObjects.toStringHelper(new TestClass()) 307 .addValue(null) 308 .addValue("Hello") 309 .addValue(null) 310 .toString(); 311 final String expected = ".*\\{null, Hello, null\\}"; 312 313 assertTrue(result, result.matches(expected)); 314 } 315 316 @GwtIncompatible // Class names are obfuscated in GWT testToStringOmitNullValues_oneField()317 public void testToStringOmitNullValues_oneField() { 318 String toTest = 319 MoreObjects.toStringHelper(new TestClass()).omitNullValues().add("field1", null).toString(); 320 assertEquals("TestClass{}", toTest); 321 } 322 323 @GwtIncompatible // Class names are obfuscated in GWT testToStringOmitNullValues_manyFieldsFirstNull()324 public void testToStringOmitNullValues_manyFieldsFirstNull() { 325 String toTest = 326 MoreObjects.toStringHelper(new TestClass()) 327 .omitNullValues() 328 .add("field1", null) 329 .add("field2", "Googley") 330 .add("field3", "World") 331 .toString(); 332 assertEquals("TestClass{field2=Googley, field3=World}", toTest); 333 } 334 335 @GwtIncompatible // Class names are obfuscated in GWT testToStringOmitNullValues_manyFieldsOmitAfterNull()336 public void testToStringOmitNullValues_manyFieldsOmitAfterNull() { 337 String toTest = 338 MoreObjects.toStringHelper(new TestClass()) 339 .add("field1", null) 340 .add("field2", "Googley") 341 .add("field3", "World") 342 .omitNullValues() 343 .toString(); 344 assertEquals("TestClass{field2=Googley, field3=World}", toTest); 345 } 346 347 @GwtIncompatible // Class names are obfuscated in GWT testToStringOmitNullValues_manyFieldsLastNull()348 public void testToStringOmitNullValues_manyFieldsLastNull() { 349 String toTest = 350 MoreObjects.toStringHelper(new TestClass()) 351 .omitNullValues() 352 .add("field1", "Hello") 353 .add("field2", "Googley") 354 .add("field3", null) 355 .toString(); 356 assertEquals("TestClass{field1=Hello, field2=Googley}", toTest); 357 } 358 359 @GwtIncompatible // Class names are obfuscated in GWT testToStringOmitEmptyValues_oneValue()360 public void testToStringOmitEmptyValues_oneValue() { 361 String toTest = 362 MoreObjects.toStringHelper(new TestClass()).omitNullValues().addValue(null).toString(); 363 assertEquals("TestClass{}", toTest); 364 } 365 366 @GwtIncompatible // Class names are obfuscated in GWT testToStringOmitNullValues_manyValuesFirstNull()367 public void testToStringOmitNullValues_manyValuesFirstNull() { 368 String toTest = 369 MoreObjects.toStringHelper(new TestClass()) 370 .omitNullValues() 371 .addValue(null) 372 .addValue("Googley") 373 .addValue("World") 374 .toString(); 375 assertEquals("TestClass{Googley, World}", toTest); 376 } 377 378 @GwtIncompatible // Class names are obfuscated in GWT testToStringOmitNullValues_manyValuesLastNull()379 public void testToStringOmitNullValues_manyValuesLastNull() { 380 String toTest = 381 MoreObjects.toStringHelper(new TestClass()) 382 .omitNullValues() 383 .addValue("Hello") 384 .addValue("Googley") 385 .addValue(null) 386 .toString(); 387 assertEquals("TestClass{Hello, Googley}", toTest); 388 } 389 390 @GwtIncompatible // Class names are obfuscated in GWT testToStringOmitNullValues_differentOrder()391 public void testToStringOmitNullValues_differentOrder() { 392 String expected = "TestClass{field1=Hello, field2=Googley, field3=World}"; 393 String toTest1 = 394 MoreObjects.toStringHelper(new TestClass()) 395 .omitNullValues() 396 .add("field1", "Hello") 397 .add("field2", "Googley") 398 .add("field3", "World") 399 .toString(); 400 String toTest2 = 401 MoreObjects.toStringHelper(new TestClass()) 402 .add("field1", "Hello") 403 .add("field2", "Googley") 404 .omitNullValues() 405 .add("field3", "World") 406 .toString(); 407 assertEquals(expected, toTest1); 408 assertEquals(expected, toTest2); 409 } 410 411 @GwtIncompatible // Class names are obfuscated in GWT testToStringOmitNullValues_canBeCalledManyTimes()412 public void testToStringOmitNullValues_canBeCalledManyTimes() { 413 String toTest = 414 MoreObjects.toStringHelper(new TestClass()) 415 .omitNullValues() 416 .omitNullValues() 417 .add("field1", "Hello") 418 .omitNullValues() 419 .add("field2", "Googley") 420 .omitNullValues() 421 .add("field3", "World") 422 .toString(); 423 assertEquals("TestClass{field1=Hello, field2=Googley, field3=World}", toTest); 424 } 425 426 /** Test class for testing formatting of inner classes. */ 427 private static class TestClass {} 428 } 429