    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 org.apache.commons.beanutils.ConversionException;
    24
    25  import junit.framework.TestCase;
    26  import junit.framework.TestSuite;
    27
    28  /***
    29   * Test Case for the ArrayConverter class.
    30   *
    31   * @version $Revision: 539812 $ $Date: 2007-05-20 02:13:29 +0100 (Sun, 20 May 2007) $
    32   */
    33  public class ArrayConverterTestCase extends TestCase {
    34
    35      /***
    36       * Construct a new Array Converter test case.
    37       * @param name Test Name
    38       */
    39      public ArrayConverterTestCase(String name) {
    40          super(name);
    41      }
    42
    43      // ------------------------------------------------------------------------
    44
    45      /***
    46       * Create Test Suite
    47       * @return test suite
    48       */
    49      public static TestSuite suite() {
    50          return new TestSuite(ArrayConverterTestCase.class);
    51      }
    52
    53      /*** Set Up */
    54      public void setUp() throws Exception {
    55      }
    56
    57      /*** Tear Down */
    58      public void tearDown() throws Exception {
    59      }
    60
    61
    62      // ------------------------------------------------------------------------
    63
    64      /***
    65       * Test Converting using the IntegerConverter as the component Converter
    66       */
    67      public void testComponentIntegerConverter() {
    68
    69          IntegerConverter intConverter = new IntegerConverter(new Integer(0));
    70          intConverter.setPattern("#,###");
    71          intConverter.setLocale(Locale.US);
    72          ArrayConverter arrayConverter = new ArrayConverter(int[].class, intConverter, 0);
    73          arrayConverter.setAllowedChars(new char[] {',', '-'});
    74          arrayConverter.setDelimiter(';');
    75
    76          // Expected results
    77          int[]     intArray     = new int[] {1111, 2222, 3333, 4444};
    78          String    stringA      = "1,111; 2,222; 3,333; 4,444";
    79          String    stringB      = intArray[0]+ ";" + intArray[1] + ";" + intArray[2] + ";" +intArray[3];
    80          String[]  strArray     = new String[] {""+intArray[0], ""+intArray[1], ""+intArray[2], ""+intArray[3]};
    81          long[]    longArray    = new long[] {intArray[0], intArray[1], intArray[2], intArray[3]};
    82          Long[]    LONGArray    = new Long[]    {new Long(intArray[0]),    new Long(intArray[1]),    new Long(intArray[2]),    new Long(intArray[3])};
    83          Integer[] IntegerArray = new Integer[] {new Integer(intArray[0]), new Integer(intArray[1]), new Integer(intArray[2]), new Integer(intArray[3])};
    84          ArrayList strList = new ArrayList();
    85          ArrayList longList = new ArrayList();
    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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (Exception e) {
    204             fail(msg + " failed " + e);
    205         }
    206     }
    207
    208     /***
    209      * Test Converting a String[] to integer array (with leading/trailing whitespace)
    210      */
    211     public void testStringArrayToNumber() {
    212
    213         // Configure Converter
    214         IntegerConverter intConverter = new IntegerConverter();
    215         ArrayConverter arrayConverter = new ArrayConverter(int[].class, intConverter);
    216
    217         // Test Data
    218         String[] array = new String[] {"10", "  11", "12  ", "  13  "};
    219         ArrayList list = new ArrayList();
    220         for (int i = 0; i < array.length; i++) {
    221             list.add(array[i]);
    222         }
    223
    224         // Expected results
    225         String msg = null;
    226         int[]     expectedInt     = new int[] {10, 11, 12, 13};
    227         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 (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 (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 (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 (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      */
    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         String matrixString = "11,12,13 ; 21,22,23 ; 31,32,33 ; 41,42,43";
    272         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         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         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         ArrayConverter matrixConverter = new ArrayConverter(int[][].class, arrayConverter);
    291         matrixConverter.setDelimiter(';');
    292         matrixConverter.setAllowedChars(new char[] {','});
    293
    294         try {
    295             // Do the Conversion
    296             Object result = matrixConverter.convert(int[][].class, matrixString);
    297
    298             // Check it actually worked OK
    299             assertEquals("Check int[][].class", int[][].class, result.getClass());
    300             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                     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 (Exception e) {
    311             fail("Matrix Conversion threw " + e);
    312         }
    313     }
    314
    315     /***
    316      * Test Converting using the IntegerConverter as the component Converter
    317      */
    318     public void testInvalidWithDefault() {
    319         int[]  zeroArray  = new int[0];
    320         int[]  oneArray   = new int[1];
    321         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      */
    331     public void testEmptyString() {
    332         int[]  zeroArray  = new int[0];
    333         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      */
    342     public void testErrors() {
    343         try {
    344             new ArrayConverter(null, new DateConverter());
    345             fail("Default Type missing - expected IllegalArgumentException");
    346         } catch (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 (IllegalArgumentException e) {
    353             // expected result
    354         }
    355         try {
    356             new ArrayConverter(int[].class, null);
    357             fail("Component Converter missing - expected IllegalArgumentException");
    358         } catch (IllegalArgumentException e) {
    359             // expected result
    360         }
    361     }
    362
    363     /***
    364      * Check that two arrays are the same.
    365      * @param msg Test prefix msg
    366      * @param expected Expected Array value
    367      * @param result Result array value
    368      */
    369     private void checkArray(String msg, Object expected, Object result) {
    370         assertNotNull(msg + " Expected Null", expected);
    371         assertNotNull(msg + " Result   Null", result);
    372         assertTrue(msg + " Result   not array", result.getClass().isArray());
    373         assertTrue(msg + " Expected not array", expected.getClass().isArray());
    374         int resultLth = Array.getLength(result);
    375         assertEquals(msg + " Size", Array.getLength(expected), resultLth);
    376         assertEquals(msg + " Type", expected.getClass(), result.getClass());
    377         for (int i = 0; i < resultLth; i++) {
    378             Object expectElement = Array.get(expected, i);
    379             Object resultElement = Array.get(result, i);
    380             assertEquals(msg + " Element " + i, expectElement, resultElement);
    381         }
    382     }
    383 }