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