/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.lang3.builder; import org.apache.commons.lang3.builder.ToStringStyleTest.Person; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.List; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; /** * Unit tests {@link org.apache.commons.lang3.builder.JsonToStringStyleTest}. */ public class JsonToStringStyleTest { private final Integer base = Integer.valueOf(5); @BeforeEach public void setUp() { ToStringBuilder.setDefaultStyle(ToStringStyle.JSON_STYLE); } @AfterEach public void tearDown() { ToStringBuilder.setDefaultStyle(ToStringStyle.DEFAULT_STYLE); } // ---------------------------------------------------------------- @Test public void testNull() { assertEquals("null", new ToStringBuilder(null).toString()); } @Test public void testBlank() { assertEquals("{}", new ToStringBuilder(base).toString()); } @Test public void testAppendSuper() { assertEquals( "{}", new ToStringBuilder(base).appendSuper( "Integer@8888[" + System.lineSeparator() + "]") .toString()); assertEquals( "{}", new ToStringBuilder(base).appendSuper( "Integer@8888[" + System.lineSeparator() + " null" + System.lineSeparator() + "]").toString()); assertEquals( "{\"a\":\"hello\"}", new ToStringBuilder(base) .appendSuper( "Integer@8888[" + System.lineSeparator() + "]").append("a", "hello").toString()); assertEquals( "{\"a\":\"hello\"}", new ToStringBuilder(base) .appendSuper( "Integer@8888[" + System.lineSeparator() + " null" + System.lineSeparator() + "]").append("a", "hello").toString()); assertEquals("{\"a\":\"hello\"}", new ToStringBuilder(base) .appendSuper(null).append("a", "hello").toString()); assertEquals("{\"a\":\"hello\",\"b\":\"world\"}", new ToStringBuilder(base) .appendSuper("{\"a\":\"hello\"}").append("b", "world").toString()); } @Test public void testChar() { assertThrows(UnsupportedOperationException.class, () -> new ToStringBuilder(base).append('A').toString()); assertEquals("{\"a\":\"A\"}", new ToStringBuilder(base).append("a", 'A') .toString()); assertEquals("{\"a\":\"A\",\"b\":\"B\"}", new ToStringBuilder(base).append("a", 'A').append("b", 'B') .toString()); } @Test public void testDate() { final Date now = new Date(); final Date afterNow = new Date(System.currentTimeMillis() + 1); assertThrows(UnsupportedOperationException.class, () -> new ToStringBuilder(base).append(now).toString()); assertEquals("{\"now\":\"" + now.toString() +"\"}", new ToStringBuilder(base).append("now", now) .toString()); assertEquals("{\"now\":\"" + now.toString() +"\",\"after\":\"" + afterNow.toString() + "\"}", new ToStringBuilder(base).append("now", now).append("after", afterNow) .toString()); } @Test public void testObject() { final Integer i3 = Integer.valueOf(3); final Integer i4 = Integer.valueOf(4); assertThrows( UnsupportedOperationException.class, () -> new ToStringBuilder(base).append((Object) null).toString()); assertThrows(UnsupportedOperationException.class, () -> new ToStringBuilder(base).append(i3).toString()); assertEquals("{\"a\":null}", new ToStringBuilder(base).append("a", (Object) null).toString()); assertEquals("{\"a\":3}", new ToStringBuilder(base).append("a", i3) .toString()); assertEquals("{\"a\":3,\"b\":4}", new ToStringBuilder(base).append("a", i3).append("b", i4) .toString()); assertThrows( UnsupportedOperationException.class, () -> new ToStringBuilder(base).append("a", i3, false).toString()); assertThrows( UnsupportedOperationException.class, () -> new ToStringBuilder(base).append("a", new ArrayList<>(), false).toString()); assertEquals( "{\"a\":[]}", new ToStringBuilder(base).append("a", new ArrayList<>(), true).toString()); assertThrows( UnsupportedOperationException.class, () -> new ToStringBuilder(base).append("a", new HashMap<>(), false).toString()); assertEquals( "{\"a\":{}}", new ToStringBuilder(base).append("a", new HashMap<>(), true).toString()); assertThrows( UnsupportedOperationException.class, () -> new ToStringBuilder(base).append("a", (Object) new String[0], false).toString()); assertEquals( "{\"a\":[]}", new ToStringBuilder(base).append("a", (Object) new String[0], true).toString()); assertThrows( UnsupportedOperationException.class, () -> new ToStringBuilder(base).append("a", (Object) new int[]{1, 2, 3}, false).toString()); assertEquals( "{\"a\":[1,2,3]}", new ToStringBuilder(base).append("a", (Object) new int[]{1, 2, 3}, true).toString()); assertThrows( UnsupportedOperationException.class, () -> new ToStringBuilder(base).append("a", (Object) new String[]{"v", "x", "y", "z"}, false).toString()); assertEquals( "{\"a\":[\"v\",\"x\",\"y\",\"z\"]}", new ToStringBuilder(base).append("a", (Object) new String[]{"v", "x", "y", "z"}, true) .toString()); } @Test public void testList() { Student student = new Student(); ArrayList objects = new ArrayList<>(); objects.add(Hobby.BOOK); objects.add(Hobby.SPORT); objects.add(Hobby.MUSIC); student.setHobbies(objects); assertEquals(student.toString(), "{\"hobbies\":[\"BOOK\",\"SPORT\",\"MUSIC\"]}"); student.setHobbies(new ArrayList<>()); assertEquals(student.toString(), "{\"hobbies\":[]}"); student.setHobbies(null); assertEquals(student.toString(), "{\"hobbies\":null}"); } @Test public void testArrayEnum() { Teacher teacher = new Teacher(); Hobby[] hobbies = new Hobby[3]; hobbies[0] = Hobby.BOOK; hobbies[1] = Hobby.SPORT; hobbies[2] = Hobby.MUSIC; teacher.setHobbies(hobbies); assertEquals(teacher.toString(), "{\"hobbies\":[\"BOOK\",\"SPORT\",\"MUSIC\"]}"); teacher.setHobbies(new Hobby[0]); assertEquals(teacher.toString(), "{\"hobbies\":[]}"); teacher.setHobbies(null); assertEquals(teacher.toString(), "{\"hobbies\":null}"); } @Test public void testCombineListAndEnum() { Teacher teacher = new Teacher(); Hobby[] teacherHobbies = new Hobby[3]; teacherHobbies[0] = Hobby.BOOK; teacherHobbies[1] = Hobby.SPORT; teacherHobbies[2] = Hobby.MUSIC; teacher.setHobbies(teacherHobbies); Student john = new Student(); john.setHobbies(Arrays.asList(Hobby.BOOK, Hobby.MUSIC)); Student alice = new Student(); alice.setHobbies(new ArrayList<>()); Student bob = new Student(); bob.setHobbies(Collections.singletonList(Hobby.BOOK)); ArrayList students = new ArrayList<>(); students.add(john); students.add(alice); students.add(bob); AcademyClass academyClass = new AcademyClass(); academyClass.setStudents(students); academyClass.setTeacher(teacher); assertEquals(academyClass.toString(), "{\"students\":[{\"hobbies\":[\"BOOK\",\"MUSIC\"]},{\"hobbies\":[]},{\"hobbies\":[\"BOOK\"]}],\"teacher\":{\"hobbies\":[\"BOOK\",\"SPORT\",\"MUSIC\"]}}"); } @Test public void testPerson() { final Person p = new Person(); p.name = "Jane Doe"; p.age = 25; p.smoker = true; assertEquals( "{\"name\":\"Jane Doe\",\"age\":25,\"smoker\":true}", new ToStringBuilder(p).append("name", p.name) .append("age", p.age).append("smoker", p.smoker) .toString()); } @Test public void testNestingPerson() { final Person p = new Person() { @Override public String toString() { return new ToStringBuilder(this).append("name", this.name) .append("age", this.age).append("smoker", this.smoker) .toString(); } }; p.name = "Jane Doe"; p.age = 25; p.smoker = true; final NestingPerson nestP = new NestingPerson(); nestP.pid="#1@Jane"; nestP.person = p; assertEquals( "{\"pid\":\"#1@Jane\",\"person\":{\"name\":\"Jane Doe\",\"age\":25,\"smoker\":true}}", new ToStringBuilder(nestP).append("pid", nestP.pid) .append("person", nestP.person) .toString()); } @Test public void testLong() { assertThrows(UnsupportedOperationException.class, () -> new ToStringBuilder(base).append(3L).toString()); assertEquals("{\"a\":3}", new ToStringBuilder(base).append("a", 3L) .toString()); assertEquals("{\"a\":3,\"b\":4}", new ToStringBuilder(base).append("a", 3L).append("b", 4L) .toString()); } @Test public void testObjectArray() { final Object[] array = new Object[]{null, base, new int[]{3, 6}}; final ToStringBuilder toStringBuilder = new ToStringBuilder(base); assertThrows(UnsupportedOperationException.class, () -> toStringBuilder.append(array).toString()); assertEquals("{\"objectArray\":[null,5,[3,6]]}", toStringBuilder.append("objectArray", array) .toString()); assertThrows( UnsupportedOperationException.class, () -> toStringBuilder.append((Object) array).toString()); assertThrows( UnsupportedOperationException.class, () -> toStringBuilder.append((Object[]) null).toString()); assertThrows( UnsupportedOperationException.class, () -> toStringBuilder.append((Object) array).toString()); } @Test public void testLongArray() { final long[] array = new long[]{1, 2, -3, 4}; final ToStringBuilder toStringBuilder = new ToStringBuilder(base); assertThrows(UnsupportedOperationException.class, () -> toStringBuilder.append(array).toString()); assertEquals("{\"longArray\":[1,2,-3,4]}", toStringBuilder.append("longArray", array) .toString()); assertThrows( UnsupportedOperationException.class, () -> toStringBuilder.append((Object) array).toString()); assertThrows( UnsupportedOperationException.class, () -> toStringBuilder.append((long[]) null).toString()); assertThrows( UnsupportedOperationException.class, () -> toStringBuilder.append((Object) array).toString()); } @Test public void testIntArray() { final int[] array = new int[]{1, 2, -3, 4}; final ToStringBuilder toStringBuilder = new ToStringBuilder(base); assertThrows(UnsupportedOperationException.class, () -> toStringBuilder.append(array).toString()); assertEquals("{\"intArray\":[1,2,-3,4]}", toStringBuilder.append("intArray", array) .toString()); assertThrows( UnsupportedOperationException.class, () -> toStringBuilder.append((Object) array).toString()); assertThrows( UnsupportedOperationException.class, () -> toStringBuilder.append((long[]) null).toString()); assertThrows( UnsupportedOperationException.class, () -> toStringBuilder.append((Object) array).toString()); } @Test public void testByteArray() { final byte[] array = new byte[]{1, 2, -3, 4}; final ToStringBuilder toStringBuilder = new ToStringBuilder(base); assertThrows(UnsupportedOperationException.class, () -> toStringBuilder.append(array).toString()); assertEquals("{\"byteArray\":[1,2,-3,4]}", toStringBuilder.append("byteArray", array) .toString()); assertThrows( UnsupportedOperationException.class, () -> toStringBuilder.append((Object) array).toString()); assertThrows( UnsupportedOperationException.class, () -> toStringBuilder.append((long[]) null).toString()); assertThrows( UnsupportedOperationException.class, () -> toStringBuilder.append((Object) array).toString()); } @Test public void testShortArray() { final short[] array = new short[]{1, 2, -3, 4}; final ToStringBuilder toStringBuilder = new ToStringBuilder(base); assertThrows(UnsupportedOperationException.class, () -> toStringBuilder.append(array).toString()); assertEquals("{\"shortArray\":[1,2,-3,4]}", toStringBuilder.append("shortArray", array) .toString()); assertThrows( UnsupportedOperationException.class, () -> toStringBuilder.append((Object) array).toString()); assertThrows( UnsupportedOperationException.class, () -> toStringBuilder.append((long[]) null).toString()); assertThrows( UnsupportedOperationException.class, () -> toStringBuilder.append((Object) array).toString()); } @Test public void testDoubleArray() { final double[] array = new double[]{1, 2, -3, 4}; final ToStringBuilder toStringBuilder = new ToStringBuilder(base); assertThrows(UnsupportedOperationException.class, () -> toStringBuilder.append(array).toString()); assertEquals("{\"doubleArray\":[1.0,2.0,-3.0,4.0]}", toStringBuilder.append("doubleArray", array) .toString()); assertThrows( UnsupportedOperationException.class, () -> toStringBuilder.append((Object) array).toString()); assertThrows( UnsupportedOperationException.class, () -> toStringBuilder.append((long[]) null).toString()); assertThrows( UnsupportedOperationException.class, () -> toStringBuilder.append((Object) array).toString()); } @Test public void testFloatArray() { final float[] array = new float[]{1, 2, -3, 4}; final ToStringBuilder toStringBuilder = new ToStringBuilder(base); assertThrows(UnsupportedOperationException.class, () -> toStringBuilder.append(array).toString()); assertEquals("{\"floatArray\":[1.0,2.0,-3.0,4.0]}", toStringBuilder.append("floatArray", array) .toString()); assertThrows( UnsupportedOperationException.class, () -> toStringBuilder.append((Object) array).toString()); assertThrows( UnsupportedOperationException.class, () -> toStringBuilder.append((long[]) null).toString()); assertThrows( UnsupportedOperationException.class, () -> toStringBuilder.append((Object) array).toString()); } @Test public void testCharArray() { final char[] array = new char[]{'1', '2', '3', '4'}; final ToStringBuilder toStringBuilder = new ToStringBuilder(base); assertThrows(UnsupportedOperationException.class, () -> toStringBuilder.append(array).toString()); assertEquals("{\"charArray\":[\"1\",\"2\",\"3\",\"4\"]}", toStringBuilder.append("charArray", array) .toString()); assertThrows( UnsupportedOperationException.class, () -> toStringBuilder.append((Object) array).toString()); assertThrows( UnsupportedOperationException.class, () -> toStringBuilder.append((long[]) null).toString()); assertThrows( UnsupportedOperationException.class, () -> toStringBuilder.append((Object) array).toString()); } @Test public void testBooleanArray() { final boolean[] array = new boolean[]{true, false}; final ToStringBuilder toStringBuilder = new ToStringBuilder(base); assertThrows(UnsupportedOperationException.class, () -> toStringBuilder.append(array).toString()); assertEquals("{\"booleanArray\":[true,false]}", toStringBuilder.append("booleanArray", array) .toString()); assertThrows( UnsupportedOperationException.class, () -> toStringBuilder.append((Object) array).toString()); assertThrows( UnsupportedOperationException.class, () -> toStringBuilder.append((long[]) null).toString()); assertThrows( UnsupportedOperationException.class, () -> toStringBuilder.append((Object) array).toString()); } @Test public void testLongArrayArray() { final long[][] array = new long[][]{{1, 2}, null, {5}}; final ToStringBuilder toStringBuilder = new ToStringBuilder(base); assertThrows(UnsupportedOperationException.class, () -> toStringBuilder.append(array).toString()); assertThrows( UnsupportedOperationException.class, () -> toStringBuilder.append((Object) array).toString()); assertThrows( UnsupportedOperationException.class, () -> toStringBuilder.append((long[][]) null).toString()); assertThrows( UnsupportedOperationException.class, () -> toStringBuilder.append((Object) array).toString()); } @Test public void testArray() { final Person p = new Person(); p.name = "Jane Doe"; p.age = 25; p.smoker = true; assertEquals( "{\"name\":\"Jane Doe\",\"age\":25,\"smoker\":true,\"groups\":['admin', 'manager', 'user']}", new ToStringBuilder(p).append("name", p.name) .append("age", p.age).append("smoker", p.smoker) .append("groups", new Object() { @Override public String toString() { return "['admin', 'manager', 'user']"; } }) .toString()); } @Test public void testLANG1395() { assertEquals("{\"name\":\"value\"}", new ToStringBuilder(base).append("name", "value").toString()); assertEquals("{\"name\":\"\"}", new ToStringBuilder(base).append("name", "").toString()); assertEquals("{\"name\":\"\\\"\"}", new ToStringBuilder(base).append("name", '"').toString()); assertEquals("{\"name\":\"\\\\\"}", new ToStringBuilder(base).append("name", '\\').toString()); assertEquals("{\"name\":\"Let's \\\"quote\\\" this\"}", new ToStringBuilder(base).append("name", "Let's \"quote\" this").toString()); } @Test public void testLANG1396() { assertEquals("{\"Let's \\\"quote\\\" this\":\"value\"}", new ToStringBuilder(base).append("Let's \"quote\" this", "value").toString()); } /** * An object with nested object structures used to test {@link ToStringStyle.JsonToStringStyle}. * */ static class NestingPerson { /** * Test String field. */ String pid; /** * Test nested object field. */ Person person; } enum Hobby { SPORT, BOOK, MUSIC } enum EmptyEnum { } static class Student { List hobbies; public List getHobbies() { return hobbies; } public void setHobbies(List hobbies) { this.hobbies = hobbies; } @Override public String toString() { return ToStringBuilder.reflectionToString(this); } } static class Teacher { Hobby[] hobbies; public Hobby[] getHobbies() { return hobbies; } public void setHobbies(Hobby[] hobbies) { this.hobbies = hobbies; } @Override public String toString() { return ToStringBuilder.reflectionToString(this); } } static class AcademyClass { Teacher teacher; List students; public void setTeacher(Teacher teacher) { this.teacher = teacher; } public void setStudents(List students) { this.students = students; } public Teacher getTeacher() { return teacher; } public List getStudents() { return students; } @Override public String toString() { return ToStringBuilder.reflectionToString(this); } } }