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 
18 package org.apache.commons.lang3.builder;
19 
20 import static org.junit.jupiter.api.Assertions.assertEquals;
21 
22 import java.util.ArrayList;
23 import java.util.List;
24 
25 import org.apache.commons.lang3.AbstractLangTest;
26 import org.junit.jupiter.api.Test;
27 
28 /**
29  */
30 public class MultilineRecursiveToStringStyleTest extends AbstractLangTest {
31 
32     private static final String LS = System.lineSeparator();
33     private static final String BASE_WITH_ARRAYS_TO_STRING = "[" + LS
34             + "  boolArray=#BOOLEAN#," + LS
35             + "  byteArray=#BYTE#," + LS
36             + "  charArray=#CHAR#," + LS
37             + "  doubleArray=#DOUBLE#," + LS
38             + "  floatArray=#FLOAT#," + LS
39             + "  intArray=#INT#," + LS
40             + "  longArray=#LONG#," + LS
41             + "  shortArray=#SHORT#," + LS
42             + "  stringArray=#STRING#" + LS
43             + "]";
44 
45     @Test
simpleObject()46     public void simpleObject() {
47         final Transaction tx = new Transaction("2014.10.15", 100);
48         final String expected = getClassPrefix(tx) + "[" + LS
49                         + "  amount=100.0," + LS
50                         + "  date=2014.10.15" + LS
51                         + "]";
52         assertEquals(expected, toString(tx));
53     }
54 
55     @Test
nestedElements()56     public void nestedElements() {
57         final Customer customer = new Customer("Douglas Adams");
58         final Bank bank = new Bank("ASF Bank");
59         customer.bank = bank;
60         final String exp = getClassPrefix(customer) + "[" + LS
61                    + "  accounts=<null>," + LS
62                    + "  bank=" + getClassPrefix(bank) + "[" + LS
63                    + "    name=ASF Bank" + LS
64                    + "  ]," + LS
65                    + "  name=Douglas Adams" + LS
66                 + "]";
67         assertEquals(exp, toString(customer));
68     }
69 
70     @Test
nestedAndArray()71     public void nestedAndArray() {
72         final Account acc = new Account();
73         final Transaction tx1 = new Transaction("2014.10.14", 100);
74         final Transaction tx2 = new Transaction("2014.10.15", 50);
75         acc.transactions.add(tx1);
76         acc.transactions.add(tx2);
77         final String expected = getClassPrefix(acc) + "[" + LS
78                         + "  owner=<null>," + LS
79                         + "  transactions=" + getClassPrefix(acc.transactions) + "{" + LS
80                         + "    " + getClassPrefix(tx1) + "[" + LS
81                         + "      amount=100.0," + LS
82                         + "      date=2014.10.14" + LS
83                         + "    ]," + LS
84                         + "    " + getClassPrefix(tx2) + "[" + LS
85                         + "      amount=50.0," + LS
86                         + "      date=2014.10.15" + LS
87                         + "    ]" + LS
88                         + "  }" + LS
89                         + "]";
90         assertEquals(expected, toString(acc));
91     }
92 
93     @Test
noArray()94     public void noArray() {
95         final WithArrays wa = new WithArrays();
96         final String exp = getExpectedToString(wa, WithArraysTestType.NONE, "");
97         assertEquals(exp, toString(wa));
98     }
99 
100     @Test
boolArray()101     public void boolArray() {
102         final WithArrays wa = new WithArrays();
103         wa.boolArray = new boolean[] { true, false, true };
104         final String exp = getExpectedToString(
105                 wa, WithArraysTestType.BOOLEAN,
106                 "{" + LS
107                 + "    true," + LS
108                 + "    false," + LS
109                 + "    true" + LS
110                 + "  }");
111         assertEquals(exp, toString(wa));
112     }
113 
114     @Test
byteArray()115     public void byteArray() {
116         final WithArrays wa = new WithArrays();
117         wa.byteArray = new byte[] { 1, 2 };
118         final String exp = getExpectedToString(
119                 wa, WithArraysTestType.BYTE,
120                 "{" + LS
121                 + "    1," + LS
122                 + "    2" + LS
123                 + "  }");
124         assertEquals(exp, toString(wa));
125     }
126 
127     @Test
charArray()128     public void charArray() {
129         final WithArrays wa = new WithArrays();
130         wa.charArray = new char[] { 'a', 'A' };
131         final String exp = getExpectedToString(
132                 wa, WithArraysTestType.CHAR,
133                 "{" + LS
134                 + "    a," + LS
135                 + "    A" + LS
136                 + "  }");
137         assertEquals(exp, toString(wa));
138     }
139 
140     @Test
intArray()141     public void intArray() {
142         final WithArrays wa = new WithArrays();
143         wa.intArray = new int[] { 1, 2 };
144         final String exp = getExpectedToString(
145                 wa, WithArraysTestType.INT,
146                 "{" + LS
147                 + "    1," + LS
148                 + "    2" + LS
149                 + "  }");
150         assertEquals(exp, toString(wa));
151     }
152 
153     @Test
doubleArray()154     public void doubleArray() {
155         final WithArrays wa = new WithArrays();
156         wa.doubleArray = new double[] { 1, 2 };
157         final String exp = getExpectedToString(
158                 wa, WithArraysTestType.DOUBLE,
159                 "{" + LS
160                 + "    1.0," + LS
161                 + "    2.0" + LS
162                 + "  }");
163         assertEquals(exp, toString(wa));
164     }
165 
166     @Test
floatArray()167     public void floatArray() {
168         final WithArrays wa = new WithArrays();
169         wa.floatArray = new float[] { 1f, 2f };
170         final String exp = getExpectedToString(
171                 wa, WithArraysTestType.FLOAT,
172                 "{" + LS
173                 + "    1.0," + LS
174                 + "    2.0" + LS
175                 + "  }");
176         assertEquals(exp, toString(wa));
177     }
178 
179     @Test
longArray()180     public void longArray() {
181         final WithArrays wa = new WithArrays();
182         wa.longArray = new long[] { 1L, 2L };
183         final String exp = getExpectedToString(
184                 wa, WithArraysTestType.LONG,
185                 "{" + LS
186                 + "    1," + LS
187                 + "    2" + LS
188                 + "  }");
189         assertEquals(exp, toString(wa));
190     }
191 
192     @Test
stringArray()193     public void stringArray() {
194         final WithArrays wa = new WithArrays();
195         wa.stringArray = new String[] { "a", "A" };
196         final String exp = getExpectedToString(
197                 wa, WithArraysTestType.STRING,
198                 "{" + LS
199                 + "    a," + LS
200                 + "    A" + LS
201                 + "  }");
202         assertEquals(exp, toString(wa));
203     }
204 
205     @Test
shortArray()206     public void shortArray() {
207         final WithArrays wa = new WithArrays();
208         wa.shortArray = new short[] { 1, 2 };
209         final String exp = getExpectedToString(
210                 wa, WithArraysTestType.SHORT,
211                 "{" + LS
212                 + "    1," + LS
213                 + "    2" + LS
214                 + "  }");
215         assertEquals(exp, toString(wa));
216     }
217 
218     @Test
testLANG1319()219     public void testLANG1319() {
220         final String[] stringArray = {"1", "2"};
221 
222         final String exp = getClassPrefix(stringArray) + "[" + LS
223                 + "  {" + LS
224                 + "    1," + LS
225                 + "    2" + LS
226                 + "  }" + LS
227                 + "]";
228         assertEquals(exp, toString(stringArray));
229     }
230 
getClassPrefix(final Object object)231     private String getClassPrefix(final Object object) {
232         return object.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(object));
233     }
234 
toString(final Object object)235     private String toString(final Object object) {
236         return new ReflectionToStringBuilder(object, new MultilineRecursiveToStringStyle()).toString();
237     }
238 
239     static class WithArrays {
240         boolean[] boolArray;
241         byte[] byteArray;
242         char[] charArray;
243         double[] doubleArray;
244         float[] floatArray;
245         int[] intArray;
246         long[] longArray;
247         short[] shortArray;
248         String[] stringArray;
249     }
250 
251     /**
252      * Create an expected to String for the given WithArraysInstance
253      * @param wa                 Instance
254      * @param arrayType          Type - empty used to indicate expect all nulls
255      * @param expectedArrayValue Expected value for the array type
256      * @return expected toString
257      */
getExpectedToString(final WithArrays wa, final WithArraysTestType arrayType, final String expectedArrayValue)258     private String getExpectedToString(final WithArrays wa, final WithArraysTestType arrayType, final String expectedArrayValue) {
259         return getClassPrefix(wa)
260                 + BASE_WITH_ARRAYS_TO_STRING
261                 .replace("#" + arrayType + "#", expectedArrayValue)
262                 .replaceAll("#[A-Z]+#", "<null>");
263     }
264 
265     private enum WithArraysTestType {
266         NONE, BOOLEAN, BYTE, CHAR, DOUBLE, FLOAT, INT, LONG, SHORT, STRING
267     }
268 
269     static class Bank {
270         String name;
271 
Bank(final String name)272         Bank(final String name) {
273             this.name = name;
274         }
275     }
276 
277     static class Customer {
278         String name;
279         Bank bank;
280         List<Account> accounts;
281 
Customer(final String name)282         Customer(final String name) {
283             this.name = name;
284         }
285     }
286 
287     static class Account {
288         Customer owner;
289         List<Transaction> transactions = new ArrayList<>();
290 
getBalance()291         public double getBalance() {
292             double balance = 0;
293             for (final Transaction tx : transactions) {
294                 balance += tx.amount;
295             }
296             return balance;
297         }
298     }
299 
300     static class Transaction {
301         double amount;
302         String date;
303 
Transaction(final String datum, final double betrag)304         Transaction(final String datum, final double betrag) {
305             this.date = datum;
306             this.amount = betrag;
307         }
308     }
309 
310 }
311