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.beanutils.converters; 18 19 import java.lang.reflect.Array; 20 import java.util.ArrayList; 21 import java.util.Locale; 22 23 import junit.framework.TestCase; 24 import junit.framework.TestSuite; 25 26 /** 27 * Test Case for the ArrayConverter class. 28 * 29 * @version $Id$ 30 */ 31 public class ArrayConverterTestCase extends TestCase { 32 33 /** 34 * Construct a new Array Converter test case. 35 * @param name Test Name 36 */ ArrayConverterTestCase(final String name)37 public ArrayConverterTestCase(final String name) { 38 super(name); 39 } 40 41 // ------------------------------------------------------------------------ 42 43 /** 44 * Create Test Suite 45 * @return test suite 46 */ suite()47 public static TestSuite suite() { 48 return new TestSuite(ArrayConverterTestCase.class); 49 } 50 51 /** Set Up */ 52 @Override setUp()53 public void setUp() throws Exception { 54 } 55 56 /** Tear Down */ 57 @Override tearDown()58 public void tearDown() throws Exception { 59 } 60 61 62 // ------------------------------------------------------------------------ 63 64 /** 65 * Test Converting using the IntegerConverter as the component Converter 66 */ testComponentIntegerConverter()67 public void testComponentIntegerConverter() { 68 69 final IntegerConverter intConverter = new IntegerConverter(new Integer(0)); 70 intConverter.setPattern("#,###"); 71 intConverter.setLocale(Locale.US); 72 final ArrayConverter arrayConverter = new ArrayConverter(int[].class, intConverter, 0); 73 arrayConverter.setAllowedChars(new char[] {',', '-'}); 74 arrayConverter.setDelimiter(';'); 75 76 // Expected results 77 final int[] intArray = new int[] {1111, 2222, 3333, 4444}; 78 final String stringA = "1,111; 2,222; 3,333; 4,444"; 79 final String stringB = intArray[0]+ ";" + intArray[1] + ";" + intArray[2] + ";" +intArray[3]; 80 final String[] strArray = new String[] {""+intArray[0], ""+intArray[1], ""+intArray[2], ""+intArray[3]}; 81 final long[] longArray = new long[] {intArray[0], intArray[1], intArray[2], intArray[3]}; 82 final Long[] LONGArray = new Long[] {new Long(intArray[0]), new Long(intArray[1]), new Long(intArray[2]), new Long(intArray[3])}; 83 final Integer[] IntegerArray = new Integer[] {new Integer(intArray[0]), new Integer(intArray[1]), new Integer(intArray[2]), new Integer(intArray[3])}; 84 final ArrayList<String> strList = new ArrayList<String>(); 85 final ArrayList<Long> longList = new ArrayList<Long>(); 86 for (int i = 0; i < strArray.length; i++) { 87 strList.add(strArray[i]); 88 longList.add(LONGArray[i]); 89 } 90 91 92 String msg = null; 93 94 // String --> int[] 95 try { 96 msg = "String --> int[]"; 97 checkArray(msg, intArray, arrayConverter.convert(int[].class, stringA)); 98 } catch (final Exception e) { 99 fail(msg + " failed " + e); 100 } 101 102 // String --> int[] (with braces) 103 try { 104 msg = "String --> Integer[] (with braces)"; 105 checkArray(msg, IntegerArray, arrayConverter.convert(Integer[].class, "{" + stringA + "}")); 106 } catch (final Exception e) { 107 fail(msg + " failed " + e); 108 } 109 110 // String[] --> int[] 111 try { 112 msg = "String[] --> int[]"; 113 checkArray(msg, intArray, arrayConverter.convert(int[].class, strArray)); 114 } catch (final Exception e) { 115 fail(msg + " failed " + e); 116 } 117 118 // String[] --> Integer[] 119 try { 120 msg = "String[] --> Integer[]"; 121 checkArray(msg, IntegerArray, arrayConverter.convert(Integer[].class, strArray)); 122 } catch (final Exception e) { 123 fail(msg + " failed " + e); 124 } 125 126 // long[] --> int[] 127 try { 128 msg = "long[] --> int[]"; 129 checkArray(msg, intArray, arrayConverter.convert(int[].class, longArray)); 130 } catch (final Exception e) { 131 fail(msg + " failed " + e); 132 } 133 134 // Long --> int[] 135 try { 136 msg = "Long --> int[]"; 137 checkArray(msg, new int[] {LONGArray[0].intValue()}, arrayConverter.convert(int[].class, LONGArray[0])); 138 } catch (final Exception e) { 139 fail(msg + " failed " + e); 140 } 141 142 // LONG[] --> int[] 143 try { 144 msg = "LONG[] --> int[]"; 145 checkArray(msg, intArray, arrayConverter.convert(int[].class, LONGArray)); 146 } catch (final Exception e) { 147 fail(msg + " failed " + e); 148 } 149 150 // Long --> String 151 try { 152 msg = "Long --> String"; 153 assertEquals(msg, LONGArray[0] + "", arrayConverter.convert(String.class, LONGArray[0])); 154 } catch (final Exception e) { 155 fail(msg + " failed " + e); 156 } 157 158 // LONG[] --> String (first) 159 try { 160 msg = "LONG[] --> String (first)"; 161 assertEquals(msg, LONGArray[0] + "", arrayConverter.convert(String.class, LONGArray)); 162 } catch (final Exception e) { 163 fail(msg + " failed " + e); 164 } 165 166 // LONG[] --> String (all) 167 try { 168 msg = "LONG[] --> String (all)"; 169 arrayConverter.setOnlyFirstToString(false); 170 assertEquals(msg, stringB, arrayConverter.convert(String.class, LONGArray)); 171 } catch (final Exception e) { 172 fail(msg + " failed " + e); 173 } 174 175 // Collection of Long --> String 176 try { 177 msg = "Collection of Long --> String"; 178 assertEquals(msg, stringB, arrayConverter.convert(String.class, longList)); 179 } catch (final Exception e) { 180 fail(msg + " failed " + e); 181 } 182 183 // LONG[] --> String[] 184 try { 185 msg = "long[] --> String[]"; 186 checkArray(msg, strArray, arrayConverter.convert(String[].class, LONGArray)); 187 } catch (final Exception e) { 188 fail(msg + " failed " + e); 189 } 190 191 // Collection of String --> Integer[] 192 try { 193 msg = "Collection of String --> Integer[]"; 194 checkArray(msg, IntegerArray, arrayConverter.convert(Integer[].class, strList)); 195 } catch (final Exception e) { 196 fail(msg + " failed " + e); 197 } 198 199 // Collection of Long --> int[] 200 try { 201 msg = "Collection of Long --> int[]"; 202 checkArray(msg, intArray, arrayConverter.convert(int[].class, longList)); 203 } catch (final Exception e) { 204 fail(msg + " failed " + e); 205 } 206 } 207 208 /** 209 * Test Converting a String[] to integer array (with leading/trailing whitespace) 210 */ testStringArrayToNumber()211 public void testStringArrayToNumber() { 212 213 // Configure Converter 214 final IntegerConverter intConverter = new IntegerConverter(); 215 final ArrayConverter arrayConverter = new ArrayConverter(int[].class, intConverter); 216 217 // Test Data 218 final String[] array = new String[] {"10", " 11", "12 ", " 13 "}; 219 final ArrayList<String> list = new ArrayList<String>(); 220 for (String element : array) { 221 list.add(element); 222 } 223 224 // Expected results 225 String msg = null; 226 final int[] expectedInt = new int[] {10, 11, 12, 13}; 227 final Integer[] expectedInteger = new Integer[] {new Integer(expectedInt[0]), new Integer(expectedInt[1]), new Integer(expectedInt[2]), new Integer(expectedInt[3])}; 228 229 // Test String[] --> int[] 230 try { 231 msg = "String[] --> int[]"; 232 checkArray(msg, expectedInt, arrayConverter.convert(int[].class, array)); 233 } catch (final Exception e) { 234 fail(msg + " failed " + e); 235 } 236 237 // Test String[] --> Integer[] 238 try { 239 msg = "String[] --> Integer[]"; 240 checkArray(msg, expectedInteger, arrayConverter.convert(Integer[].class, array)); 241 } catch (final Exception e) { 242 fail(msg + " failed " + e); 243 } 244 245 // Test List --> int[] 246 try { 247 msg = "List --> int[]"; 248 checkArray(msg, expectedInt, arrayConverter.convert(int[].class, list)); 249 } catch (final Exception e) { 250 fail(msg + " failed " + e); 251 } 252 253 // Test List --> Integer[] 254 try { 255 msg = "List --> Integer[]"; 256 checkArray(msg, expectedInteger, arrayConverter.convert(Integer[].class, list)); 257 } catch (final Exception e) { 258 fail(msg + " failed " + e); 259 } 260 } 261 262 /** 263 * Test the Matrix!!!! (parses a String into a 2 dimensional integer array or matrix) 264 */ testTheMatrix()265 public void testTheMatrix() { 266 267 // Test Date - create the Matrix!! 268 // Following String uses two delimiter: 269 // - comma (",") to separate individual numbers 270 // - semi-colon (";") to separate lists of numbers 271 final String matrixString = "11,12,13 ; 21,22,23 ; 31,32,33 ; 41,42,43"; 272 final int[][] expected = new int[][] {new int[] {11, 12, 13}, 273 new int[] {21, 22, 23}, 274 new int[] {31, 32, 33}, 275 new int[] {41, 42, 43}}; 276 277 // Construct an Integer Converter 278 final IntegerConverter integerConverter = new IntegerConverter(); 279 280 // Construct an array Converter for an integer array (i.e. int[]) using 281 // an IntegerConverter as the element converter. 282 // N.B. Uses the default comma (i.e. ",") as the delimiter between individual numbers 283 final ArrayConverter arrayConverter = new ArrayConverter(int[].class, integerConverter); 284 285 // Construct a "Matrix" Converter which converts arrays of integer arrays using 286 // the first (int[]) Converter as the element Converter. 287 // N.B. Uses a semi-colon (i.e. ";") as the delimiter to separate the different sets of numbers. 288 // Also the delimiter for the above array Converter needs to be added to this 289 // array Converter's "allowed characters" 290 final ArrayConverter matrixConverter = new ArrayConverter(int[][].class, arrayConverter); 291 matrixConverter.setDelimiter(';'); 292 matrixConverter.setAllowedChars(new char[] {','}); 293 294 try { 295 // Do the Conversion 296 final Object result = matrixConverter.convert(int[][].class, matrixString); 297 298 // Check it actually worked OK 299 assertEquals("Check int[][].class", int[][].class, result.getClass()); 300 final int[][] matrix = (int[][])result; 301 assertEquals("Check int[][] length", expected.length, matrix.length); 302 for (int i = 0; i < expected.length; i++) { 303 assertEquals("Check int[" + i + "] length", expected[i].length, matrix[i].length); 304 for (int j = 0; j < expected[i].length; j++) { 305 final String label = "Matrix int[" + i + "," + j + "] element"; 306 assertEquals(label, expected[i][j], matrix[i][j]); 307 // System.out.println(label + " = " + matrix[i][j]); 308 } 309 } 310 } catch (final Exception e) { 311 fail("Matrix Conversion threw " + e); 312 } 313 } 314 315 /** 316 * Test Converting using the IntegerConverter as the component Converter 317 */ testInvalidWithDefault()318 public void testInvalidWithDefault() { 319 final int[] zeroArray = new int[0]; 320 final int[] oneArray = new int[1]; 321 final IntegerConverter intConverter = new IntegerConverter(); 322 323 assertEquals("Null Default", null, new ArrayConverter(int[].class, intConverter, -1).convert(int[].class, null)); 324 checkArray("Zero Length", zeroArray, new ArrayConverter(int[].class, intConverter, 0).convert(int[].class, null)); 325 checkArray("One Length", oneArray, new ArrayConverter(Integer[].class, intConverter, 1).convert(int[].class, null)); 326 } 327 328 /** 329 * Test Empty String 330 */ testEmptyString()331 public void testEmptyString() { 332 final int[] zeroArray = new int[0]; 333 final IntegerConverter intConverter = new IntegerConverter(); 334 335 checkArray("Empty String", zeroArray, new ArrayConverter(int[].class, intConverter, -1).convert(int[].class, "")); 336 assertEquals("Default String", null, new ArrayConverter(int[].class, intConverter).convert(String.class, null)); 337 } 338 339 /** 340 * Test Errors creating the converter 341 */ testErrors()342 public void testErrors() { 343 try { 344 new ArrayConverter(null, new DateConverter()); 345 fail("Default Type missing - expected IllegalArgumentException"); 346 } catch (final IllegalArgumentException e) { 347 // expected result 348 } 349 try { 350 new ArrayConverter(Boolean.class, new DateConverter()); 351 fail("Default Type not an array - expected IllegalArgumentException"); 352 } catch (final IllegalArgumentException e) { 353 // expected result 354 } 355 try { 356 new ArrayConverter(int[].class, null); 357 fail("Component Converter missing - expected IllegalArgumentException"); 358 } catch (final IllegalArgumentException e) { 359 // expected result 360 } 361 } 362 363 /** 364 * Test for BEANUTILS-302 - throwing a NPE when underscore used 365 */ testUnderscore_BEANUTILS_302()366 public void testUnderscore_BEANUTILS_302() { 367 final String value = "first_value,second_value"; 368 final ArrayConverter converter = new ArrayConverter(String[].class, new StringConverter()); 369 370 // test underscore not allowed (the default) 371 String[] result = converter.convert(String[].class, value); 372 assertNotNull("result.null", result); 373 assertEquals("result.length", 4, result.length); 374 assertEquals("result[0]", "first", result[0]); 375 assertEquals("result[1]", "value", result[1]); 376 assertEquals("result[2]", "second", result[2]); 377 assertEquals("result[3]", "value", result[3]); 378 379 // configure the converter to allow underscore 380 converter.setAllowedChars(new char[] {'.', '-', '_'}); 381 382 // test underscore allowed 383 result = converter.convert(String[].class, value); 384 assertNotNull("result.null", result); 385 assertEquals("result.length", 2, result.length); 386 assertEquals("result[0]", "first_value", result[0]); 387 assertEquals("result[1]", "second_value", result[1]); 388 } 389 390 /** 391 * Check that two arrays are the same. 392 * @param msg Test prefix msg 393 * @param expected Expected Array value 394 * @param result Result array value 395 */ checkArray(final String msg, final Object expected, final Object result)396 private void checkArray(final String msg, final Object expected, final Object result) { 397 assertNotNull(msg + " Expected Null", expected); 398 assertNotNull(msg + " Result Null", result); 399 assertTrue(msg + " Result not array", result.getClass().isArray()); 400 assertTrue(msg + " Expected not array", expected.getClass().isArray()); 401 final int resultLth = Array.getLength(result); 402 assertEquals(msg + " Size", Array.getLength(expected), resultLth); 403 assertEquals(msg + " Type", expected.getClass(), result.getClass()); 404 for (int i = 0; i < resultLth; i++) { 405 final Object expectElement = Array.get(expected, i); 406 final Object resultElement = Array.get(result, i); 407 assertEquals(msg + " Element " + i, expectElement, resultElement); 408 } 409 } 410 } 411