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    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.lang3.builder;
18  
19  import static org.junit.jupiter.api.Assertions.assertEquals;
20  import static org.junit.jupiter.api.Assertions.assertThrows;
21  
22  import java.util.ArrayList;
23  import java.util.Arrays;
24  import java.util.Collections;
25  import java.util.Date;
26  import java.util.HashMap;
27  import java.util.LinkedHashMap;
28  import java.util.List;
29  import java.util.Map;
30  
31  import org.apache.commons.lang3.AbstractLangTest;
32  import org.apache.commons.lang3.builder.ToStringStyleTest.Person;
33  import org.junit.jupiter.api.AfterEach;
34  import org.junit.jupiter.api.BeforeEach;
35  import org.junit.jupiter.api.Test;
36  
37  /**
38   * Unit tests {@link org.apache.commons.lang3.builder.JsonToStringStyleTest}.
39   */
40  public class JsonToStringStyleTest extends AbstractLangTest {
41  
42      static class AcademyClass {
43          Teacher teacher;
44          List<Student> students;
45  
46          public List<Student> getStudents() {
47              return students;
48          }
49  
50          public Teacher getTeacher() {
51              return teacher;
52          }
53  
54          public void setStudents(final List<Student> students) {
55              this.students = students;
56          }
57  
58          public void setTeacher(final Teacher teacher) {
59              this.teacher = teacher;
60          }
61  
62          @Override
63          public String toString() {
64              return ToStringBuilder.reflectionToString(this);
65          }
66      }
67  
68      enum EmptyEnum {
69      }
70  
71      enum Hobby {
72          SPORT,
73          BOOK,
74          MUSIC
75      }
76  
77      /**
78       * An object with a Map field used to test {@code ToStringStyle.JsonToStringStyle}.
79       */
80      static class InnerMapObject {
81          /**
82           * Test String field.
83           */
84          String pid;
85  
86          /**
87           * Test inner map field.
88           */
89          Map<String, Object> map;
90      }
91  
92      /**
93       * An object with nested object structures used to test {@code ToStringStyle.JsonToStringStyle}.
94       */
95      static class NestingPerson {
96          /**
97           * Test String field.
98           */
99          String pid;
100 
101         /**
102          * Test nested object field.
103          */
104         Person person;
105     }
106 
107     static class Student {
108         List<Hobby> hobbies;
109 
110         public List<Hobby> getHobbies() {
111             return hobbies;
112         }
113 
114         public void setHobbies(final List<Hobby> hobbies) {
115             this.hobbies = hobbies;
116         }
117 
118         @Override
119         public String toString() {
120             return ToStringBuilder.reflectionToString(this);
121         }
122     }
123 
124     static class Teacher {
125         Hobby[] hobbies;
126 
127         public Hobby[] getHobbies() {
128             return hobbies;
129         }
130 
131         public void setHobbies(final Hobby[] hobbies) {
132             this.hobbies = hobbies;
133         }
134 
135         @Override
136         public String toString() {
137             return ToStringBuilder.reflectionToString(this);
138         }
139     }
140 
141     private final Integer base = Integer.valueOf(5);
142 
143     @BeforeEach
144     public void setUp() {
145         ToStringBuilder.setDefaultStyle(ToStringStyle.JSON_STYLE);
146     }
147 
148     @AfterEach
149     public void tearDown() {
150         ToStringBuilder.setDefaultStyle(ToStringStyle.DEFAULT_STYLE);
151     }
152 
153     @Test
154     public void testAppendSuper() {
155         assertEquals(
156                 "{}",
157                 new ToStringBuilder(base).appendSuper(
158                         "Integer@8888[" + System.lineSeparator() + "]")
159                         .toString());
160         assertEquals(
161                 "{}",
162                 new ToStringBuilder(base).appendSuper(
163                         "Integer@8888[" + System.lineSeparator() + "  null"
164                                 + System.lineSeparator() + "]").toString());
165         assertEquals(
166                 "{\"a\":\"hello\"}",
167                 new ToStringBuilder(base)
168                         .appendSuper(
169                                 "Integer@8888[" + System.lineSeparator()
170                                         + "]").append("a", "hello").toString());
171         assertEquals(
172                 "{\"a\":\"hello\"}",
173                 new ToStringBuilder(base)
174                         .appendSuper(
175                                 "Integer@8888[" + System.lineSeparator()
176                                         + "  null" + System.lineSeparator()
177                                         + "]").append("a", "hello").toString());
178         assertEquals("{\"a\":\"hello\"}", new ToStringBuilder(base)
179                 .appendSuper(null).append("a", "hello").toString());
180 
181         assertEquals("{\"a\":\"hello\",\"b\":\"world\"}", new ToStringBuilder(base)
182                 .appendSuper("{\"a\":\"hello\"}").append("b", "world").toString());
183     }
184 
185     @Test
186     public void testArray() {
187         final Person p = new Person();
188         p.name = "Jane Doe";
189         p.age = 25;
190         p.smoker = true;
191 
192         assertEquals(
193                 "{\"name\":\"Jane Doe\",\"age\":25,\"smoker\":true,\"groups\":['admin', 'manager', 'user']}",
194                 new ToStringBuilder(p).append("name", p.name)
195                         .append("age", p.age).append("smoker", p.smoker)
196                         .append("groups", new Object() {
197                             @Override
198                             public String toString() {
199                                 return "['admin', 'manager', 'user']";
200                             }
201                         })
202                         .toString());
203     }
204 
205     @Test
206     public void testArrayEnum() {
207         final Teacher teacher = new Teacher();
208         final Hobby[] hobbies = new Hobby[3];
209         hobbies[0] = Hobby.BOOK;
210         hobbies[1] = Hobby.SPORT;
211         hobbies[2] = Hobby.MUSIC;
212 
213         teacher.setHobbies(hobbies);
214 
215         assertEquals(teacher.toString(), "{\"hobbies\":[\"BOOK\",\"SPORT\",\"MUSIC\"]}");
216         teacher.setHobbies(new Hobby[0]);
217         assertEquals(teacher.toString(), "{\"hobbies\":[]}");
218         teacher.setHobbies(null);
219         assertEquals(teacher.toString(), "{\"hobbies\":null}");
220     }
221 
222     @Test
223     public void testBlank() {
224         assertEquals("{}", new ToStringBuilder(base).toString());
225     }
226 
227     @Test
228     public void testBooleanArray() {
229         final boolean[] array = {true, false};
230 
231         final ToStringBuilder toStringBuilder = new ToStringBuilder(base);
232         assertThrows(UnsupportedOperationException.class, () -> toStringBuilder.append(array).toString());
233 
234         assertEquals("{\"booleanArray\":[true,false]}", toStringBuilder.append("booleanArray", array)
235                 .toString());
236 
237         assertThrows(
238                 UnsupportedOperationException.class, () -> toStringBuilder.append((Object) array).toString());
239 
240         assertThrows(
241                 UnsupportedOperationException.class, () -> toStringBuilder.append((long[]) null).toString());
242 
243         assertThrows(
244                 UnsupportedOperationException.class, () -> toStringBuilder.append((Object) array).toString());
245     }
246 
247     @Test
248     public void testByteArray() {
249         final byte[] array = {1, 2, -3, 4};
250 
251         final ToStringBuilder toStringBuilder = new ToStringBuilder(base);
252         assertThrows(UnsupportedOperationException.class, () -> toStringBuilder.append(array).toString());
253 
254         assertEquals("{\"byteArray\":[1,2,-3,4]}", toStringBuilder.append("byteArray", array)
255                 .toString());
256 
257         assertThrows(
258                 UnsupportedOperationException.class, () -> toStringBuilder.append((Object) array).toString());
259 
260         assertThrows(
261                 UnsupportedOperationException.class, () -> toStringBuilder.append((long[]) null).toString());
262 
263         assertThrows(
264                 UnsupportedOperationException.class, () -> toStringBuilder.append((Object) array).toString());
265     }
266 
267     @Test
268     public void testChar() {
269         assertThrows(UnsupportedOperationException.class, () -> new ToStringBuilder(base).append('A').toString());
270 
271         assertEquals("{\"a\":\"A\"}", new ToStringBuilder(base).append("a", 'A')
272                 .toString());
273         assertEquals("{\"a\":\"A\",\"b\":\"B\"}", new ToStringBuilder(base).append("a", 'A').append("b", 'B')
274                 .toString());
275     }
276 
277     @Test
278     public void testCharArray() {
279         final char[] array = {'1', '2', '3', '4'};
280 
281         final ToStringBuilder toStringBuilder = new ToStringBuilder(base);
282         assertThrows(UnsupportedOperationException.class, () -> toStringBuilder.append(array).toString());
283 
284         assertEquals("{\"charArray\":[\"1\",\"2\",\"3\",\"4\"]}", toStringBuilder.append("charArray", array)
285                 .toString());
286 
287         assertThrows(
288                 UnsupportedOperationException.class, () -> toStringBuilder.append((Object) array).toString());
289 
290         assertThrows(
291                 UnsupportedOperationException.class, () -> toStringBuilder.append((long[]) null).toString());
292 
293         assertThrows(
294                 UnsupportedOperationException.class, () -> toStringBuilder.append((Object) array).toString());
295     }
296 
297     @Test
298     public void testCombineListAndEnum() {
299         final Teacher teacher = new Teacher();
300 
301         final Hobby[] teacherHobbies = new Hobby[3];
302         teacherHobbies[0] = Hobby.BOOK;
303         teacherHobbies[1] = Hobby.SPORT;
304         teacherHobbies[2] = Hobby.MUSIC;
305 
306         teacher.setHobbies(teacherHobbies);
307 
308         final Student john = new Student();
309         john.setHobbies(Arrays.asList(Hobby.BOOK, Hobby.MUSIC));
310 
311         final Student alice = new Student();
312         alice.setHobbies(new ArrayList<>());
313 
314         final Student bob = new Student();
315         bob.setHobbies(Collections.singletonList(Hobby.BOOK));
316 
317         final ArrayList<Student> students = new ArrayList<>();
318         students.add(john);
319         students.add(alice);
320         students.add(bob);
321 
322         final AcademyClass academyClass = new AcademyClass();
323         academyClass.setStudents(students);
324         academyClass.setTeacher(teacher);
325 
326         assertEquals(academyClass.toString(), "{\"students\":[{\"hobbies\":[\"BOOK\",\"MUSIC\"]},{\"hobbies\":[]},{\"hobbies\":[\"BOOK\"]}],\"teacher\":{\"hobbies\":[\"BOOK\",\"SPORT\",\"MUSIC\"]}}");
327     }
328 
329     @Test
330     public void testDate() {
331         final Date now = new Date();
332         final Date afterNow = new Date(System.currentTimeMillis() + 1);
333 
334         assertThrows(UnsupportedOperationException.class, () -> new ToStringBuilder(base).append(now).toString());
335 
336         assertEquals("{\"now\":\"" + now.toString() +"\"}", new ToStringBuilder(base).append("now", now)
337                 .toString());
338         assertEquals("{\"now\":\"" + now.toString() +"\",\"after\":\"" + afterNow.toString() + "\"}", new ToStringBuilder(base).append("now", now).append("after", afterNow)
339                 .toString());
340     }
341 
342     @Test
343     public void testDoubleArray() {
344         final double[] array = {1, 2, -3, 4};
345 
346         final ToStringBuilder toStringBuilder = new ToStringBuilder(base);
347         assertThrows(UnsupportedOperationException.class, () -> toStringBuilder.append(array).toString());
348 
349         assertEquals("{\"doubleArray\":[1.0,2.0,-3.0,4.0]}", toStringBuilder.append("doubleArray", array)
350                 .toString());
351 
352         assertThrows(
353                 UnsupportedOperationException.class, () -> toStringBuilder.append((Object) array).toString());
354 
355         assertThrows(
356                 UnsupportedOperationException.class, () -> toStringBuilder.append((long[]) null).toString());
357 
358         assertThrows(
359                 UnsupportedOperationException.class, () -> toStringBuilder.append((Object) array).toString());
360     }
361 
362     @Test
363     public void testFloatArray() {
364         final float[] array = {1, 2, -3, 4};
365 
366         final ToStringBuilder toStringBuilder = new ToStringBuilder(base);
367         assertThrows(UnsupportedOperationException.class, () -> toStringBuilder.append(array).toString());
368 
369         assertEquals("{\"floatArray\":[1.0,2.0,-3.0,4.0]}", toStringBuilder.append("floatArray", array)
370                 .toString());
371 
372         assertThrows(
373                 UnsupportedOperationException.class, () -> toStringBuilder.append((Object) array).toString());
374 
375         assertThrows(
376                 UnsupportedOperationException.class, () -> toStringBuilder.append((long[]) null).toString());
377 
378         assertThrows(
379                 UnsupportedOperationException.class, () -> toStringBuilder.append((Object) array).toString());
380     }
381 
382     @Test
383     public void testIntArray() {
384         final int[] array = {1, 2, -3, 4};
385 
386         final ToStringBuilder toStringBuilder = new ToStringBuilder(base);
387         assertThrows(UnsupportedOperationException.class, () -> toStringBuilder.append(array).toString());
388 
389         assertEquals("{\"intArray\":[1,2,-3,4]}", toStringBuilder.append("intArray", array)
390                 .toString());
391 
392         assertThrows(
393                 UnsupportedOperationException.class, () -> toStringBuilder.append((Object) array).toString());
394 
395         assertThrows(
396                 UnsupportedOperationException.class, () -> toStringBuilder.append((long[]) null).toString());
397 
398         assertThrows(
399                 UnsupportedOperationException.class, () -> toStringBuilder.append((Object) array).toString());
400     }
401 
402     @Test
403     public void testLANG1395() {
404         assertEquals("{\"name\":\"value\"}", new ToStringBuilder(base).append("name", "value").toString());
405         assertEquals("{\"name\":\"\"}", new ToStringBuilder(base).append("name", "").toString());
406         assertEquals("{\"name\":\"\\\"\"}", new ToStringBuilder(base).append("name", '"').toString());
407         assertEquals("{\"name\":\"\\\\\"}", new ToStringBuilder(base).append("name", '\\').toString());
408         assertEquals("{\"name\":\"Let's \\\"quote\\\" this\"}", new ToStringBuilder(base).append("name", "Let's \"quote\" this").toString());
409     }
410 
411     @Test
412     public void testLANG1396() {
413         assertEquals("{\"Let's \\\"quote\\\" this\":\"value\"}", new ToStringBuilder(base).append("Let's \"quote\" this", "value").toString());
414     }
415 
416     @Test
417     public void testList() {
418         final Student student = new Student();
419         final ArrayList<Hobby> objects = new ArrayList<>();
420 
421         objects.add(Hobby.BOOK);
422         objects.add(Hobby.SPORT);
423         objects.add(Hobby.MUSIC);
424 
425         student.setHobbies(objects);
426 
427         assertEquals(student.toString(), "{\"hobbies\":[\"BOOK\",\"SPORT\",\"MUSIC\"]}");
428         student.setHobbies(new ArrayList<>());
429         assertEquals(student.toString(), "{\"hobbies\":[]}");
430         student.setHobbies(null);
431         assertEquals(student.toString(), "{\"hobbies\":null}");
432     }
433 
434     @Test
435     public void testLong() {
436         assertThrows(UnsupportedOperationException.class, () -> new ToStringBuilder(base).append(3L).toString());
437 
438         assertEquals("{\"a\":3}", new ToStringBuilder(base).append("a", 3L)
439                 .toString());
440         assertEquals("{\"a\":3,\"b\":4}",
441                 new ToStringBuilder(base).append("a", 3L).append("b", 4L)
442                         .toString());
443     }
444 
445     @Test
446     public void testLongArray() {
447         final long[] array = {1, 2, -3, 4};
448 
449         final ToStringBuilder toStringBuilder = new ToStringBuilder(base);
450         assertThrows(UnsupportedOperationException.class, () -> toStringBuilder.append(array).toString());
451 
452         assertEquals("{\"longArray\":[1,2,-3,4]}", toStringBuilder.append("longArray", array)
453                 .toString());
454 
455         assertThrows(
456                 UnsupportedOperationException.class, () -> toStringBuilder.append((Object) array).toString());
457 
458         assertThrows(
459                 UnsupportedOperationException.class, () -> toStringBuilder.append((long[]) null).toString());
460 
461         assertThrows(
462                 UnsupportedOperationException.class, () -> toStringBuilder.append((Object) array).toString());
463     }
464 
465     @Test
466     public void testLongArrayArray() {
467         final long[][] array = {{1, 2}, null, {5}};
468 
469         final ToStringBuilder toStringBuilder = new ToStringBuilder(base);
470         assertThrows(UnsupportedOperationException.class, () -> toStringBuilder.append(array).toString());
471 
472         assertThrows(
473                 UnsupportedOperationException.class, () -> toStringBuilder.append((Object) array).toString());
474 
475         assertThrows(
476                 UnsupportedOperationException.class, () -> toStringBuilder.append((long[][]) null).toString());
477 
478         assertThrows(
479                 UnsupportedOperationException.class, () -> toStringBuilder.append((Object) array).toString());
480     }
481 
482     @Test
483     public void testMapSkipNullKey() {
484         final Map<String, Object> map = new LinkedHashMap<>();
485         map.put("k1", "v1");
486         map.put(null, "v2");
487 
488         assertEquals("{\"map\":{\"k1\":\"v1\"}}",
489                 new ToStringBuilder(base).append("map", map).toString());
490     }
491 
492     @Test
493     public void testNestedMaps() {
494         final Map<String, Object> innerMap = new LinkedHashMap<>();
495         innerMap.put("k2.1", "v2.1");
496         innerMap.put("k2.2", "v2.2");
497         final Map<String, Object> baseMap = new LinkedHashMap<>();
498         baseMap.put("k1", "v1");
499         baseMap.put("k2", innerMap);
500 
501         final InnerMapObject object = new InnerMapObject(){
502             @Override
503             public String toString() {
504                 return new ToStringBuilder(this).append("pid", this.pid)
505                         .append("map", this.map).toString();
506             }
507         };
508         object.pid = "dummy-text";
509         object.map = baseMap;
510 
511         assertEquals("{\"object\":{\"pid\":\"dummy-text\",\"map\":{\"k1\":\"v1\"," +
512                         "\"k2\":{\"k2.1\":\"v2.1\",\"k2.2\":\"v2.2\"}}}}",
513                 new ToStringBuilder(base).append("object", object).toString());
514     }
515 
516     @Test
517     public void testNestingPerson() {
518         final Person p = new Person() {
519             @Override
520             public String toString() {
521                 return new ToStringBuilder(this).append("name", this.name)
522                     .append("age", this.age).append("smoker", this.smoker)
523                     .toString();
524             }
525         };
526         p.name = "Jane Doe";
527         p.age = 25;
528         p.smoker = true;
529 
530         final NestingPerson nestP = new NestingPerson();
531         nestP.pid="#1@Jane";
532         nestP.person = p;
533 
534         assertEquals(
535                 "{\"pid\":\"#1@Jane\",\"person\":{\"name\":\"Jane Doe\",\"age\":25,\"smoker\":true}}",
536                 new ToStringBuilder(nestP).append("pid", nestP.pid)
537                         .append("person", nestP.person)
538                         .toString());
539     }
540 
541     @Test
542     public void testNull() {
543         assertEquals("null", new ToStringBuilder(null).toString());
544     }
545 
546     @Test
547     public void testObject() {
548 
549         final Integer i3 = Integer.valueOf(3);
550         final Integer i4 = Integer.valueOf(4);
551 
552         assertThrows(
553                 UnsupportedOperationException.class, () -> new ToStringBuilder(base).append((Object) null).toString());
554 
555         assertThrows(UnsupportedOperationException.class, () -> new ToStringBuilder(base).append(i3).toString());
556 
557         assertEquals("{\"a\":null}",
558                 new ToStringBuilder(base).append("a", (Object) null).toString());
559         assertEquals("{\"a\":3}", new ToStringBuilder(base).append("a", i3)
560                 .toString());
561         assertEquals("{\"a\":3,\"b\":4}",
562                 new ToStringBuilder(base).append("a", i3).append("b", i4)
563                         .toString());
564 
565         assertThrows(
566                 UnsupportedOperationException.class, () -> new ToStringBuilder(base).append("a", i3, false).toString());
567 
568         assertThrows(
569                 UnsupportedOperationException.class,
570                 () -> new ToStringBuilder(base).append("a", new ArrayList<>(), false).toString());
571 
572         assertEquals(
573                 "{\"a\":[]}",
574                 new ToStringBuilder(base).append("a", new ArrayList<>(),
575                         true).toString());
576 
577         assertThrows(
578                 UnsupportedOperationException.class,
579                 () -> new ToStringBuilder(base).append("a", new HashMap<>(), false).toString());
580 
581         assertEquals(
582                 "{\"a\":{}}",
583                 new ToStringBuilder(base).append("a",
584                         new HashMap<>(), true).toString());
585 
586         assertThrows(
587                 UnsupportedOperationException.class,
588                 () -> new ToStringBuilder(base).append("a", (Object) new String[0], false).toString());
589 
590         assertEquals(
591                 "{\"a\":[]}",
592                 new ToStringBuilder(base).append("a", (Object) new String[0],
593                         true).toString());
594 
595         assertThrows(
596                 UnsupportedOperationException.class,
597                 () -> new ToStringBuilder(base).append("a", (Object) new int[]{1, 2, 3}, false).toString());
598 
599         assertEquals(
600                 "{\"a\":[1,2,3]}",
601                 new ToStringBuilder(base).append("a",
602                         (Object) new int[]{1, 2, 3}, true).toString());
603 
604         assertThrows(
605                 UnsupportedOperationException.class,
606                 () -> new ToStringBuilder(base).append("a", (Object) new String[]{"v", "x", "y", "z"}, false).toString());
607 
608         assertEquals(
609                 "{\"a\":[\"v\",\"x\",\"y\",\"z\"]}",
610                 new ToStringBuilder(base).append("a",
611                         (Object) new String[]{"v", "x", "y", "z"}, true)
612                         .toString());
613     }
614 
615     @Test
616     public void testObjectArray() {
617         final Object[] array = {null, base, new int[]{3, 6}};
618 
619         final ToStringBuilder toStringBuilder = new ToStringBuilder(base);
620         assertThrows(UnsupportedOperationException.class, () -> toStringBuilder.append(array).toString());
621 
622         assertEquals("{\"objectArray\":[null,5,[3,6]]}", toStringBuilder.append("objectArray", array)
623                 .toString());
624 
625         assertThrows(
626                 UnsupportedOperationException.class, () -> toStringBuilder.append((Object) array).toString());
627 
628         assertThrows(
629                 UnsupportedOperationException.class, () -> toStringBuilder.append((Object[]) null).toString());
630 
631         assertThrows(
632                 UnsupportedOperationException.class, () -> toStringBuilder.append((Object) array).toString());
633     }
634 
635     @Test
636     public void testObjectWithInnerMap() {
637         final Map<String, Object> map = new LinkedHashMap<>();
638         map.put("k1", "value1");
639         map.put("k2", 2);
640 
641         final InnerMapObject object = new InnerMapObject(){
642             @Override
643             public String toString() {
644                 return new ToStringBuilder(this).append("pid", this.pid)
645                         .append("map", this.map).toString();
646             }
647         };
648         object.pid = "dummy-text";
649         object.map = map;
650 
651         assertEquals("{\"object\":{\"pid\":\"dummy-text\",\"map\":{\"k1\":\"value1\",\"k2\":2}}}",
652                 new ToStringBuilder(base).append("object", object).toString());
653     }
654 
655     @Test
656     public void testPerson() {
657         final Person p = new Person();
658         p.name = "Jane Doe";
659         p.age = 25;
660         p.smoker = true;
661 
662         assertEquals(
663                 "{\"name\":\"Jane Doe\",\"age\":25,\"smoker\":true}",
664                 new ToStringBuilder(p).append("name", p.name)
665                         .append("age", p.age).append("smoker", p.smoker)
666                         .toString());
667     }
668 
669     @Test
670     public void testRootMap() {
671         final Map<String, Object> map = new LinkedHashMap<>();
672         map.put("k1", "v1");
673         map.put("k2", 2);
674 
675         assertEquals("{\"map\":{\"k1\":\"v1\",\"k2\":2}}",
676                 new ToStringBuilder(base).append("map", map).toString());
677     }
678 
679     @Test
680     public void testShortArray() {
681         final short[] array = {1, 2, -3, 4};
682 
683         final ToStringBuilder toStringBuilder = new ToStringBuilder(base);
684         assertThrows(UnsupportedOperationException.class, () -> toStringBuilder.append(array).toString());
685 
686         assertEquals("{\"shortArray\":[1,2,-3,4]}", toStringBuilder.append("shortArray", array)
687                 .toString());
688 
689         assertThrows(
690                 UnsupportedOperationException.class, () -> toStringBuilder.append((Object) array).toString());
691 
692         assertThrows(
693                 UnsupportedOperationException.class, () -> toStringBuilder.append((long[]) null).toString());
694 
695         assertThrows(
696                 UnsupportedOperationException.class, () -> toStringBuilder.append((Object) array).toString());
697     }
698 }