View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      https://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.builder;
18  
19  import static org.apache.commons.lang3.LangAssertions.assertIllegalArgumentException;
20  import static org.apache.commons.lang3.LangAssertions.assertNullPointerException;
21  import static org.junit.jupiter.api.Assertions.assertEquals;
22  import static org.junit.jupiter.api.Assertions.assertNotNull;
23  import static org.junit.jupiter.api.Assertions.assertSame;
24  
25  import java.util.ArrayList;
26  import java.util.HashMap;
27  import java.util.List;
28  
29  import org.apache.commons.lang3.AbstractLangTest;
30  import org.junit.jupiter.api.Test;
31  
32  /**
33   * Tests for {@link org.apache.commons.lang3.builder.ToStringBuilder}.
34   */
35  class ToStringBuilderTest extends AbstractLangTest {
36  
37      /**
38       * Test fixture for ReflectionToStringBuilder.toString() for statics.
39       */
40      @SuppressWarnings("unused")
41      final class InheritedReflectionStaticFieldsFixture extends SimpleReflectionStaticFieldsFixture {
42          static final String staticString2 = "staticString2";
43          static final int staticInt2 = 67890;
44      }
45  
46      /**
47       * Points out failure to print anything from appendToString methods using MULTI_LINE_STYLE. See issue LANG-372.
48       */
49      final class MultiLineTestObject {
50          Integer i = Integer.valueOf(31337);
51  
52          @Override
53          public String toString() {
54              return new ToStringBuilder(this).append("testInt", i).toString();
55          }
56      }
57  
58      static class ObjectCycle {
59          Object obj;
60  
61          @Override
62          public String toString() {
63              return new ToStringBuilder(this).append(obj).toString();
64          }
65      }
66  
67      static class Outer {
68          final class Inner {
69              @Override
70              public String toString() {
71                  return ToStringBuilder.reflectionToString(this);
72              }
73          }
74  
75          Inner inner = new Inner();
76  
77          @Override
78          public String toString() {
79              return ToStringBuilder.reflectionToString(this);
80          }
81      }
82  
83      /**
84       * Tests ReflectionToStringBuilder.toString() for statics.
85       */
86      final class ReflectionStaticFieldsFixture {
87          static final String staticString = "staticString";
88          static final int staticInt = 12345;
89          static final transient String staticTransientString = "staticTransientString";
90          static final transient int staticTransientInt = 54321;
91          String instanceString = "instanceString";
92          int instanceInt = 67890;
93          transient String transientString = "transientString";
94          transient int transientInt = 98765;
95      }
96  
97      /**
98       * A reflection test fixture.
99       */
100     static class ReflectionTestCycleA {
101         ReflectionTestCycleB b;
102 
103         @Override
104         public String toString() {
105             return ToStringBuilder.reflectionToString(this);
106         }
107     }
108 
109     /**
110      * A reflection test fixture.
111      */
112     static class ReflectionTestCycleB {
113         ReflectionTestCycleA a;
114 
115         @Override
116         public String toString() {
117             return ToStringBuilder.reflectionToString(this);
118         }
119     }
120 
121     static class ReflectionTestFixtureA {
122         @SuppressWarnings("unused")
123         private final char a = 'a';
124         @SuppressWarnings("unused")
125         private final transient char transientA = 't';
126     }
127 
128     static class ReflectionTestFixtureB extends ReflectionTestFixtureA {
129         @SuppressWarnings("unused")
130         private final char b = 'b';
131         @SuppressWarnings("unused")
132         private final transient char transientB = 't';
133     }
134 
135     private static final class SelfInstanceTwoVarsReflectionTestFixture {
136         @SuppressWarnings("unused")
137         private final SelfInstanceTwoVarsReflectionTestFixture typeIsSelf;
138         private final String otherType = "The Other Type";
139 
140         SelfInstanceTwoVarsReflectionTestFixture() {
141             this.typeIsSelf = this;
142         }
143 
144         public String getOtherType() {
145             return this.otherType;
146         }
147 
148         @Override
149         public String toString() {
150             return ToStringBuilder.reflectionToString(this);
151         }
152     }
153 
154     private static final class SelfInstanceVarReflectionTestFixture {
155         @SuppressWarnings("unused")
156         private final SelfInstanceVarReflectionTestFixture typeIsSelf;
157 
158         SelfInstanceVarReflectionTestFixture() {
159             this.typeIsSelf = this;
160         }
161 
162         @Override
163         public String toString() {
164             return ToStringBuilder.reflectionToString(this);
165         }
166     }
167 
168     /**
169      * Test fixture for ReflectionToStringBuilder.toString() for statics.
170      */
171     class SimpleReflectionStaticFieldsFixture {
172         static final String staticString = "staticString";
173         static final int staticInt = 12345;
174     }
175 
176     /**
177      * A reflection test fixture.
178      */
179     static class SimpleReflectionTestFixture {
180         Object o;
181 
182         SimpleReflectionTestFixture() {
183         }
184 
185         SimpleReflectionTestFixture(final Object o) {
186             this.o = o;
187         }
188 
189         @Override
190         public String toString() {
191             return ToStringBuilder.reflectionToString(this);
192         }
193     }
194 
195     // Reflection Array tests
196 
197     //
198     // Note on the following line of code repeated in the reflection array tests.
199     //
200     // assertReflectionArray("<null>", array);
201     //
202     // The expected value is not baseStr + "[<null>]" since array == null and is typed as Object.
203     // The null array does not carry array type information.
204     // If we added a primitive array type constructor and pile of associated methods,
205     // then type declaring type information could be carried forward. IMHO, null is null.
206     //
207     // Gary Gregory - 2003-03-12 - ggregory@seagullsw.com
208     //
209 
210     // See LANG-1337 for more.
211     private static final int ARRAYLIST_INITIAL_CAPACITY = 10;
212 
213     private final Integer base = Integer.valueOf(5);
214 
215     private final String baseStr = base.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(base));
216 
217     public void assertReflectionArray(final String expected, final Object actual) {
218         if (actual == null) {
219             // Until ToStringBuilder supports null objects.
220             return;
221         }
222         assertEquals(expected, ToStringBuilder.reflectionToString(actual));
223         assertEquals(expected, ToStringBuilder.reflectionToString(actual, null));
224         assertEquals(expected, ToStringBuilder.reflectionToString(actual, null, true));
225         assertEquals(expected, ToStringBuilder.reflectionToString(actual, null, false));
226     }
227 
228     /**
229      * Tests ReflectionToStringBuilder setUpToClass().
230      */
231     @Test
232     void test_setUpToClass_invalid() {
233         final Integer val = Integer.valueOf(5);
234         final ReflectionToStringBuilder test = new ReflectionToStringBuilder(val);
235         assertIllegalArgumentException(() -> test.setUpToClass(String.class));
236         test.toString();
237     }
238 
239     /**
240      * Tests ReflectionToStringBuilder setUpToClass().
241      */
242     @Test
243     void test_setUpToClass_valid() {
244         final Integer val = Integer.valueOf(5);
245         final ReflectionToStringBuilder test = new ReflectionToStringBuilder(val);
246         test.setUpToClass(Number.class);
247         test.toString();
248     }
249 
250     @Test
251     void testAppendAsObjectToString() {
252         final String objectToAppend1 = "";
253         final Boolean objectToAppend2 = Boolean.TRUE;
254         final Object objectToAppend3 = new Object();
255 
256         assertEquals(baseStr + "[" + toBaseString(objectToAppend1) + "]", new ToStringBuilder(base).appendAsObjectToString(objectToAppend1).toString());
257         assertEquals(baseStr + "[" + toBaseString(objectToAppend2) + "]", new ToStringBuilder(base).appendAsObjectToString(objectToAppend2).toString());
258         assertEquals(baseStr + "[" + toBaseString(objectToAppend3) + "]", new ToStringBuilder(base).appendAsObjectToString(objectToAppend3).toString());
259     }
260 
261     @Test
262     void testAppendAsObjectToStringNullPointerException() {
263         final ToStringBuilder builder = new ToStringBuilder(1);
264         assertNullPointerException(() -> builder.appendAsObjectToString(null));
265         builder.toString();
266     }
267 
268     @Test
269     void testAppendBooleanArrayWithFieldName() {
270         final boolean[] array = { true, false, false };
271         assertEquals(baseStr + "[flags={true,false,false}]", new ToStringBuilder(base).append("flags", array).toString());
272         assertEquals(baseStr + "[flags=<null>]", new ToStringBuilder(base).append("flags", (boolean[]) null).toString());
273         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append(null, (boolean[]) null).toString());
274         assertEquals(baseStr + "[{true,false,false}]", new ToStringBuilder(base).append(null, array).toString());
275     }
276 
277     @Test
278     void testAppendBooleanArrayWithFieldNameAndFullDetail() {
279         final boolean[] array = { true, false, false };
280         assertEquals(baseStr + "[flags={true,false,false}]", new ToStringBuilder(base).append("flags", array, true).toString());
281         assertEquals(baseStr + "[length=<size=3>]", new ToStringBuilder(base).append("length", array, false).toString());
282         assertEquals(baseStr + "[flags=<null>]", new ToStringBuilder(base).append("flags", (boolean[]) null, true).toString());
283         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append(null, (boolean[]) null, false).toString());
284         assertEquals(baseStr + "[<size=3>]", new ToStringBuilder(base).append(null, array, false).toString());
285     }
286 
287     // Reflection Array Array tests
288 
289     @Test
290     void testAppendByteArrayWithFieldName() {
291         final byte[] array = { 1, 2, -3, 4 };
292         assertEquals(baseStr + "[values={1,2,-3,4}]", new ToStringBuilder(base).append("values", array).toString());
293         assertEquals(baseStr + "[values=<null>]", new ToStringBuilder(base).append("values", (boolean[]) null).toString());
294         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append(null, (boolean[]) null).toString());
295         assertEquals(baseStr + "[{1,2,-3,4}]", new ToStringBuilder(base).append(null, array).toString());
296     }
297 
298     @Test
299     void testAppendByteArrayWithFieldNameAndFullDetail() {
300         final byte[] array = { 1, 2, -3, 4 };
301         assertEquals(baseStr + "[values={1,2,-3,4}]", new ToStringBuilder(base).append("values", array, true).toString());
302         assertEquals(baseStr + "[length=<size=4>]", new ToStringBuilder(base).append("length", array, false).toString());
303         assertEquals(baseStr + "[values=<null>]", new ToStringBuilder(base).append("values", (boolean[]) null, true).toString());
304         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append(null, (boolean[]) null, false).toString());
305         assertEquals(baseStr + "[<size=4>]", new ToStringBuilder(base).append(null, array, false).toString());
306     }
307 
308     @Test
309     void testAppendCharArrayWithFieldName() {
310         final char[] array = { 'A', '2', '_', 'D' };
311         assertEquals(baseStr + "[chars={A,2,_,D}]", new ToStringBuilder(base).append("chars", array).toString());
312         assertEquals(baseStr + "[letters={A,2,_,D}]", new ToStringBuilder(base).append("letters", array).toString());
313         assertEquals(baseStr + "[flags=<null>]", new ToStringBuilder(base).append("flags", (boolean[]) null).toString());
314         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append(null, (boolean[]) null).toString());
315         assertEquals(baseStr + "[{A,2,_,D}]", new ToStringBuilder(base).append(null, array).toString());
316     }
317 
318     @Test
319     void testAppendCharArrayWithFieldNameAndFullDetail() {
320         final char[] array = { 'A', '2', '_', 'D' };
321         assertEquals(baseStr + "[chars={A,2,_,D}]", new ToStringBuilder(base).append("chars", array, true).toString());
322         assertEquals(baseStr + "[letters=<size=4>]", new ToStringBuilder(base).append("letters", array, false).toString());
323         assertEquals(baseStr + "[flags=<null>]", new ToStringBuilder(base).append("flags", (boolean[]) null, true).toString());
324         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append(null, (boolean[]) null, false).toString());
325         assertEquals(baseStr + "[<size=4>]", new ToStringBuilder(base).append(null, array, false).toString());
326     }
327 
328     @Test
329     void testAppendDoubleArrayWithFieldName() {
330         final double[] array = { 1.0, 2.9876, -3.00001, 4.3 };
331         assertEquals(baseStr + "[values={1.0,2.9876,-3.00001,4.3}]", new ToStringBuilder(base).append("values", array).toString());
332         assertEquals(baseStr + "[values=<null>]", new ToStringBuilder(base).append("values", (boolean[]) null).toString());
333         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append(null, (boolean[]) null).toString());
334         assertEquals(baseStr + "[{1.0,2.9876,-3.00001,4.3}]", new ToStringBuilder(base).append(null, array).toString());
335     }
336 
337     @Test
338     void testAppendDoubleArrayWithFieldNameAndFullDetail() {
339         final double[] array = { 1.0, 2.9876, -3.00001, 4.3 };
340         assertEquals(baseStr + "[values={1.0,2.9876,-3.00001,4.3}]", new ToStringBuilder(base).append("values", array, true).toString());
341         assertEquals(baseStr + "[length=<size=4>]", new ToStringBuilder(base).append("length", array, false).toString());
342         assertEquals(baseStr + "[values=<null>]", new ToStringBuilder(base).append("values", (boolean[]) null, true).toString());
343         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append(null, (boolean[]) null, false).toString());
344         assertEquals(baseStr + "[<size=4>]", new ToStringBuilder(base).append(null, array, false).toString());
345     }
346 
347     @Test
348     void testAppendFloatArrayWithFieldName() {
349         final float[] array = { 1.0f, 2.9876f, -3.00001f, 4.3f };
350         assertEquals(baseStr + "[values={1.0,2.9876,-3.00001,4.3}]", new ToStringBuilder(base).append("values", array).toString());
351         assertEquals(baseStr + "[values=<null>]", new ToStringBuilder(base).append("values", (boolean[]) null).toString());
352         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append(null, (boolean[]) null).toString());
353         assertEquals(baseStr + "[{1.0,2.9876,-3.00001,4.3}]", new ToStringBuilder(base).append(null, array).toString());
354     }
355 
356     @Test
357     void testAppendFloatArrayWithFieldNameAndFullDetail() {
358         final float[] array = { 1.0f, 2.9876f, -3.00001f, 4.3f };
359         assertEquals(baseStr + "[values={1.0,2.9876,-3.00001,4.3}]", new ToStringBuilder(base).append("values", array, true).toString());
360         assertEquals(baseStr + "[length=<size=4>]", new ToStringBuilder(base).append("length", array, false).toString());
361         assertEquals(baseStr + "[values=<null>]", new ToStringBuilder(base).append("values", (boolean[]) null, true).toString());
362         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append(null, (boolean[]) null, false).toString());
363         assertEquals(baseStr + "[<size=4>]", new ToStringBuilder(base).append(null, array, false).toString());
364     }
365 
366     @Test
367     void testAppendIntArrayWithFieldName() {
368         final int[] array = { 1, 2, -3, 4 };
369         assertEquals(baseStr + "[values={1,2,-3,4}]", new ToStringBuilder(base).append("values", array).toString());
370         assertEquals(baseStr + "[values=<null>]", new ToStringBuilder(base).append("values", (boolean[]) null).toString());
371         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append(null, (boolean[]) null).toString());
372         assertEquals(baseStr + "[{1,2,-3,4}]", new ToStringBuilder(base).append(null, array).toString());
373     }
374 
375     @Test
376     void testAppendIntArrayWithFieldNameAndFullDetail() {
377         final int[] array = { 1, 2, -3, 4 };
378         assertEquals(baseStr + "[values={1,2,-3,4}]", new ToStringBuilder(base).append("values", array, true).toString());
379         assertEquals(baseStr + "[length=<size=4>]", new ToStringBuilder(base).append("length", array, false).toString());
380         assertEquals(baseStr + "[values=<null>]", new ToStringBuilder(base).append("values", (boolean[]) null, true).toString());
381         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append(null, (boolean[]) null, false).toString());
382         assertEquals(baseStr + "[<size=4>]", new ToStringBuilder(base).append(null, array, false).toString());
383     }
384 
385     @Test
386     void testAppendLongArrayWithFieldName() {
387         final long[] array = { 1, 2, -3, 4 };
388         assertEquals(baseStr + "[values={1,2,-3,4}]", new ToStringBuilder(base).append("values", array).toString());
389         assertEquals(baseStr + "[values=<null>]", new ToStringBuilder(base).append("values", (boolean[]) null).toString());
390         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append(null, (boolean[]) null).toString());
391         assertEquals(baseStr + "[{1,2,-3,4}]", new ToStringBuilder(base).append(null, array).toString());
392     }
393 
394     @Test
395     void testAppendLongArrayWithFieldNameAndFullDetail() {
396         final long[] array = { 1, 2, -3, 4 };
397         assertEquals(baseStr + "[values={1,2,-3,4}]", new ToStringBuilder(base).append("values", array, true).toString());
398         assertEquals(baseStr + "[length=<size=4>]", new ToStringBuilder(base).append("length", array, false).toString());
399         assertEquals(baseStr + "[values=<null>]", new ToStringBuilder(base).append("values", (boolean[]) null, true).toString());
400         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append(null, (boolean[]) null, false).toString());
401         assertEquals(baseStr + "[<size=4>]", new ToStringBuilder(base).append(null, array, false).toString());
402     }
403 
404     @Test
405     void testAppendObjectArrayWithFieldName() {
406         final Object[] array = { null, base, new int[] { 3, 6 } };
407         assertEquals(baseStr + "[values={<null>,5,{3,6}}]", new ToStringBuilder(base).append("values", array).toString());
408         assertEquals(baseStr + "[values=<null>]", new ToStringBuilder(base).append("values", (boolean[]) null).toString());
409         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append(null, (boolean[]) null).toString());
410         assertEquals(baseStr + "[{<null>,5,{3,6}}]", new ToStringBuilder(base).append(null, array).toString());
411     }
412 
413     @Test
414     void testAppendObjectArrayWithFieldNameAndFullDetail() {
415         final Object[] array = { null, base, new int[] { 3, 6 } };
416         assertEquals(baseStr + "[values={<null>,5,{3,6}}]", new ToStringBuilder(base).append("values", array, true).toString());
417         assertEquals(baseStr + "[length=<size=3>]", new ToStringBuilder(base).append("length", array, false).toString());
418         assertEquals(baseStr + "[values=<null>]", new ToStringBuilder(base).append("values", (boolean[]) null, true).toString());
419         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append(null, (boolean[]) null, false).toString());
420         assertEquals(baseStr + "[<size=3>]", new ToStringBuilder(base).append(null, array, false).toString());
421     }
422 
423     // Reflection cycle tests
424 
425     @Test
426     void testAppendShortArrayWithFieldName() {
427         final short[] array = { 1, 2, -3, 4 };
428         assertEquals(baseStr + "[values={1,2,-3,4}]", new ToStringBuilder(base).append("values", array).toString());
429         assertEquals(baseStr + "[values=<null>]", new ToStringBuilder(base).append("values", (boolean[]) null).toString());
430         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append(null, (boolean[]) null).toString());
431         assertEquals(baseStr + "[{1,2,-3,4}]", new ToStringBuilder(base).append(null, array).toString());
432     }
433 
434     @Test
435     void testAppendShortArrayWithFieldNameAndFullDetail() {
436         final short[] array = { 1, 2, -3, 4 };
437         assertEquals(baseStr + "[values={1,2,-3,4}]", new ToStringBuilder(base).append("values", array, true).toString());
438         assertEquals(baseStr + "[length=<size=4>]", new ToStringBuilder(base).append("length", array, false).toString());
439         assertEquals(baseStr + "[values=<null>]", new ToStringBuilder(base).append("values", (boolean[]) null, true).toString());
440         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append(null, (boolean[]) null, false).toString());
441         assertEquals(baseStr + "[<size=4>]", new ToStringBuilder(base).append(null, array, false).toString());
442     }
443 
444     @Test
445     void testAppendSuper() {
446         assertEquals(baseStr + "[]", new ToStringBuilder(base).appendSuper("Integer@8888[]").toString());
447         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).appendSuper("Integer@8888[<null>]").toString());
448 
449         assertEquals(baseStr + "[a=hello]", new ToStringBuilder(base).appendSuper("Integer@8888[]").append("a", "hello").toString());
450         assertEquals(baseStr + "[<null>,a=hello]", new ToStringBuilder(base).appendSuper("Integer@8888[<null>]").append("a", "hello").toString());
451         assertEquals(baseStr + "[a=hello]", new ToStringBuilder(base).appendSuper(null).append("a", "hello").toString());
452     }
453 
454     @Test
455     void testAppendToString() {
456         assertEquals(baseStr + "[]", new ToStringBuilder(base).appendToString("Integer@8888[]").toString());
457         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).appendToString("Integer@8888[<null>]").toString());
458 
459         assertEquals(baseStr + "[a=hello]", new ToStringBuilder(base).appendToString("Integer@8888[]").append("a", "hello").toString());
460         assertEquals(baseStr + "[<null>,a=hello]", new ToStringBuilder(base).appendToString("Integer@8888[<null>]").append("a", "hello").toString());
461         assertEquals(baseStr + "[a=hello]", new ToStringBuilder(base).appendToString(null).append("a", "hello").toString());
462     }
463 
464     @Test
465     void testAppendToStringUsingMultiLineStyle() {
466         final MultiLineTestObject obj = new MultiLineTestObject();
467         final ToStringBuilder testBuilder = new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE).appendToString(obj.toString());
468         assertEquals(-1, testBuilder.toString().indexOf("testInt=31337"));
469     }
470 
471     @Test
472     void testBlank() {
473         assertEquals(baseStr + "[]", new ToStringBuilder(base).toString());
474     }
475 
476     @Test
477     void testBoolean() {
478         assertEquals(baseStr + "[true]", new ToStringBuilder(base).append(true).toString());
479         assertEquals(baseStr + "[a=true]", new ToStringBuilder(base).append("a", true).toString());
480         assertEquals(baseStr + "[a=true,b=false]", new ToStringBuilder(base).append("a", true).append("b", false).toString());
481     }
482 
483     @Test
484     void testBooleanArray() {
485         boolean[] array = { true, false, false };
486         assertEquals(baseStr + "[{true,false,false}]", new ToStringBuilder(base).append(array).toString());
487         assertEquals(baseStr + "[{true,false,false}]", new ToStringBuilder(base).append((Object) array).toString());
488         array = null;
489         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append(array).toString());
490         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append((Object) array).toString());
491     }
492 
493     @Test
494     void testBooleanArrayArray() {
495         boolean[][] array = { { true, false }, null, { false } };
496         assertEquals(baseStr + "[{{true,false},<null>,{false}}]", new ToStringBuilder(base).append(array).toString());
497         assertEquals(baseStr + "[{{true,false},<null>,{false}}]", new ToStringBuilder(base).append((Object) array).toString());
498         array = null;
499         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append(array).toString());
500         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append((Object) array).toString());
501     }
502 
503     @Test
504     void testByte() {
505         assertEquals(baseStr + "[3]", new ToStringBuilder(base).append((byte) 3).toString());
506         assertEquals(baseStr + "[a=3]", new ToStringBuilder(base).append("a", (byte) 3).toString());
507         assertEquals(baseStr + "[a=3,b=4]", new ToStringBuilder(base).append("a", (byte) 3).append("b", (byte) 4).toString());
508     }
509 
510     @Test
511     void testByteArray() {
512         byte[] array = { 1, 2, -3, 4 };
513         assertEquals(baseStr + "[{1,2,-3,4}]", new ToStringBuilder(base).append(array).toString());
514         assertEquals(baseStr + "[{1,2,-3,4}]", new ToStringBuilder(base).append((Object) array).toString());
515         array = null;
516         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append(array).toString());
517         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append((Object) array).toString());
518     }
519 
520     @Test
521     void testByteArrayArray() {
522         byte[][] array = { { 1, 2 }, null, { 5 } };
523         assertEquals(baseStr + "[{{1,2},<null>,{5}}]", new ToStringBuilder(base).append(array).toString());
524         assertEquals(baseStr + "[{{1,2},<null>,{5}}]", new ToStringBuilder(base).append((Object) array).toString());
525         array = null;
526         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append(array).toString());
527         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append((Object) array).toString());
528     }
529 
530     @Test
531     void testChar() {
532         assertEquals(baseStr + "[A]", new ToStringBuilder(base).append((char) 65).toString());
533         assertEquals(baseStr + "[a=A]", new ToStringBuilder(base).append("a", (char) 65).toString());
534         assertEquals(baseStr + "[a=A,b=B]", new ToStringBuilder(base).append("a", (char) 65).append("b", (char) 66).toString());
535     }
536 
537     @Test
538     void testCharArray() {
539         char[] array = { 'A', '2', '_', 'D' };
540         assertEquals(baseStr + "[{A,2,_,D}]", new ToStringBuilder(base).append(array).toString());
541         assertEquals(baseStr + "[{A,2,_,D}]", new ToStringBuilder(base).append((Object) array).toString());
542         array = null;
543         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append(array).toString());
544         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append((Object) array).toString());
545     }
546 
547     @Test
548     void testCharArrayArray() {
549         char[][] array = { { 'A', 'B' }, null, { 'p' } };
550         assertEquals(baseStr + "[{{A,B},<null>,{p}}]", new ToStringBuilder(base).append(array).toString());
551         assertEquals(baseStr + "[{{A,B},<null>,{p}}]", new ToStringBuilder(base).append((Object) array).toString());
552         array = null;
553         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append(array).toString());
554         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append((Object) array).toString());
555     }
556 
557     @Test
558     void testConstructorEx1() {
559         assertEquals("<null>", new ToStringBuilder(null).toString());
560     }
561 
562     @Test
563     void testConstructorEx2() {
564         assertEquals("<null>", new ToStringBuilder(null, null).toString());
565         new ToStringBuilder(this.base, null).toString();
566     }
567 
568     @Test
569     void testConstructorEx3() {
570         assertEquals("<null>", new ToStringBuilder(null, null, null).toString());
571         new ToStringBuilder(this.base, null, null).toString();
572         new ToStringBuilder(this.base, ToStringStyle.DEFAULT_STYLE, null).toString();
573     }
574 
575     @Test
576     void testConstructToStringBuilder() {
577         final ToStringBuilder stringBuilder1 = new ToStringBuilder(base, null, null);
578         final ToStringBuilder stringBuilder2 = new ToStringBuilder(base, ToStringStyle.DEFAULT_STYLE, new StringBuffer(1024));
579         assertEquals(ToStringStyle.DEFAULT_STYLE, stringBuilder1.getStyle());
580         assertNotNull(stringBuilder1.getStringBuffer());
581         assertNotNull(stringBuilder1.toString());
582         assertEquals(ToStringStyle.DEFAULT_STYLE, stringBuilder2.getStyle());
583         assertNotNull(stringBuilder2.getStringBuffer());
584         assertNotNull(stringBuilder2.toString());
585     }
586 
587     @Test
588     void testDouble() {
589         assertEquals(baseStr + "[3.2]", new ToStringBuilder(base).append(3.2).toString());
590         assertEquals(baseStr + "[a=3.2]", new ToStringBuilder(base).append("a", 3.2).toString());
591         assertEquals(baseStr + "[a=3.2,b=4.3]", new ToStringBuilder(base).append("a", 3.2).append("b", 4.3).toString());
592     }
593 
594     @Test
595     void testDoubleArray() {
596         double[] array = { 1.0, 2.9876, -3.00001, 4.3 };
597         assertEquals(baseStr + "[{1.0,2.9876,-3.00001,4.3}]", new ToStringBuilder(base).append(array).toString());
598         assertEquals(baseStr + "[{1.0,2.9876,-3.00001,4.3}]", new ToStringBuilder(base).append((Object) array).toString());
599         array = null;
600         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append(array).toString());
601         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append((Object) array).toString());
602     }
603 
604     @Test
605     void testDoubleArrayArray() {
606         double[][] array = { { 1.0, 2.29686 }, null, { Double.NaN } };
607         assertEquals(baseStr + "[{{1.0,2.29686},<null>,{NaN}}]", new ToStringBuilder(base).append(array).toString());
608         assertEquals(baseStr + "[{{1.0,2.29686},<null>,{NaN}}]", new ToStringBuilder(base).append((Object) array).toString());
609         array = null;
610         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append(array).toString());
611         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append((Object) array).toString());
612     }
613 
614     @Test
615     void testFloat() {
616         assertEquals(baseStr + "[3.2]", new ToStringBuilder(base).append((float) 3.2).toString());
617         assertEquals(baseStr + "[a=3.2]", new ToStringBuilder(base).append("a", (float) 3.2).toString());
618         assertEquals(baseStr + "[a=3.2,b=4.3]", new ToStringBuilder(base).append("a", (float) 3.2).append("b", (float) 4.3).toString());
619     }
620 
621     @Test
622     void testFloatArray() {
623         float[] array = { 1.0f, 2.9876f, -3.00001f, 4.3f };
624         assertEquals(baseStr + "[{1.0,2.9876,-3.00001,4.3}]", new ToStringBuilder(base).append(array).toString());
625         assertEquals(baseStr + "[{1.0,2.9876,-3.00001,4.3}]", new ToStringBuilder(base).append((Object) array).toString());
626         array = null;
627         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append(array).toString());
628         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append((Object) array).toString());
629     }
630 
631     @Test
632     void testFloatArrayArray() {
633         float[][] array = { { 1.0f, 2.29686f }, null, { Float.NaN } };
634         assertEquals(baseStr + "[{{1.0,2.29686},<null>,{NaN}}]", new ToStringBuilder(base).append(array).toString());
635         assertEquals(baseStr + "[{{1.0,2.29686},<null>,{NaN}}]", new ToStringBuilder(base).append((Object) array).toString());
636         array = null;
637         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append(array).toString());
638         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append((Object) array).toString());
639     }
640 
641     @Test
642     void testGetSetDefault() {
643         try {
644             ToStringBuilder.setDefaultStyle(ToStringStyle.NO_FIELD_NAMES_STYLE);
645             assertSame(ToStringStyle.NO_FIELD_NAMES_STYLE, ToStringBuilder.getDefaultStyle());
646         } finally {
647             // reset for other tests
648             ToStringBuilder.setDefaultStyle(ToStringStyle.DEFAULT_STYLE);
649         }
650     }
651 
652     /**
653      * Tests ReflectionToStringBuilder.toString() for statics.
654      */
655     @Test
656     void testInheritedReflectionStatics() {
657         final InheritedReflectionStaticFieldsFixture instance1 = new InheritedReflectionStaticFieldsFixture();
658         assertEquals(toBaseString(instance1) + "[staticInt2=67890,staticString2=staticString2]",
659                 ReflectionToStringBuilder.toString(instance1, null, false, true, InheritedReflectionStaticFieldsFixture.class));
660         assertEquals(toBaseString(instance1) + "[staticInt2=67890,staticString2=staticString2,staticInt=12345,staticString=staticString]",
661                 ReflectionToStringBuilder.toString(instance1, null, false, true, SimpleReflectionStaticFieldsFixture.class));
662         assertEquals(toBaseString(instance1) + "[staticInt2=67890,staticString2=staticString2,staticInt=12345,staticString=staticString]",
663                 this.toStringWithStatics(instance1, null, SimpleReflectionStaticFieldsFixture.class));
664         assertEquals(toBaseString(instance1) + "[staticInt2=67890,staticString2=staticString2,staticInt=12345,staticString=staticString]",
665                 this.toStringWithStatics(instance1, null, SimpleReflectionStaticFieldsFixture.class));
666     }
667 
668     @Test
669     void testInnerClassReflection() {
670         final Outer outer = new Outer();
671         assertEquals(toBaseString(outer) + "[inner=" + toBaseString(outer.inner) + "[]]", outer.toString());
672     }
673 
674     @Test
675     void testInt() {
676         assertEquals(baseStr + "[3]", new ToStringBuilder(base).append(3).toString());
677         assertEquals(baseStr + "[a=3]", new ToStringBuilder(base).append("a", 3).toString());
678         assertEquals(baseStr + "[a=3,b=4]", new ToStringBuilder(base).append("a", 3).append("b", 4).toString());
679     }
680 
681     @Test
682     void testIntArray() {
683         int[] array = { 1, 2, -3, 4 };
684         assertEquals(baseStr + "[{1,2,-3,4}]", new ToStringBuilder(base).append(array).toString());
685         assertEquals(baseStr + "[{1,2,-3,4}]", new ToStringBuilder(base).append((Object) array).toString());
686         array = null;
687         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append(array).toString());
688         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append((Object) array).toString());
689     }
690 
691     @Test
692     void testIntArrayArray() {
693         int[][] array = { { 1, 2 }, null, { 5 } };
694         assertEquals(baseStr + "[{{1,2},<null>,{5}}]", new ToStringBuilder(base).append(array).toString());
695         assertEquals(baseStr + "[{{1,2},<null>,{5}}]", new ToStringBuilder(base).append((Object) array).toString());
696         array = null;
697         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append(array).toString());
698         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append((Object) array).toString());
699     }
700 
701     @Test
702     void testLong() {
703         assertEquals(baseStr + "[3]", new ToStringBuilder(base).append(3L).toString());
704         assertEquals(baseStr + "[a=3]", new ToStringBuilder(base).append("a", 3L).toString());
705         assertEquals(baseStr + "[a=3,b=4]", new ToStringBuilder(base).append("a", 3L).append("b", 4L).toString());
706     }
707 
708     @Test
709     void testLongArray() {
710         long[] array = { 1, 2, -3, 4 };
711         assertEquals(baseStr + "[{1,2,-3,4}]", new ToStringBuilder(base).append(array).toString());
712         assertEquals(baseStr + "[{1,2,-3,4}]", new ToStringBuilder(base).append((Object) array).toString());
713         array = null;
714         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append(array).toString());
715         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append((Object) array).toString());
716     }
717 
718     @Test
719     void testLongArrayArray() {
720         long[][] array = { { 1, 2 }, null, { 5 } };
721         assertEquals(baseStr + "[{{1,2},<null>,{5}}]", new ToStringBuilder(base).append(array).toString());
722         assertEquals(baseStr + "[{{1,2},<null>,{5}}]", new ToStringBuilder(base).append((Object) array).toString());
723         array = null;
724         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append(array).toString());
725         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append((Object) array).toString());
726     }
727 
728     @Test
729     void testObject() {
730         final Integer i3 = Integer.valueOf(3);
731         final Integer i4 = Integer.valueOf(4);
732         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append((Object) null).toString());
733         assertEquals(baseStr + "[3]", new ToStringBuilder(base).append(i3).toString());
734         assertEquals(baseStr + "[a=<null>]", new ToStringBuilder(base).append("a", (Object) null).toString());
735         assertEquals(baseStr + "[a=3]", new ToStringBuilder(base).append("a", i3).toString());
736         assertEquals(baseStr + "[a=3,b=4]", new ToStringBuilder(base).append("a", i3).append("b", i4).toString());
737         assertEquals(baseStr + "[a=<Integer>]", new ToStringBuilder(base).append("a", i3, false).toString());
738         assertEquals(baseStr + "[a=<size=0>]", new ToStringBuilder(base).append("a", new ArrayList<>(), false).toString());
739         assertEquals(baseStr + "[a=[]]", new ToStringBuilder(base).append("a", new ArrayList<>(), true).toString());
740         assertEquals(baseStr + "[a=<size=0>]", new ToStringBuilder(base).append("a", new HashMap<>(), false).toString());
741         assertEquals(baseStr + "[a={}]", new ToStringBuilder(base).append("a", new HashMap<>(), true).toString());
742         assertEquals(baseStr + "[a=<size=0>]", new ToStringBuilder(base).append("a", (Object) new String[0], false).toString());
743         assertEquals(baseStr + "[a={}]", new ToStringBuilder(base).append("a", (Object) new String[0], true).toString());
744     }
745 
746     @Test
747     void testObjectArray() {
748         Object[] array = { null, base, new int[] { 3, 6 } };
749         assertEquals(baseStr + "[{<null>,5,{3,6}}]", new ToStringBuilder(base).append(array).toString());
750         assertEquals(baseStr + "[{<null>,5,{3,6}}]", new ToStringBuilder(base).append((Object) array).toString());
751         array = null;
752         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append(array).toString());
753         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append((Object) array).toString());
754     }
755 
756     @Test
757     void testObjectBuild() {
758         final Integer i3 = Integer.valueOf(3);
759         final Integer i4 = Integer.valueOf(4);
760         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append((Object) null).build());
761         assertEquals(baseStr + "[3]", new ToStringBuilder(base).append(i3).build());
762         assertEquals(baseStr + "[a=<null>]", new ToStringBuilder(base).append("a", (Object) null).build());
763         assertEquals(baseStr + "[a=3]", new ToStringBuilder(base).append("a", i3).build());
764         assertEquals(baseStr + "[a=3,b=4]", new ToStringBuilder(base).append("a", i3).append("b", i4).build());
765         assertEquals(baseStr + "[a=<Integer>]", new ToStringBuilder(base).append("a", i3, false).build());
766         assertEquals(baseStr + "[a=<size=0>]", new ToStringBuilder(base).append("a", new ArrayList<>(), false).build());
767         assertEquals(baseStr + "[a=[]]", new ToStringBuilder(base).append("a", new ArrayList<>(), true).build());
768         assertEquals(baseStr + "[a=<size=0>]", new ToStringBuilder(base).append("a", new HashMap<>(), false).build());
769         assertEquals(baseStr + "[a={}]", new ToStringBuilder(base).append("a", new HashMap<>(), true).build());
770         assertEquals(baseStr + "[a=<size=0>]", new ToStringBuilder(base).append("a", (Object) new String[0], false).build());
771         assertEquals(baseStr + "[a={}]", new ToStringBuilder(base).append("a", (Object) new String[0], true).build());
772     }
773 
774     @Test
775     void testObjectCycle() {
776         final ObjectCycle a = new ObjectCycle();
777         final ObjectCycle b = new ObjectCycle();
778         a.obj = b;
779         b.obj = a;
780 
781         final String expected = toBaseString(a) + "[" + toBaseString(b) + "[" + toBaseString(a) + "]]";
782         assertEquals(expected, a.toString());
783     }
784 
785     /**
786      * Test a nasty combination of arrays and Objects pointing to each other. objects[0] -&gt; SimpleReflectionTestFixture[ o -&gt; objects ]
787      */
788     @Test
789     void testReflectionArrayAndObjectCycle() {
790         final Object[] objects = new Object[1];
791         final SimpleReflectionTestFixture simple = new SimpleReflectionTestFixture(objects);
792         objects[0] = simple;
793         assertEquals(toBaseString(objects) + "[{" + toBaseString(simple) + "[o=" + toBaseString(objects) + "]}]",
794                 ToStringBuilder.reflectionToString(objects));
795         assertEquals(toBaseString(simple) + "[o={" + toBaseString(simple) + "}]", ToStringBuilder.reflectionToString(simple));
796     }
797 
798     @Test
799     void testReflectionArrayArrayCycle() {
800         final Object[][] objects = new Object[2][2];
801         objects[0][0] = objects;
802         objects[0][1] = objects;
803         objects[1][0] = objects;
804         objects[1][1] = objects;
805         final String basicToString = toBaseString(objects);
806         assertEquals(basicToString + "[{{" + basicToString + "," + basicToString + "},{" + basicToString + "," + basicToString + "}}]",
807                 ToStringBuilder.reflectionToString(objects));
808     }
809 
810     /**
811      * Test an array element pointing to its container.
812      */
813     @Test
814     void testReflectionArrayCycle() {
815         final Object[] objects = new Object[1];
816         objects[0] = objects;
817         assertEquals(toBaseString(objects) + "[{" + toBaseString(objects) + "}]", ToStringBuilder.reflectionToString(objects));
818     }
819 
820     /**
821      * Test an array element pointing to its container.
822      */
823     @Test
824     void testReflectionArrayCycleLevel2() {
825         final Object[] objects = new Object[1];
826         final Object[] objectsLevel2 = new Object[1];
827         objects[0] = objectsLevel2;
828         objectsLevel2[0] = objects;
829         assertEquals(toBaseString(objects) + "[{{" + toBaseString(objects) + "}}]", ToStringBuilder.reflectionToString(objects));
830         assertEquals(toBaseString(objectsLevel2) + "[{{" + toBaseString(objectsLevel2) + "}}]", ToStringBuilder.reflectionToString(objectsLevel2));
831     }
832 
833     /**
834      * Test wrapper for char boolean.
835      */
836     @Test
837     void testReflectionBoolean() {
838         Boolean b;
839         b = Boolean.TRUE;
840         assertEquals(toBaseString(b) + "[value=true]", ToStringBuilder.reflectionToString(b));
841         b = Boolean.FALSE;
842         assertEquals(toBaseString(b) + "[value=false]", ToStringBuilder.reflectionToString(b));
843     }
844 
845     @Test
846     void testReflectionBooleanArray() {
847         boolean[] array = { true, false, false };
848         final String baseString = toBaseString(array);
849         assertEquals(baseString + "[{true,false,false}]", ToStringBuilder.reflectionToString(array));
850         array = null;
851         assertReflectionArray("<null>", array);
852     }
853 
854     @Test
855     void testReflectionBooleanArrayArray() {
856         boolean[][] array = { { true, false }, null, { false } };
857         final String baseString = toBaseString(array);
858         assertEquals(baseString + "[{{true,false},<null>,{false}}]", ToStringBuilder.reflectionToString(array));
859         assertEquals(baseString + "[{{true,false},<null>,{false}}]", ToStringBuilder.reflectionToString(array));
860         array = null;
861         assertReflectionArray("<null>", array);
862     }
863 
864     @Test
865     void testReflectionByteArray() {
866         byte[] array = { 1, 2, -3, 4 };
867         final String baseString = toBaseString(array);
868         assertEquals(baseString + "[{1,2,-3,4}]", ToStringBuilder.reflectionToString(array));
869         array = null;
870         assertReflectionArray("<null>", array);
871     }
872 
873     @Test
874     void testReflectionByteArrayArray() {
875         byte[][] array = { { 1, 2 }, null, { 5 } };
876         final String baseString = toBaseString(array);
877         assertEquals(baseString + "[{{1,2},<null>,{5}}]", ToStringBuilder.reflectionToString(array));
878         array = null;
879         assertReflectionArray("<null>", array);
880     }
881 
882     /**
883      * Test wrapper for char primitive.
884      */
885     @Test
886     void testReflectionCharacter() {
887         final Character c = 'A';
888         assertEquals(toBaseString(c) + "[value=A]", ToStringBuilder.reflectionToString(c));
889     }
890 
891     @Test
892     void testReflectionCharArray() {
893         char[] array = { 'A', '2', '_', 'D' };
894         final String baseString = toBaseString(array);
895         assertEquals(baseString + "[{A,2,_,D}]", ToStringBuilder.reflectionToString(array));
896         array = null;
897         assertReflectionArray("<null>", array);
898     }
899 
900     @Test
901     void testReflectionCharArrayArray() {
902         char[][] array = { { 'A', 'B' }, null, { 'p' } };
903         final String baseString = toBaseString(array);
904         assertEquals(baseString + "[{{A,B},<null>,{p}}]", ToStringBuilder.reflectionToString(array));
905         array = null;
906         assertReflectionArray("<null>", array);
907     }
908 
909     @Test
910     void testReflectionDoubleArray() {
911         double[] array = { 1.0, 2.9876, -3.00001, 4.3 };
912         final String baseString = toBaseString(array);
913         assertEquals(baseString + "[{1.0,2.9876,-3.00001,4.3}]", ToStringBuilder.reflectionToString(array));
914         array = null;
915         assertReflectionArray("<null>", array);
916     }
917 
918     @Test
919     void testReflectionDoubleArrayArray() {
920         double[][] array = { { 1.0, 2.29686 }, null, { Double.NaN } };
921         final String baseString = toBaseString(array);
922         assertEquals(baseString + "[{{1.0,2.29686},<null>,{NaN}}]", ToStringBuilder.reflectionToString(array));
923         array = null;
924         assertReflectionArray("<null>", array);
925     }
926 
927     @Test
928     void testReflectionFloatArray() {
929         float[] array = { 1.0f, 2.9876f, -3.00001f, 4.3f };
930         final String baseString = toBaseString(array);
931         assertEquals(baseString + "[{1.0,2.9876,-3.00001,4.3}]", ToStringBuilder.reflectionToString(array));
932         array = null;
933         assertReflectionArray("<null>", array);
934     }
935 
936     @Test
937     void testReflectionFloatArrayArray() {
938         float[][] array = { { 1.0f, 2.29686f }, null, { Float.NaN } };
939         final String baseString = toBaseString(array);
940         assertEquals(baseString + "[{{1.0,2.29686},<null>,{NaN}}]", ToStringBuilder.reflectionToString(array));
941         array = null;
942         assertReflectionArray("<null>", array);
943     }
944 
945     @Test
946     void testReflectionHierarchy() {
947         final ReflectionTestFixtureA baseA = new ReflectionTestFixtureA();
948         String baseString = toBaseString(baseA);
949         assertEquals(baseString + "[a=a]", ToStringBuilder.reflectionToString(baseA));
950         assertEquals(baseString + "[a=a]", ToStringBuilder.reflectionToString(baseA, null));
951         assertEquals(baseString + "[a=a]", ToStringBuilder.reflectionToString(baseA, null, false));
952         assertEquals(baseString + "[a=a,transientA=t]", ToStringBuilder.reflectionToString(baseA, null, true));
953         assertEquals(baseString + "[a=a]", ToStringBuilder.reflectionToString(baseA, null, false, null));
954         assertEquals(baseString + "[a=a]", ToStringBuilder.reflectionToString(baseA, null, false, Object.class));
955         assertEquals(baseString + "[a=a]", ToStringBuilder.reflectionToString(baseA, null, false, ReflectionTestFixtureA.class));
956 
957         final ReflectionTestFixtureB baseB = new ReflectionTestFixtureB();
958         baseString = toBaseString(baseB);
959         assertEquals(baseString + "[b=b,a=a]", ToStringBuilder.reflectionToString(baseB));
960         assertEquals(baseString + "[b=b,a=a]", ToStringBuilder.reflectionToString(baseB));
961         assertEquals(baseString + "[b=b,a=a]", ToStringBuilder.reflectionToString(baseB, null));
962         assertEquals(baseString + "[b=b,a=a]", ToStringBuilder.reflectionToString(baseB, null, false));
963         assertEquals(baseString + "[b=b,transientB=t,a=a,transientA=t]", ToStringBuilder.reflectionToString(baseB, null, true));
964         assertEquals(baseString + "[b=b,a=a]", ToStringBuilder.reflectionToString(baseB, null, false, null));
965         assertEquals(baseString + "[b=b,a=a]", ToStringBuilder.reflectionToString(baseB, null, false, Object.class));
966         assertEquals(baseString + "[b=b,a=a]", ToStringBuilder.reflectionToString(baseB, null, false, ReflectionTestFixtureA.class));
967         assertEquals(baseString + "[b=b]", ToStringBuilder.reflectionToString(baseB, null, false, ReflectionTestFixtureB.class));
968     }
969 
970     // Reflection hierarchy tests
971     @Test
972     void testReflectionHierarchyArrayList() {
973         // LANG-1337 without this, the generated string can differ depending on the JVM version/vendor
974         final List<Object> list = new ArrayList<>(ARRAYLIST_INITIAL_CAPACITY);
975         final String baseString = toBaseString(list);
976         final String expectedWithTransients = baseString
977                 + "[elementData={<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>},size=0,modCount=0]";
978         final String toStringWithTransients = ToStringBuilder.reflectionToString(list, null, true);
979         if (!expectedWithTransients.equals(toStringWithTransients)) {
980             assertEquals(expectedWithTransients, toStringWithTransients);
981         }
982         final String expectedWithoutTransients = baseString + "[size=0]";
983         final String toStringWithoutTransients = ToStringBuilder.reflectionToString(list, null, false);
984         if (!expectedWithoutTransients.equals(toStringWithoutTransients)) {
985             assertEquals(expectedWithoutTransients, toStringWithoutTransients);
986         }
987     }
988 
989     @Test
990     void testReflectionIntArray() {
991         int[] array = { 1, 2, -3, 4 };
992         final String baseString = toBaseString(array);
993         assertEquals(baseString + "[{1,2,-3,4}]", ToStringBuilder.reflectionToString(array));
994         array = null;
995         assertReflectionArray("<null>", array);
996     }
997 
998     @Test
999     void testReflectionIntArrayArray() {
1000         int[][] array = { { 1, 2 }, null, { 5 } };
1001         final String baseString = toBaseString(array);
1002         assertEquals(baseString + "[{{1,2},<null>,{5}}]", ToStringBuilder.reflectionToString(array));
1003         array = null;
1004         assertReflectionArray("<null>", array);
1005     }
1006 
1007     /**
1008      * Test wrapper for int primitive.
1009      */
1010     @Test
1011     void testReflectionInteger() {
1012         assertEquals(baseStr + "[value=5]", ToStringBuilder.reflectionToString(base));
1013     }
1014 
1015     @Test
1016     void testReflectionLongArray() {
1017         long[] array = { 1, 2, -3, 4 };
1018         final String baseString = toBaseString(array);
1019         assertEquals(baseString + "[{1,2,-3,4}]", ToStringBuilder.reflectionToString(array));
1020         array = null;
1021         assertReflectionArray("<null>", array);
1022     }
1023 
1024     @Test
1025     void testReflectionLongArrayArray() {
1026         long[][] array = { { 1, 2 }, null, { 5 } };
1027         final String baseString = toBaseString(array);
1028         assertEquals(baseString + "[{{1,2},<null>,{5}}]", ToStringBuilder.reflectionToString(array));
1029         array = null;
1030         assertReflectionArray("<null>", array);
1031     }
1032 
1033     @Test
1034     void testReflectionNull() {
1035         assertEquals("<null>", ReflectionToStringBuilder.toString(null));
1036     }
1037 
1038     @Test
1039     void testReflectionObjectArray() {
1040         Object[] array = { null, base, new int[] { 3, 6 } };
1041         final String baseString = toBaseString(array);
1042         assertEquals(baseString + "[{<null>,5,{3,6}}]", ToStringBuilder.reflectionToString(array));
1043         array = null;
1044         assertReflectionArray("<null>", array);
1045     }
1046 
1047     /**
1048      * Test Objects pointing to each other.
1049      */
1050     @Test
1051     void testReflectionObjectCycle() {
1052         final ReflectionTestCycleA a = new ReflectionTestCycleA();
1053         final ReflectionTestCycleB b = new ReflectionTestCycleB();
1054         a.b = b;
1055         b.a = a;
1056         assertEquals(toBaseString(a) + "[b=" + toBaseString(b) + "[a=" + toBaseString(a) + "]]", a.toString());
1057     }
1058 
1059     @Test
1060     void testReflectionShort2DArray() {
1061         short[][] array = { { 1, 2 }, null, { 5 } };
1062         final String baseString = toBaseString(array);
1063         assertEquals(baseString + "[{{1,2},<null>,{5}}]", ToStringBuilder.reflectionToString(array));
1064         array = null;
1065         assertReflectionArray("<null>", array);
1066     }
1067 
1068     @Test
1069     void testReflectionShortArray() {
1070         short[] array = { 1, 2, -3, 4 };
1071         final String baseString = toBaseString(array);
1072         assertEquals(baseString + "[{1,2,-3,4}]", ToStringBuilder.reflectionToString(array));
1073         array = null;
1074         assertReflectionArray("<null>", array);
1075     }
1076 
1077     /**
1078      * Tests ReflectionToStringBuilder.toString() for statics.
1079      */
1080     @Test
1081     void testReflectionStatics() {
1082         final ReflectionStaticFieldsFixture instance1 = new ReflectionStaticFieldsFixture();
1083         assertEquals(toBaseString(instance1) + "[instanceInt=67890,instanceString=instanceString,staticInt=12345,staticString=staticString]",
1084                 ReflectionToStringBuilder.toString(instance1, null, false, true, ReflectionStaticFieldsFixture.class));
1085         assertEquals(toBaseString(instance1)
1086                 + "[instanceInt=67890,instanceString=instanceString,staticInt=12345,staticString=staticString,staticTransientInt=54321,staticTransientString=staticTransientString,transientInt=98765,transientString=transientString]",
1087                 ReflectionToStringBuilder.toString(instance1, null, true, true, ReflectionStaticFieldsFixture.class));
1088         assertEquals(toBaseString(instance1) + "[instanceInt=67890,instanceString=instanceString,staticInt=12345,staticString=staticString]",
1089                 this.toStringWithStatics(instance1, null, ReflectionStaticFieldsFixture.class));
1090         assertEquals(toBaseString(instance1) + "[instanceInt=67890,instanceString=instanceString,staticInt=12345,staticString=staticString]",
1091                 this.toStringWithStatics(instance1, null, ReflectionStaticFieldsFixture.class));
1092     }
1093 
1094     /**
1095      * Test a class that defines an ivar pointing to itself. This test was created to show that handling cyclical object resulted in a missing endFieldSeparator
1096      * call.
1097      */
1098     @Test
1099     void testSelfInstanceTwoVarsReflectionObjectCycle() {
1100         final SelfInstanceTwoVarsReflectionTestFixture test = new SelfInstanceTwoVarsReflectionTestFixture();
1101         assertEquals(toBaseString(test) + "[otherType=" + test.getOtherType().toString() + ",typeIsSelf=" + toBaseString(test) + "]",
1102                 test.toString());
1103     }
1104 
1105     /**
1106      * Test a class that defines an ivar pointing to itself.
1107      */
1108     @Test
1109     void testSelfInstanceVarReflectionObjectCycle() {
1110         final SelfInstanceVarReflectionTestFixture test = new SelfInstanceVarReflectionTestFixture();
1111         assertEquals(toBaseString(test) + "[typeIsSelf=" + toBaseString(test) + "]", test.toString());
1112     }
1113 
1114     @Test
1115     void testSetDefaultEx() {
1116         assertNullPointerException(() -> ToStringBuilder.setDefaultStyle(null));
1117     }
1118 
1119     @Test
1120     void testShort() {
1121         assertEquals(baseStr + "[3]", new ToStringBuilder(base).append((short) 3).toString());
1122         assertEquals(baseStr + "[a=3]", new ToStringBuilder(base).append("a", (short) 3).toString());
1123         assertEquals(baseStr + "[a=3,b=4]", new ToStringBuilder(base).append("a", (short) 3).append("b", (short) 4).toString());
1124     }
1125 
1126     @Test
1127     void testShortArray() {
1128         short[] array = { 1, 2, -3, 4 };
1129         assertEquals(baseStr + "[{1,2,-3,4}]", new ToStringBuilder(base).append(array).toString());
1130         assertEquals(baseStr + "[{1,2,-3,4}]", new ToStringBuilder(base).append((Object) array).toString());
1131         array = null;
1132         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append(array).toString());
1133         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append((Object) array).toString());
1134     }
1135 
1136     @Test
1137     void testShortArrayArray() {
1138         short[][] array = { { 1, 2 }, null, { 5 } };
1139         assertEquals(baseStr + "[{{1,2},<null>,{5}}]", new ToStringBuilder(base).append(array).toString());
1140         assertEquals(baseStr + "[{{1,2},<null>,{5}}]", new ToStringBuilder(base).append((Object) array).toString());
1141         array = null;
1142         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append(array).toString());
1143         assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append((Object) array).toString());
1144     }
1145 
1146     /**
1147      * Test an Object pointing to itself, the simplest test.
1148      */
1149     @Test
1150     void testSimpleReflectionObjectCycle() {
1151         final SimpleReflectionTestFixture simple = new SimpleReflectionTestFixture();
1152         simple.o = simple;
1153         assertEquals(toBaseString(simple) + "[o=" + toBaseString(simple) + "]", simple.toString());
1154     }
1155 
1156     @Test
1157     void testSimpleReflectionStatics() {
1158         final SimpleReflectionStaticFieldsFixture instance1 = new SimpleReflectionStaticFieldsFixture();
1159         assertEquals(toBaseString(instance1) + "[staticInt=12345,staticString=staticString]",
1160                 ReflectionToStringBuilder.toString(instance1, null, false, true, SimpleReflectionStaticFieldsFixture.class));
1161         assertEquals(toBaseString(instance1) + "[staticInt=12345,staticString=staticString]",
1162                 ReflectionToStringBuilder.toString(instance1, null, true, true, SimpleReflectionStaticFieldsFixture.class));
1163         assertEquals(toBaseString(instance1) + "[staticInt=12345,staticString=staticString]",
1164                 this.toStringWithStatics(instance1, null, SimpleReflectionStaticFieldsFixture.class));
1165         assertEquals(toBaseString(instance1) + "[staticInt=12345,staticString=staticString]",
1166                 this.toStringWithStatics(instance1, null, SimpleReflectionStaticFieldsFixture.class));
1167     }
1168 
1169     /**
1170      * Create the same toString() as Object.toString().
1171      *
1172      * @param o the object to create the string for.
1173      * @return a String in the Object.toString format.
1174      */
1175     private String toBaseString(final Object o) {
1176         return o.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(o));
1177     }
1178 
1179     /**
1180      * This method uses reflection to build a suitable {@code toString} value which includes static fields.
1181      * <p>
1182      * It uses {@code AccessibleObject.setAccessible} to gain access to private fields. This means that it will throw a security exception if run under a
1183      * security manager, if the permissions are not set up correctly. It is also not as efficient as testing explicitly.
1184      * </p>
1185      * <p>
1186      * Transient fields are not output.
1187      * </p>
1188      * <p>
1189      * Superclass fields will be appended up to and including the specified superclass. A null superclass is treated as {@link Object}.
1190      * </p>
1191      * <p>
1192      * If the style is {@code null}, the default {@code ToStringStyle} is used.
1193      * </p>
1194      *
1195      * @param <T>              the type of the output object
1196      * @param object           the Object to be output
1197      * @param style            the style of the {@code toString} to create, may be {@code null}
1198      * @param reflectUpToClass the superclass to reflect up to (inclusive), may be {@code null}
1199      * @return the String result
1200      * @throws IllegalArgumentException if the Object is {@code null}
1201      */
1202     public <T> String toStringWithStatics(final T object, final ToStringStyle style, final Class<? super T> reflectUpToClass) {
1203         return ReflectionToStringBuilder.toString(object, style, false, true, reflectUpToClass);
1204     }
1205 
1206 }