    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.beanutils;
    19
    20
    21  import java.lang.reflect.InvocationTargetException;
    22  import java.util.Calendar;
    23  import java.util.HashMap;
    24  import java.util.Iterator;
    25  import java.util.Locale;
    26  import java.util.Map;
    27  import java.util.StringTokenizer;
    28
    29  import org.apache.commons.beanutils.converters.ArrayConverter;
    30  import org.apache.commons.beanutils.converters.DateConverter;
    31
    32  import junit.framework.Test;
    33  import junit.framework.TestCase;
    34  import junit.framework.TestSuite;
    35
    36
    37  /***
    38   * <p>
    39   *  Test Case for the BeanUtils class.  The majority of these tests use
    40   *  instances of the TestBean class, so be sure to update the tests if you
    41   *  change the characteristics of that class.
    42   * </p>
    43   *
    44   * <p>
    45   *  Template for this stolen from Craigs PropertyUtilsTestCase
    46   * </p>
    47   *
    48   * <p>
    49   *   Note that the tests are dependant upon the static aspects
    50   *   (such as array sizes...) of the TestBean.java class, so ensure
    51   *   than all changes to TestBean are reflected here.
    52   * </p>
    53   *
    54   * <p>
    55   *  So far, this test case has tests for the following methods of the
    56   *  <code>BeanUtils</code> class:
    57   * </p>
    58   * <ul>
    59   *   <li>getArrayProperty(Object bean, String name)</li>
    60   * </ul>
    61   *
    62   * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
    63   * @version $Revision: 552381 $
    64   */
    65
    66  public class BeanUtilsTestCase extends TestCase {
    67
    68      // ---------------------------------------------------- Instance Variables
    69
    70      /***
    71       * The test bean for each test.
    72       */
    73      protected TestBean bean = null;
    74
    75
    76      /***
    77       * The set of properties that should be described.
    78       */
    79      protected String describes[] =
    80      { "booleanProperty",
    81        "booleanSecond",
    82        "byteProperty",
    83        "doubleProperty",
    84        "dupProperty",
    85        "floatProperty",
    86        "intArray",
    87        //      "intIndexed",
    88        "longProperty",
    89        "listIndexed",
    90        "longProperty",
    91        //      "mappedProperty",
    92        //      "mappedIntProperty",
    93        "nested",
    94        "nullProperty",
    95        "readOnlyProperty",
    96        "shortProperty",
    97        "stringArray",
    98        //      "stringIndexed",
    99        "stringProperty"
    100     };
    101
    102     /*** Test Calendar value */
    103     protected java.util.Calendar testCalendar;
    104
    105     /*** Test java.util.Date value */
    106     protected java.util.Date testUtilDate;
    107
    108     /*** Test String Date value */
    109     protected String testStringDate;
    110
    111     // ---------------------------------------------------------- Constructors
    112
    113     /***
    114      * Construct a new instance of this test case.
    115      *
    116      * @param name Name of the test case
    117      */
    118     public BeanUtilsTestCase(String name) {
    119         super(name);
    120     }
    121
    122
    123     // -------------------------------------------------- Overall Test Methods
    124
    125
    126     /***
    127      * Set up instance variables required by this test case.
    128      */
    129     public void setUp() {
    130         ConvertUtils.deregister();
    131         BeanUtilsBean.setInstance(new BeanUtilsBean());
    132         setUpShared();
    133     }
    134
    135     /***
    136      * Shared Set up.
    137      */
    138     protected void setUpShared() {
    139         bean = new TestBean();
    140
    141         DateConverter dateConverter = new DateConverter(null);
    142         dateConverter.setLocale(Locale.US);
    143         dateConverter.setPattern("dd.MM.yyyy");
    144         ConvertUtils.register(dateConverter, java.util.Date.class);
    145
    146         ArrayConverter dateArrayConverter =
    147             new ArrayConverter(java.util.Date[].class, dateConverter, 0);
    148         ConvertUtils.register(dateArrayConverter, java.util.Date[].class);
    149
    150         testCalendar = Calendar.getInstance();
    151         testCalendar.set(1992, 11, 28, 0, 0, 0);
    152         testCalendar.set(Calendar.MILLISECOND, 0);
    153         testUtilDate = testCalendar.getTime();
    154         testStringDate = "28.12.1992";
    155     }
    156
    157
    158     /***
    159      * Return the tests included in this test suite.
    160      */
    161     public static Test suite() {
    162         return (new TestSuite(BeanUtilsTestCase.class));
    163     }
    164
    165     /***
    166      * Tear down instance variables required by this test case.
    167      */
    168     public void tearDown() {
    169         bean = null;
    170     }
    171
    172
    173     // ------------------------------------------------ Individual Test Methods
    174
    175
    176     /***
    177      * Test the copyProperties() method from a DynaBean.
    178      */
    179     public void testCopyPropertiesDynaBean() {
    180
    181         // Set up an origin bean with customized properties
    182         DynaClass dynaClass = DynaBeanUtilsTestCase.createDynaClass();
    183         DynaBean orig = null;
    184         try {
    185             orig = dynaClass.newInstance();
    186         } catch (Exception e) {
    187             fail("newInstance(): " + e);
    188         }
    189         orig.set("booleanProperty", Boolean.FALSE);
    190         orig.set("byteProperty", new Byte((byte) 111));
    191         orig.set("doubleProperty", new Double(333.33));
    192         orig.set("dupProperty",
    193                  new String[] { "New 0", "New 1", "New 2" });
    194         orig.set("intArray", new int[] { 100, 200, 300 });
    195         orig.set("intProperty", new Integer(333));
    196         orig.set("longProperty", new Long(3333));
    197         orig.set("shortProperty", new Short((short) 33));
    198         orig.set("stringArray", new String[] { "New 0", "New 1" });
    199         orig.set("stringProperty", "Custom string");
    200
    201         // Copy the origin bean to our destination test bean
    202         try {
    203             BeanUtils.copyProperties(bean, orig);
    204         } catch (Exception e) {
    205             fail("Threw exception: " + e);
    206         }
    207
    208         // Validate the results for scalar properties
    209         assertEquals("Copied boolean property",
    210                      false,
    211                      bean.getBooleanProperty());
    212         assertEquals("Copied byte property",
    213                      (byte) 111,
    214                      bean.getByteProperty());
    215         assertEquals("Copied double property",
    216                      333.33,
    217                      bean.getDoubleProperty(),
    218                      0.005);
    219         assertEquals("Copied int property",
    220                      333,
    221                      bean.getIntProperty());
    222         assertEquals("Copied long property",
    223                      3333,
    224                      bean.getLongProperty());
    225         assertEquals("Copied short property",
    226                      (short) 33,
    227                      bean.getShortProperty());
    228         assertEquals("Copied string property",
    229                      "Custom string",
    230                      bean.getStringProperty());
    231
    232         // Validate the results for array properties
    233         String dupProperty[] = bean.getDupProperty();
    234         assertNotNull("dupProperty present", dupProperty);
    235         assertEquals("dupProperty length", 3, dupProperty.length);
    236         assertEquals("dupProperty[0]", "New 0", dupProperty[0]);
    237         assertEquals("dupProperty[1]", "New 1", dupProperty[1]);
    238         assertEquals("dupProperty[2]", "New 2", dupProperty[2]);
    239         int intArray[] = bean.getIntArray();
    240         assertNotNull("intArray present", intArray);
    241         assertEquals("intArray length", 3, intArray.length);
    242         assertEquals("intArray[0]", 100, intArray[0]);
    243         assertEquals("intArray[1]", 200, intArray[1]);
    244         assertEquals("intArray[2]", 300, intArray[2]);
    245         String stringArray[] = bean.getStringArray();
    246         assertNotNull("stringArray present", stringArray);
    247         assertEquals("stringArray length", 2, stringArray.length);
    248         assertEquals("stringArray[0]", "New 0", stringArray[0]);
    249         assertEquals("stringArray[1]", "New 1", stringArray[1]);
    250
    251     }
    252
    253
    254     /***
    255      * Test copyProperties() when the origin is a a <code>Map</code>.
    256      */
    257     public void testCopyPropertiesMap() {
    258
    259         Map map = new HashMap();
    260         map.put("booleanProperty", "false");
    261         map.put("byteProperty", "111");
    262         map.put("doubleProperty", "333.0");
    263         map.put("dupProperty", new String[] { "New 0", "New 1", "New 2" });
    264         map.put("floatProperty", "222.0");
    265         map.put("intArray", new String[] { "0", "100", "200" });
    266         map.put("intProperty", "111");
    267         map.put("longProperty", "444");
    268         map.put("shortProperty", "555");
    269         map.put("stringProperty", "New String Property");
    270
    271         try {
    272             BeanUtils.copyProperties(bean, map);
    273         } catch (Throwable t) {
    274             fail("Threw " + t.toString());
    275         }
    276
    277         // Scalar properties
    278         assertEquals("booleanProperty", false,
    279                      bean.getBooleanProperty());
    280         assertEquals("byteProperty", (byte) 111,
    281                      bean.getByteProperty());
    282         assertEquals("doubleProperty", 333.0,
    283                      bean.getDoubleProperty(), 0.005);
    284         assertEquals("floatProperty", (float) 222.0,
    285                      bean.getFloatProperty(), (float) 0.005);
    286         assertEquals("longProperty", 111,
    287                      bean.getIntProperty());
    288         assertEquals("longProperty", 444,
    289                      bean.getLongProperty());
    290         assertEquals("shortProperty", (short) 555,
    291                      bean.getShortProperty());
    292         assertEquals("stringProperty", "New String Property",
    293                      bean.getStringProperty());
    294
    295         // Indexed Properties
    296         String dupProperty[] = bean.getDupProperty();
    297         assertNotNull("dupProperty present", dupProperty);
    298         assertEquals("dupProperty length", 3, dupProperty.length);
    299         assertEquals("dupProperty[0]", "New 0", dupProperty[0]);
    300         assertEquals("dupProperty[1]", "New 1", dupProperty[1]);
    301         assertEquals("dupProperty[2]", "New 2", dupProperty[2]);
    302         int intArray[] = bean.getIntArray();
    303         assertNotNull("intArray present", intArray);
    304         assertEquals("intArray length", 3, intArray.length);
    305         assertEquals("intArray[0]", 0, intArray[0]);
    306         assertEquals("intArray[1]", 100, intArray[1]);
    307         assertEquals("intArray[2]", 200, intArray[2]);
    308
    309     }
    310
    311
    312     /***
    313      * Test the copyProperties() method from a standard JavaBean.
    314      */
    315     public void testCopyPropertiesStandard() {
    316
    317         // Set up an origin bean with customized properties
    318         TestBean orig = new TestBean();
    319         orig.setBooleanProperty(false);
    320         orig.setByteProperty((byte) 111);
    321         orig.setDoubleProperty(333.33);
    322         orig.setDupProperty(new String[] { "New 0", "New 1", "New 2" });
    323         orig.setIntArray(new int[] { 100, 200, 300 });
    324         orig.setIntProperty(333);
    325         orig.setLongProperty(3333);
    326         orig.setShortProperty((short) 33);
    327         orig.setStringArray(new String[] { "New 0", "New 1" });
    328         orig.setStringProperty("Custom string");
    329
    330         // Copy the origin bean to our destination test bean
    331         try {
    332             BeanUtils.copyProperties(bean, orig);
    333         } catch (Exception e) {
    334             fail("Threw exception: " + e);
    335         }
    336
    337         // Validate the results for scalar properties
    338         assertEquals("Copied boolean property",
    339                      false,
    340                      bean.getBooleanProperty());
    341         assertEquals("Copied byte property",
    342                      (byte) 111,
    343                      bean.getByteProperty());
    344         assertEquals("Copied double property",
    345                      333.33,
    346                      bean.getDoubleProperty(),
    347                      0.005);
    348         assertEquals("Copied int property",
    349                      333,
    350                      bean.getIntProperty());
    351         assertEquals("Copied long property",
    352                      3333,
    353                      bean.getLongProperty());
    354         assertEquals("Copied short property",
    355                      (short) 33,
    356                      bean.getShortProperty());
    357         assertEquals("Copied string property",
    358                      "Custom string",
    359                      bean.getStringProperty());
    360
    361         // Validate the results for array properties
    362         String dupProperty[] = bean.getDupProperty();
    363         assertNotNull("dupProperty present", dupProperty);
    364         assertEquals("dupProperty length", 3, dupProperty.length);
    365         assertEquals("dupProperty[0]", "New 0", dupProperty[0]);
    366         assertEquals("dupProperty[1]", "New 1", dupProperty[1]);
    367         assertEquals("dupProperty[2]", "New 2", dupProperty[2]);
    368         int intArray[] = bean.getIntArray();
    369         assertNotNull("intArray present", intArray);
    370         assertEquals("intArray length", 3, intArray.length);
    371         assertEquals("intArray[0]", 100, intArray[0]);
    372         assertEquals("intArray[1]", 200, intArray[1]);
    373         assertEquals("intArray[2]", 300, intArray[2]);
    374         String stringArray[] = bean.getStringArray();
    375         assertNotNull("stringArray present", stringArray);
    376         assertEquals("stringArray length", 2, stringArray.length);
    377         assertEquals("stringArray[0]", "New 0", stringArray[0]);
    378         assertEquals("stringArray[1]", "New 1", stringArray[1]);
    379
    380     }
    381
    382
    383     /***
    384      * Test the describe() method.
    385      */
    386     public void testDescribe() {
    387
    388         Map map = null;
    389         try {
    390             map = BeanUtils.describe(bean);
    391         } catch (Exception e) {
    392             fail("Threw exception " + e);
    393         }
    394
    395         // Verify existence of all the properties that should be present
    396         for (int i = 0; i < describes.length; i++) {
    397             assertTrue("Property '" + describes[i] + "' is present",
    398                        map.containsKey(describes[i]));
    399         }
    400         assertTrue("Property 'writeOnlyProperty' is not present",
    401                    !map.containsKey("writeOnlyProperty"));
    402
    403         // Verify the values of scalar properties
    404         assertEquals("Value of 'booleanProperty'",
    405                      "true",
    406                      (String) map.get("booleanProperty"));
    407         assertEquals("Value of 'byteProperty'",
    408                      "121",
    409                      (String) map.get("byteProperty"));
    410         assertEquals("Value of 'doubleProperty'",
    411                      "321.0",
    412                      (String) map.get("doubleProperty"));
    413         assertEquals("Value of 'floatProperty'",
    414                      "123.0",
    415                      (String) map.get("floatProperty"));
    416         assertEquals("Value of 'intProperty'",
    417                      "123",
    418                      (String) map.get("intProperty"));
    419         assertEquals("Value of 'longProperty'",
    420                      "321",
    421                      (String) map.get("longProperty"));
    422         assertEquals("Value of 'shortProperty'",
    423                      "987",
    424                      (String) map.get("shortProperty"));
    425         assertEquals("Value of 'stringProperty'",
    426                      "This is a string",
    427                      (String) map.get("stringProperty"));
    428
    429     }
    430
    431
    432     /***
    433      *  tests the string and int arrays of TestBean
    434      */
    435     public void testGetArrayProperty() {
    436         try {
    437             String arr[] = BeanUtils.getArrayProperty(bean, "stringArray");
    438             String comp[] = bean.getStringArray();
    439
    440             assertTrue("String array length = " + comp.length,
    441                     (comp.length == arr.length));
    442
    443             arr = BeanUtils.getArrayProperty(bean, "intArray");
    444             int iarr[] = bean.getIntArray();
    445
    446             assertTrue("String array length = " + iarr.length,
    447                     (iarr.length == arr.length));
    448
    449
    450             // Test property which isn't array or collection
    451             arr = BeanUtils.getArrayProperty(bean, "shortProperty");
    452             String shortAsString = "" + bean.getShortProperty();
    453             assertEquals("Short List Test lth", 1, arr.length);
    454             assertEquals("Short Test value", shortAsString, arr[0]);
    455
    456
    457             // Test comma delimited list
    458             String value1 = "ABC";
    459             bean.setStringProperty("ABC");
    460             arr = BeanUtils.getArrayProperty(bean, "stringProperty");
    461             assertEquals("Delimited List Test lth", 1, arr.length);
    462             assertEquals("Delimited List Test value1", "ABC", arr[0]);
    463
    464         } catch (IllegalAccessException e) {
    465             fail("IllegalAccessException");
    466         } catch (InvocationTargetException e) {
    467             fail("InvocationTargetException");
    468         } catch (NoSuchMethodException e) {
    469             fail("NoSuchMethodException");
    470         }
    471
    472     }
    473
    474     /***
    475      * Test <code>getArrayProperty()</code> converting to a String.
    476      */
    477     public void testGetArrayPropertyDate() {
    478         String[] value = null;
    479         try {
    480             bean.setDateArrayProperty(new java.util.Date[] {testUtilDate});
    481             value = BeanUtils.getArrayProperty(bean, "dateArrayProperty");
    482         } catch (Throwable t) {
    483             fail("Threw " + t);
    484         }
    485         assertEquals("java.util.Date[] --> String[] length", 1, value.length);
    486         assertEquals("java.util.Date[] --> String[] value ", testUtilDate.toString(), value[0]);
    487     }
    488
    489     /***
    490      *  tests getting an indexed property
    491      */
    492     public void testGetIndexedProperty1() {
    493         try {
    494             String val = BeanUtils.getIndexedProperty(bean, "intIndexed[3]");
    495             String comp = String.valueOf(bean.getIntIndexed(3));
    496             assertTrue("intIndexed[3] == " + comp, val.equals(comp));
    497
    498             val = BeanUtils.getIndexedProperty(bean, "stringIndexed[3]");
    499             comp = bean.getStringIndexed(3);
    500             assertTrue("stringIndexed[3] == " + comp, val.equals(comp));
    501         } catch (IllegalAccessException e) {
    502             fail("IllegalAccessException");
    503         } catch (InvocationTargetException e) {
    504             fail("InvocationTargetException");
    505         } catch (NoSuchMethodException e) {
    506             fail("NoSuchMethodException");
    507         }
    508     }
    509
    510     /***
    511      * Test <code>getArrayProperty()</code> converting to a String.
    512      */
    513     public void testGetIndexedPropertyDate() {
    514         String value = null;
    515         try {
    516             bean.setDateArrayProperty(new java.util.Date[] {testUtilDate});
    517             value = BeanUtils.getIndexedProperty(bean, "dateArrayProperty[0]");
    518         } catch (Throwable t) {
    519             fail("Threw " + t);
    520         }
    521         assertEquals("java.util.Date[0] --> String", testUtilDate.toString(), value);
    522     }
    523
    524     /***
    525      *  tests getting an indexed property
    526      */
    527     public void testGetIndexedProperty2() {
    528         try {
    529             String val = BeanUtils.getIndexedProperty(bean, "intIndexed", 3);
    530             String comp = String.valueOf(bean.getIntIndexed(3));
    531
    532             assertTrue("intIndexed,3 == " + comp, val.equals(comp));
    533
    534             val = BeanUtils.getIndexedProperty(bean, "stringIndexed", 3);
    535             comp = bean.getStringIndexed(3);
    536
    537             assertTrue("stringIndexed,3 == " + comp, val.equals(comp));
    538
    539         } catch (IllegalAccessException e) {
    540             fail("IllegalAccessException");
    541         } catch (InvocationTargetException e) {
    542             fail("InvocationTargetException");
    543         } catch (NoSuchMethodException e) {
    544             fail("NoSuchMethodException");
    545         }
    546     }
    547
    548
    549     /***
    550      *  tests getting a nested property
    551      */
    552     public void testGetNestedProperty() {
    553         try {
    554             String val = BeanUtils.getNestedProperty(bean, "nested.stringProperty");
    555             String comp = bean.getNested().getStringProperty();
    556             assertTrue("nested.StringProperty == " + comp,
    557                     val.equals(comp));
    558         } catch (IllegalAccessException e) {
    559             fail("IllegalAccessException");
    560         } catch (InvocationTargetException e) {
    561             fail("InvocationTargetException");
    562         } catch (NoSuchMethodException e) {
    563             fail("NoSuchMethodException");
    564         }
    565     }
    566
    567
    568     /***
    569      *  tests getting a 'whatever' property
    570      */
    571     public void testGetGeneralProperty() {
    572         try {
    573             String val = BeanUtils.getProperty(bean, "nested.intIndexed[2]");
    574             String comp = String.valueOf(bean.getIntIndexed(2));
    575
    576             assertTrue("nested.intIndexed[2] == " + comp,
    577                     val.equals(comp));
    578         } catch (IllegalAccessException e) {
    579             fail("IllegalAccessException");
    580         } catch (InvocationTargetException e) {
    581             fail("InvocationTargetException");
    582         } catch (NoSuchMethodException e) {
    583             fail("NoSuchMethodException");
    584         }
    585     }
    586
    587
    588     /***
    589      *  tests getting a 'whatever' property
    590      */
    591     public void testGetSimpleProperty() {
    592         try {
    593             String val = BeanUtils.getSimpleProperty(bean, "shortProperty");
    594             String comp = String.valueOf(bean.getShortProperty());
    595
    596             assertTrue("shortProperty == " + comp,
    597                     val.equals(comp));
    598         } catch (IllegalAccessException e) {
    599             fail("IllegalAccessException");
    600         } catch (InvocationTargetException e) {
    601             fail("InvocationTargetException");
    602         } catch (NoSuchMethodException e) {
    603             fail("NoSuchMethodException");
    604         }
    605     }
    606
    607     /***
    608      * Test <code>getSimpleProperty()</code> converting to a String.
    609      */
    610     public void testGetSimplePropertyDate() {
    611         String value = null;
    612         try {
    613             bean.setDateProperty(testUtilDate);
    614             value = BeanUtils.getSimpleProperty(bean, "dateProperty");
    615         } catch (Throwable t) {
    616             fail("Threw " + t);
    617         }
    618         assertEquals("java.util.Date --> String", testUtilDate.toString(), value);
    619     }
    620
    621     /***
    622      * Test populate() method on individual array elements.
    623      */
    624     public void testPopulateArrayElements() {
    625
    626         try {
    627
    628             HashMap map = new HashMap();
    629             map.put("intIndexed[0]", "100");
    630             map.put("intIndexed[2]", "120");
    631             map.put("intIndexed[4]", "140");
    632
    633             BeanUtils.populate(bean, map);
    634
    635             assertEquals("intIndexed[0] is 100",
    636                          100, bean.getIntIndexed(0));
    637             assertEquals("intIndexed[1] is 10",
    638                          10, bean.getIntIndexed(1));
    639             assertEquals("intIndexed[2] is 120",
    640                          120, bean.getIntIndexed(2));
    641             assertEquals("intIndexed[3] is 30",
    642                          30, bean.getIntIndexed(3));
    643             assertEquals("intIndexed[4] is 140",
    644                          140, bean.getIntIndexed(4));
    645
    646             map.clear();
    647             map.put("stringIndexed[1]", "New String 1");
    648             map.put("stringIndexed[3]", "New String 3");
    649
    650             BeanUtils.populate(bean, map);
    651
    652             assertEquals("stringIndexed[0] is \"String 0\"",
    653                          "String 0", bean.getStringIndexed(0));
    654             assertEquals("stringIndexed[1] is \"New String 1\"",
    655                          "New String 1", bean.getStringIndexed(1));
    656             assertEquals("stringIndexed[2] is \"String 2\"",
    657                          "String 2", bean.getStringIndexed(2));
    658             assertEquals("stringIndexed[3] is \"New String 3\"",
    659                          "New String 3", bean.getStringIndexed(3));
    660             assertEquals("stringIndexed[4] is \"String 4\"",
    661                          "String 4", bean.getStringIndexed(4));
    662
    663         } catch (IllegalAccessException e) {
    664             fail("IllegalAccessException");
    665         } catch (InvocationTargetException e) {
    666             fail("InvocationTargetException");
    667         }
    668
    669     }
    670
    671
    672     /***
    673      * Test populate() method on array properties as a whole.
    674      */
    675     public void testPopulateArrayProperties() {
    676
    677         try {
    678
    679             HashMap map = new HashMap();
    680             int intArray[] = new int[] { 123, 456, 789 };
    681             map.put("intArray", intArray);
    682             String stringArray[] = new String[]
    683                 { "New String 0", "New String 1" };
    684             map.put("stringArray", stringArray);
    685
    686             BeanUtils.populate(bean, map);
    687
    688             intArray = bean.getIntArray();
    689             assertNotNull("intArray is present", intArray);
    690             assertEquals("intArray length",
    691                          3, intArray.length);
    692             assertEquals("intArray[0]", 123, intArray[0]);
    693             assertEquals("intArray[1]", 456, intArray[1]);
    694             assertEquals("intArray[2]", 789, intArray[2]);
    695             stringArray = bean.getStringArray();
    696             assertNotNull("stringArray is present", stringArray);
    697             assertEquals("stringArray length", 2, stringArray.length);
    698             assertEquals("stringArray[0]", "New String 0", stringArray[0]);
    699             assertEquals("stringArray[1]", "New String 1", stringArray[1]);
    700
    701         } catch (IllegalAccessException e) {
    702             fail("IllegalAccessException");
    703         } catch (InvocationTargetException e) {
    704             fail("InvocationTargetException");
    705         }
    706
    707     }
    708
    709
    710     /***
    711      * Test populate() on mapped properties.
    712      */
    713     public void testPopulateMapped() {
    714
    715         try {
    716
    717             HashMap map = new HashMap();
    718             map.put("mappedProperty(First Key)", "New First Value");
    719             map.put("mappedProperty(Third Key)", "New Third Value");
    720
    721             BeanUtils.populate(bean, map);
    722
    723             assertEquals("mappedProperty(First Key)",
    724                          "New First Value",
    725                          bean.getMappedProperty("First Key"));
    726             assertEquals("mappedProperty(Second Key)",
    727                          "Second Value",
    728                          bean.getMappedProperty("Second Key"));
    729             assertEquals("mappedProperty(Third Key)",
    730                          "New Third Value",
    731                          bean.getMappedProperty("Third Key"));
    732             assertNull("mappedProperty(Fourth Key",
    733                        bean.getMappedProperty("Fourth Key"));
    734
    735         } catch (IllegalAccessException e) {
    736             fail("IllegalAccessException");
    737         } catch (InvocationTargetException e) {
    738             fail("InvocationTargetException");
    739         }
    740
    741     }
    742
    743
    744     /***
    745      * Test populate() method on nested properties.
    746      */
    747     public void testPopulateNested() {
    748
    749         try {
    750
    751             HashMap map = new HashMap();
    752             map.put("nested.booleanProperty", "false");
    753             // booleanSecond is left at true
    754             map.put("nested.doubleProperty", "432.0");
    755             // floatProperty is left at 123.0
    756             map.put("nested.intProperty", "543");
    757             // longProperty is left at 321
    758             map.put("nested.shortProperty", "654");
    759             // stringProperty is left at "This is a string"
    760             map.put("nested.writeOnlyProperty", "New writeOnlyProperty value");
    761
    762             BeanUtils.populate(bean, map);
    763
    764             assertTrue("booleanProperty is false",
    765                        !bean.getNested().getBooleanProperty());
    766             assertTrue("booleanSecond is true",
    767                        bean.getNested().isBooleanSecond());
    768             assertEquals("doubleProperty is 432.0",
    769                          432.0,
    770                          bean.getNested().getDoubleProperty(),
    771                          0.005);
    772             assertEquals("floatProperty is 123.0",
    773                          (float) 123.0,
    774                          bean.getNested().getFloatProperty(),
    775                          (float) 0.005);
    776             assertEquals("intProperty is 543",
    777                          543, bean.getNested().getIntProperty());
    778             assertEquals("longProperty is 321",
    779                          321, bean.getNested().getLongProperty());
    780             assertEquals("shortProperty is 654",
    781                          (short) 654, bean.getNested().getShortProperty());
    782             assertEquals("stringProperty is \"This is a string\"",
    783                          "This is a string",
    784                          bean.getNested().getStringProperty());
    785             assertEquals("writeOnlyProperty is \"New writeOnlyProperty value\"",
    786                          "New writeOnlyProperty value",
    787                          bean.getNested().getWriteOnlyPropertyValue());
    788
    789         } catch (IllegalAccessException e) {
    790             fail("IllegalAccessException");
    791         } catch (InvocationTargetException e) {
    792             fail("InvocationTargetException");
    793         }
    794
    795     }
    796
    797
    798     /***
    799      * Test populate() method on scalar properties.
    800      */
    801     public void testPopulateScalar() {
    802
    803         try {
    804
    805             bean.setNullProperty("Non-null value");
    806
    807             HashMap map = new HashMap();
    808             map.put("booleanProperty", "false");
    809             // booleanSecond is left at true
    810             map.put("byteProperty", "111");
    811             map.put("doubleProperty", "432.0");
    812             // floatProperty is left at 123.0
    813             map.put("intProperty", "543");
    814             map.put("longProperty", "");
    815             map.put("nullProperty", null);
    816             map.put("shortProperty", "654");
    817             // stringProperty is left at "This is a string"
    818             map.put("writeOnlyProperty", "New writeOnlyProperty value");
    819             map.put("readOnlyProperty", "New readOnlyProperty value");
    820
    821             BeanUtils.populate(bean, map);
    822
    823             assertTrue("booleanProperty is false", !bean.getBooleanProperty());
    824             assertTrue("booleanSecond is true", bean.isBooleanSecond());
    825             assertEquals("byteProperty is 111",
    826                          (byte) 111, bean.getByteProperty());
    827             assertEquals("doubleProperty is 432.0",
    828                          432.0, bean.getDoubleProperty(),
    829                          0.005);
    830             assertEquals("floatProperty is 123.0",
    831                          (float) 123.0, bean.getFloatProperty(),
    832                          (float) 0.005);
    833             assertEquals("intProperty is 543",
    834                          543, bean.getIntProperty());
    835             assertEquals("longProperty is 0",
    836                          0, bean.getLongProperty());
    837             assertNull("nullProperty is null",
    838                        bean.getNullProperty());
    839             assertEquals("shortProperty is 654",
    840                          (short) 654, bean.getShortProperty());
    841             assertEquals("stringProperty is \"This is a string\"",
    842                          "This is a string", bean.getStringProperty());
    843             assertEquals("writeOnlyProperty is \"New writeOnlyProperty value\"",
    844                          "New writeOnlyProperty value",
    845                          bean.getWriteOnlyPropertyValue());
    846             assertEquals("readOnlyProperty is \"Read Only String Property\"",
    847                          "Read Only String Property",
    848                          bean.getReadOnlyProperty());
    849
    850         } catch (IllegalAccessException e) {
    851             fail("IllegalAccessException");
    852         } catch (InvocationTargetException e) {
    853             fail("InvocationTargetException");
    854         }
    855
    856     }
    857
    858
    859     /***
    860      * Test calling setProperty() with null property values.
    861      */
    862     public void testSetPropertyNullValues() throws Exception {
    863
    864         Object oldValue = null;
    865         Object newValue = null;
    866
    867         // Scalar value into array
    868         oldValue = PropertyUtils.getSimpleProperty(bean, "stringArray");
    869         BeanUtils.setProperty(bean, "stringArray", (String) null);
    870         newValue = PropertyUtils.getSimpleProperty(bean, "stringArray");
    871         assertNotNull("stringArray is not null", newValue);
    872         assertTrue("stringArray of correct type",
    873                    newValue instanceof String[]);
    874         assertEquals("stringArray length",
    875                      1, ((String[]) newValue).length);
    876         PropertyUtils.setProperty(bean, "stringArray", oldValue);
    877
    878         // Indexed value into array
    879         oldValue = PropertyUtils.getSimpleProperty(bean, "stringArray");
    880         BeanUtils.setProperty(bean, "stringArray[2]", (String) null);
    881         newValue = PropertyUtils.getSimpleProperty(bean, "stringArray");
    882         assertNotNull("stringArray is not null", newValue);
    883         assertTrue("stringArray of correct type",
    884                    newValue instanceof String[]);
    885         assertEquals("stringArray length",
    886                      5, ((String[]) newValue).length);
    887         assertTrue("stringArray[2] is null",
    888                    ((String[]) newValue)[2] == null);
    889         PropertyUtils.setProperty(bean, "stringArray", oldValue);
    890
    891         // Value into scalar
    892         BeanUtils.setProperty(bean, "stringProperty", null);
    893         assertTrue("stringProperty is now null",
    894                    BeanUtils.getProperty(bean, "stringProperty") == null);
    895
    896     }
    897
    898
    899     /***
    900      * Test converting to and from primitive wrapper types.
    901      */
    902     public void testSetPropertyOnPrimitiveWrappers() throws Exception {
    903
    904         BeanUtils.setProperty(bean,"intProperty", new Integer(1));
    905         assertEquals(1,bean.getIntProperty());
    906         BeanUtils.setProperty(bean,"stringProperty", new Integer(1));
    907         assertEquals(1, Integer.parseInt(bean.getStringProperty()));
    908
    909     }
    910
    911
    912     /***
    913      * Test narrowing and widening conversions on byte.
    914      */
    915     public void testSetPropertyByte() throws Exception {
    916
    917         BeanUtils.setProperty(bean, "byteProperty", new Byte((byte) 123));
    918         assertEquals((byte) 123, bean.getByteProperty());
    919 /*
    920         BeanUtils.setProperty(bean, "byteProperty", new Double((double) 123));
    921         assertEquals((byte) 123, bean.getByteProperty());
    922         BeanUtils.setProperty(bean, "byteProperty", new Float((float) 123));
    923         assertEquals((byte) 123, bean.getByteProperty());
    924 */
    925         BeanUtils.setProperty(bean, "byteProperty", new Integer(123));
    926         assertEquals((byte) 123, bean.getByteProperty());
    927         BeanUtils.setProperty(bean, "byteProperty", new Long(123));
    928         assertEquals((byte) 123, bean.getByteProperty());
    929         BeanUtils.setProperty(bean, "byteProperty", new Short((short) 123));
    930         assertEquals((byte) 123, bean.getByteProperty());
    931
    932     }
    933
    934     /***
    935      * Test <code>setProperty()</code> conversion.
    936      */
    937     public void testSetPropertyConvert() {
    938         try {
    939             BeanUtils.setProperty(bean, "dateProperty", testCalendar);
    940         } catch (Throwable t) {
    941             fail("Threw " + t);
    942         }
    943         assertEquals("Calendar --> java.util.Date", testUtilDate, bean.getDateProperty());
    944     }
    945
    946     /***
    947      * Test <code>setProperty()</code> converting from a String.
    948      */
    949     public void testSetPropertyConvertFromString() {
    950         try {
    951             BeanUtils.setProperty(bean, "dateProperty", testStringDate);
    952         } catch (Throwable t) {
    953             fail("Threw " + t);
    954         }
    955         assertEquals("String --> java.util.Date", testUtilDate, bean.getDateProperty());
    956     }
    957
    958     /***
    959      * Test <code>setProperty()</code> converting to a String.
    960      */
    961     public void testSetPropertyConvertToString() {
    962         try {
    963             BeanUtils.setProperty(bean, "stringProperty", testUtilDate);
    964         } catch (Throwable t) {
    965             fail("Threw " + t);
    966         }
    967         assertEquals("java.util.Date --> String", testUtilDate.toString(), bean.getStringProperty());
    968     }
    969
    970     /***
    971      * Test <code>setProperty()</code> converting to a String array.
    972      */
    973     public void testSetPropertyConvertToStringArray() {
    974         try {
    975             bean.setStringArray(null);
    976             BeanUtils.setProperty(bean, "stringArray", new java.util.Date[] {testUtilDate});
    977         } catch (Throwable t) {
    978             fail("Threw " + t);
    979         }
    980         assertEquals("java.util.Date[] --> String[] length", 1, bean.getStringArray().length);
    981         assertEquals("java.util.Date[] --> String[] value ", testUtilDate.toString(), bean.getStringArray()[0]);
    982     }
    983
    984     /***
    985      * Test <code>setProperty()</code> converting to a String on indexed property
    986      */
    987     public void testSetPropertyConvertToStringIndexed() {
    988         try {
    989             bean.setStringArray(new String[1]);
    990             BeanUtils.setProperty(bean, "stringArray[0]", testUtilDate);
    991         } catch (Throwable t) {
    992             fail("Threw " + t);
    993         }
    994         assertEquals("java.util.Date --> String[]", testUtilDate.toString(), bean.getStringArray()[0]);
    995     }
    996
    997     /***
    998      * Test narrowing and widening conversions on double.
    999      */
    1000     public void testSetPropertyDouble() throws Exception {
    1001
    1002         BeanUtils.setProperty(bean, "doubleProperty", new Byte((byte) 123));
    1003         assertEquals(123, bean.getDoubleProperty(), 0.005);
    1004         BeanUtils.setProperty(bean, "doubleProperty", new Double(123));
    1005         assertEquals(123, bean.getDoubleProperty(), 0.005);
    1006         BeanUtils.setProperty(bean, "doubleProperty", new Float(123));
    1007         assertEquals(123, bean.getDoubleProperty(), 0.005);
    1008         BeanUtils.setProperty(bean, "doubleProperty", new Integer(123));
    1009         assertEquals(123, bean.getDoubleProperty(), 0.005);
    1010         BeanUtils.setProperty(bean, "doubleProperty", new Long(123));
    1011         assertEquals(123, bean.getDoubleProperty(), 0.005);
    1012         BeanUtils.setProperty(bean, "doubleProperty", new Short((short) 123));
    1013         assertEquals(123, bean.getDoubleProperty(), 0.005);
    1014
    1015     }
    1016
    1017
    1018     /***
    1019      * Test narrowing and widening conversions on float.
    1020      */
    1021     public void testSetPropertyFloat() throws Exception {
    1022
    1023         BeanUtils.setProperty(bean, "floatProperty", new Byte((byte) 123));
    1024         assertEquals(123, bean.getFloatProperty(), 0.005);
    1025         BeanUtils.setProperty(bean, "floatProperty", new Double(123));
    1026         assertEquals(123, bean.getFloatProperty(), 0.005);
    1027         BeanUtils.setProperty(bean, "floatProperty", new Float(123));
    1028         assertEquals(123, bean.getFloatProperty(), 0.005);
    1029         BeanUtils.setProperty(bean, "floatProperty", new Integer(123));
    1030         assertEquals(123, bean.getFloatProperty(), 0.005);
    1031         BeanUtils.setProperty(bean, "floatProperty", new Long(123));
    1032         assertEquals(123, bean.getFloatProperty(), 0.005);
    1033         BeanUtils.setProperty(bean, "floatProperty", new Short((short) 123));
    1034         assertEquals(123, bean.getFloatProperty(), 0.005);
    1035
    1036     }
    1037
    1038
    1039     /***
    1040      * Test narrowing and widening conversions on int.
    1041      */
    1042     public void testSetPropertyInteger() throws Exception {
    1043
    1044         BeanUtils.setProperty(bean, "longProperty", new Byte((byte) 123));
    1045         assertEquals(123, bean.getIntProperty());
    1046 /*
    1047         BeanUtils.setProperty(bean, "longProperty", new Double((double) 123));
    1048         assertEquals((int) 123, bean.getIntProperty());
    1049         BeanUtils.setProperty(bean, "longProperty", new Float((float) 123));
    1050         assertEquals((int) 123, bean.getIntProperty());
    1051 */
    1052         BeanUtils.setProperty(bean, "longProperty", new Integer(123));
    1053         assertEquals(123, bean.getIntProperty());
    1054         BeanUtils.setProperty(bean, "longProperty", new Long(123));
    1055         assertEquals(123, bean.getIntProperty());
    1056         BeanUtils.setProperty(bean, "longProperty", new Short((short) 123));
    1057         assertEquals(123, bean.getIntProperty());
    1058
    1059     }
    1060
    1061
    1062     /***
    1063      * Test narrowing and widening conversions on long.
    1064      */
    1065     public void testSetPropertyLong() throws Exception {
    1066
    1067         BeanUtils.setProperty(bean, "longProperty", new Byte((byte) 123));
    1068         assertEquals(123, bean.getLongProperty());
    1069 /*
    1070         BeanUtils.setProperty(bean, "longProperty", new Double((double) 123));
    1071         assertEquals((long) 123, bean.getLongProperty());
    1072         BeanUtils.setProperty(bean, "longProperty", new Float((float) 123));
    1073         assertEquals((long) 123, bean.getLongProperty());
    1074 */
    1075         BeanUtils.setProperty(bean, "longProperty", new Integer(123));
    1076         assertEquals(123, bean.getLongProperty());
    1077         BeanUtils.setProperty(bean, "longProperty", new Long(123));
    1078         assertEquals(123, bean.getLongProperty());
    1079         BeanUtils.setProperty(bean, "longProperty", new Short((short) 123));
    1080         assertEquals(123, bean.getLongProperty());
    1081
    1082     }
    1083
    1084
    1085     /***
    1086      * Test setting a null property value.
    1087      */
    1088     public void testSetPropertyNull() throws Exception {
    1089
    1090         bean.setNullProperty("non-null value");
    1091         BeanUtils.setProperty(bean, "nullProperty", null);
    1092         assertNull("nullProperty is null", bean.getNullProperty());
    1093
    1094     }
    1095
    1096
    1097     /***
    1098      * Test narrowing and widening conversions on short.
    1099      */
    1100     public void testSetPropertyShort() throws Exception {
    1101
    1102         BeanUtils.setProperty(bean, "shortProperty", new Byte((byte) 123));
    1103         assertEquals((short) 123, bean.getShortProperty());
    1104 /*
    1105         BeanUtils.setProperty(bean, "shortProperty", new Double((double) 123));
    1106         assertEquals((short) 123, bean.getShortProperty());
    1107         BeanUtils.setProperty(bean, "shortProperty", new Float((float) 123));
    1108         assertEquals((short) 123, bean.getShortProperty());
    1109 */
    1110         BeanUtils.setProperty(bean, "shortProperty", new Integer(123));
    1111         assertEquals((short) 123, bean.getShortProperty());
    1112         BeanUtils.setProperty(bean, "shortProperty", new Long(123));
    1113         assertEquals((short) 123, bean.getShortProperty());
    1114         BeanUtils.setProperty(bean, "shortProperty", new Short((short) 123));
    1115         assertEquals((short) 123, bean.getShortProperty());
    1116
    1117     }
    1118
    1119     /***
    1120      * Test setting a String value to a String array property
    1121      */
    1122     public void testSetPropertyStringToArray() throws Exception {
    1123         BeanUtils.setProperty(bean, "stringArray", "ABC,DEF,GHI");
    1124         String[] strArray =  bean.getStringArray();
    1125         assertEquals("length", 3, strArray.length);
    1126         assertEquals("value[0]", "ABC", strArray[0]);
    1127         assertEquals("value[1]", "DEF", strArray[1]);
    1128         assertEquals("value[2]", "GHI", strArray[2]);
    1129
    1130         BeanUtils.setProperty(bean, "intArray", "0, 10, 20, 30, 40");
    1131         int[] intArray =  bean.getIntArray();
    1132         assertEquals("length", 5, intArray.length);
    1133         assertEquals("value[0]", 0, intArray[0]);
    1134         assertEquals("value[1]", 10, intArray[1]);
    1135         assertEquals("value[2]", 20, intArray[2]);
    1136         assertEquals("value[3]", 30, intArray[3]);
    1137         assertEquals("value[4]", 40, intArray[4]);
    1138     }
    1139
    1140
    1141     /***
    1142      * Test narrowing and widening conversions on byte.
    1143      */
    1144     public void testCopyPropertyByte() throws Exception {
    1145
    1146         BeanUtils.copyProperty(bean, "byteProperty", new Byte((byte) 123));
    1147         assertEquals((byte) 123, bean.getByteProperty());
    1148         BeanUtils.copyProperty(bean, "byteProperty", new Double(123));
    1149         assertEquals((byte) 123, bean.getByteProperty());
    1150         BeanUtils.copyProperty(bean, "byteProperty", new Float(123));
    1151         assertEquals((byte) 123, bean.getByteProperty());
    1152         BeanUtils.copyProperty(bean, "byteProperty", new Integer(123));
    1153         assertEquals((byte) 123, bean.getByteProperty());
    1154         BeanUtils.copyProperty(bean, "byteProperty", new Long(123));
    1155         assertEquals((byte) 123, bean.getByteProperty());
    1156         BeanUtils.copyProperty(bean, "byteProperty", new Short((short) 123));
    1157         assertEquals((byte) 123, bean.getByteProperty());
    1158
    1159     }
    1160
    1161     /***
    1162      * Test <code>copyProperty()</code> conversion.
    1163      */
    1164     public void testCopyPropertyConvert() {
    1165         try {
    1166             BeanUtils.copyProperty(bean, "dateProperty", testCalendar);
    1167         } catch (Throwable t) {
    1168             fail("Threw " + t);
    1169         }
    1170         assertEquals("Calendar --> java.util.Date", testUtilDate, bean.getDateProperty());
    1171     }
    1172
    1173     /***
    1174      * Test <code>copyProperty()</code> converting from a String.
    1175      */
    1176     public void testCopyPropertyConvertFromString() {
    1177         try {
    1178             BeanUtils.copyProperty(bean, "dateProperty", testStringDate);
    1179         } catch (Throwable t) {
    1180             fail("Threw " + t);
    1181         }
    1182         assertEquals("String --> java.util.Date", testUtilDate, bean.getDateProperty());
    1183     }
    1184
    1185     /***
    1186      * Test <code>copyProperty()</code> converting to a String.
    1187      */
    1188     public void testCopyPropertyConvertToString() {
    1189         try {
    1190             BeanUtils.copyProperty(bean, "stringProperty", testUtilDate);
    1191         } catch (Throwable t) {
    1192             fail("Threw " + t);
    1193         }
    1194         assertEquals("java.util.Date --> String", testUtilDate.toString(), bean.getStringProperty());
    1195     }
    1196
    1197     /***
    1198      * Test <code>copyProperty()</code> converting to a String.
    1199      */
    1200     public void testCopyPropertyConvertToStringArray() {
    1201         try {
    1202             bean.setStringArray(null);
    1203             BeanUtils.copyProperty(bean, "stringArray", new java.util.Date[] {testUtilDate});
    1204         } catch (Throwable t) {
    1205             fail("Threw " + t);
    1206         }
    1207         assertEquals("java.util.Date[] --> String[] length", 1, bean.getStringArray().length);
    1208         assertEquals("java.util.Date[] --> String[] value ", testUtilDate.toString(), bean.getStringArray()[0]);
    1209     }
    1210
    1211     /***
    1212      * Test <code>copyProperty()</code> converting to a String on indexed property
    1213      */
    1214     public void testCopyPropertyConvertToStringIndexed() {
    1215         try {
    1216             bean.setStringArray(new String[1]);
    1217             BeanUtils.copyProperty(bean, "stringArray[0]", testUtilDate);
    1218         } catch (Throwable t) {
    1219             fail("Threw " + t);
    1220         }
    1221         assertEquals("java.util.Date --> String[]", testUtilDate.toString(), bean.getStringArray()[0]);
    1222     }
    1223
    1224     /***
    1225      * Test narrowing and widening conversions on double.
    1226      */
    1227     public void testCopyPropertyDouble() throws Exception {
    1228
    1229         BeanUtils.copyProperty(bean, "doubleProperty", new Byte((byte) 123));
    1230         assertEquals(123, bean.getDoubleProperty(), 0.005);
    1231         BeanUtils.copyProperty(bean, "doubleProperty", new Double(123));
    1232         assertEquals(123, bean.getDoubleProperty(), 0.005);
    1233         BeanUtils.copyProperty(bean, "doubleProperty", new Float(123));
    1234         assertEquals(123, bean.getDoubleProperty(), 0.005);
    1235         BeanUtils.copyProperty(bean, "doubleProperty", new Integer(123));
    1236         assertEquals(123, bean.getDoubleProperty(), 0.005);
    1237         BeanUtils.copyProperty(bean, "doubleProperty", new Long(123));
    1238         assertEquals(123, bean.getDoubleProperty(), 0.005);
    1239         BeanUtils.copyProperty(bean, "doubleProperty", new Short((short) 123));
    1240         assertEquals(123, bean.getDoubleProperty(), 0.005);
    1241
    1242     }
    1243
    1244
    1245     /***
    1246      * Test narrowing and widening conversions on float.
    1247      */
    1248     public void testCopyPropertyFloat() throws Exception {
    1249
    1250         BeanUtils.copyProperty(bean, "floatProperty", new Byte((byte) 123));
    1251         assertEquals(123, bean.getFloatProperty(), 0.005);
    1252         BeanUtils.copyProperty(bean, "floatProperty", new Double(123));
    1253         assertEquals(123, bean.getFloatProperty(), 0.005);
    1254         BeanUtils.copyProperty(bean, "floatProperty", new Float(123));
    1255         assertEquals(123, bean.getFloatProperty(), 0.005);
    1256         BeanUtils.copyProperty(bean, "floatProperty", new Integer(123));
    1257         assertEquals(123, bean.getFloatProperty(), 0.005);
    1258         BeanUtils.copyProperty(bean, "floatProperty", new Long(123));
    1259         assertEquals(123, bean.getFloatProperty(), 0.005);
    1260         BeanUtils.copyProperty(bean, "floatProperty", new Short((short) 123));
    1261         assertEquals(123, bean.getFloatProperty(), 0.005);
    1262
    1263     }
    1264
    1265
    1266     /***
    1267      * Test narrowing and widening conversions on int.
    1268      */
    1269     public void testCopyPropertyInteger() throws Exception {
    1270
    1271         BeanUtils.copyProperty(bean, "longProperty", new Byte((byte) 123));
    1272         assertEquals(123, bean.getIntProperty());
    1273         BeanUtils.copyProperty(bean, "longProperty", new Double(123));
    1274         assertEquals(123, bean.getIntProperty());
    1275         BeanUtils.copyProperty(bean, "longProperty", new Float(123));
    1276         assertEquals(123, bean.getIntProperty());
    1277         BeanUtils.copyProperty(bean, "longProperty", new Integer(123));
    1278         assertEquals(123, bean.getIntProperty());
    1279         BeanUtils.copyProperty(bean, "longProperty", new Long(123));
    1280         assertEquals(123, bean.getIntProperty());
    1281         BeanUtils.copyProperty(bean, "longProperty", new Short((short) 123));
    1282         assertEquals(123, bean.getIntProperty());
    1283
    1284     }
    1285
    1286
    1287     /***
    1288      * Test narrowing and widening conversions on long.
    1289      */
    1290     public void testCopyPropertyLong() throws Exception {
    1291
    1292         BeanUtils.copyProperty(bean, "longProperty", new Byte((byte) 123));
    1293         assertEquals(123, bean.getLongProperty());
    1294         BeanUtils.copyProperty(bean, "longProperty", new Double(123));
    1295         assertEquals(123, bean.getLongProperty());
    1296         BeanUtils.copyProperty(bean, "longProperty", new Float(123));
    1297         assertEquals(123, bean.getLongProperty());
    1298         BeanUtils.copyProperty(bean, "longProperty", new Integer(123));
    1299         assertEquals(123, bean.getLongProperty());
    1300         BeanUtils.copyProperty(bean, "longProperty", new Long(123));
    1301         assertEquals(123, bean.getLongProperty());
    1302         BeanUtils.copyProperty(bean, "longProperty", new Short((short) 123));
    1303         assertEquals(123, bean.getLongProperty());
    1304
    1305     }
    1306
    1307
    1308     /***
    1309      * Test narrowing and widening conversions on short.
    1310      */
    1311     public void testCopyPropertyShort() throws Exception {
    1312
    1313         BeanUtils.copyProperty(bean, "shortProperty", new Byte((byte) 123));
    1314         assertEquals((short) 123, bean.getShortProperty());
    1315         BeanUtils.copyProperty(bean, "shortProperty", new Double(123));
    1316         assertEquals((short) 123, bean.getShortProperty());
    1317         BeanUtils.copyProperty(bean, "shortProperty", new Float(123));
    1318         assertEquals((short) 123, bean.getShortProperty());
    1319         BeanUtils.copyProperty(bean, "shortProperty", new Integer(123));
    1320         assertEquals((short) 123, bean.getShortProperty());
    1321         BeanUtils.copyProperty(bean, "shortProperty", new Long(123));
    1322         assertEquals((short) 123, bean.getShortProperty());
    1323         BeanUtils.copyProperty(bean, "shortProperty", new Short((short) 123));
    1324         assertEquals((short) 123, bean.getShortProperty());
    1325
    1326     }
    1327
    1328
    1329     /***
    1330      * Test copying a property using a nested indexed array expression,
    1331      * with and without conversions.
    1332      */
    1333     public void testCopyPropertyNestedIndexedArray() throws Exception {
    1334
    1335         int origArray[] = { 0, 10, 20, 30, 40 };
    1336         int intArray[] = { 0, 0, 0 };
    1337         bean.getNested().setIntArray(intArray);
    1338         int intChanged[] = { 0, 0, 0 };
    1339
    1340         // No conversion required
    1341         BeanUtils.copyProperty(bean, "nested.intArray[1]", new Integer(1));
    1342         checkIntArray(bean.getIntArray(), origArray);
    1343         intChanged[1] = 1;
    1344         checkIntArray(bean.getNested().getIntArray(), intChanged);
    1345
    1346         // Widening conversion required
    1347         BeanUtils.copyProperty(bean, "nested.intArray[1]", new Byte((byte) 2));
    1348         checkIntArray(bean.getIntArray(), origArray);
    1349         intChanged[1] = 2;
    1350         checkIntArray(bean.getNested().getIntArray(), intChanged);
    1351
    1352         // Narrowing conversion required
    1353         BeanUtils.copyProperty(bean, "nested.intArray[1]", new Long(3));
    1354         checkIntArray(bean.getIntArray(), origArray);
    1355         intChanged[1] = 3;
    1356         checkIntArray(bean.getNested().getIntArray(), intChanged);
    1357
    1358         // String conversion required
    1359         BeanUtils.copyProperty(bean, "nested.intArray[1]", "4");
    1360         checkIntArray(bean.getIntArray(), origArray);
    1361         intChanged[1] = 4;
    1362         checkIntArray(bean.getNested().getIntArray(), intChanged);
    1363
    1364     }
    1365
    1366
    1367     /***
    1368      * Test copying a property using a nested mapped map property.
    1369      */
    1370     public void testCopyPropertyNestedMappedMap() throws Exception {
    1371
    1372         Map origMap = new HashMap();
    1373         origMap.put("First Key", "First Value");
    1374         origMap.put("Second Key", "Second Value");
    1375         Map changedMap = new HashMap();
    1376         changedMap.put("First Key", "First Value");
    1377         changedMap.put("Second Key", "Second Value");
    1378
    1379         // No conversion required
    1380         BeanUtils.copyProperty(bean, "nested.mapProperty(Second Key)",
    1381                                "New Second Value");
    1382         checkMap(bean.getMapProperty(), origMap);
    1383         changedMap.put("Second Key", "New Second Value");
    1384         checkMap(bean.getNested().getMapProperty(), changedMap);
    1385
    1386     }
    1387
    1388
    1389     /***
    1390      * Test copying a property using a nested simple expression, with and
    1391      * without conversions.
    1392      */
    1393     public void testCopyPropertyNestedSimple() throws Exception {
    1394
    1395         bean.setIntProperty(0);
    1396         bean.getNested().setIntProperty(0);
    1397
    1398         // No conversion required
    1399         BeanUtils.copyProperty(bean, "nested.intProperty", new Integer(1));
    1400         assertNotNull(bean.getNested());
    1401         assertEquals(0, bean.getIntProperty());
    1402         assertEquals(1, bean.getNested().getIntProperty());
    1403
    1404         // Widening conversion required
    1405         BeanUtils.copyProperty(bean, "nested.intProperty", new Byte((byte) 2));
    1406         assertNotNull(bean.getNested());
    1407         assertEquals(0, bean.getIntProperty());
    1408         assertEquals(2, bean.getNested().getIntProperty());
    1409
    1410         // Narrowing conversion required
    1411         BeanUtils.copyProperty(bean, "nested.intProperty", new Long(3));
    1412         assertNotNull(bean.getNested());
    1413         assertEquals(0, bean.getIntProperty());
    1414         assertEquals(3, bean.getNested().getIntProperty());
    1415
    1416         // String conversion required
    1417         BeanUtils.copyProperty(bean, "nested.intProperty", "4");
    1418         assertNotNull(bean.getNested());
    1419         assertEquals(0, bean.getIntProperty());
    1420         assertEquals(4, bean.getNested().getIntProperty());
    1421
    1422     }
    1423
    1424
    1425     /***
    1426      * Test copying a null property value.
    1427      */
    1428     public void testCopyPropertyNull() throws Exception {
    1429
    1430         bean.setNullProperty("non-null value");
    1431         BeanUtils.copyProperty(bean, "nullProperty", null);
    1432         assertNull("nullProperty is null", bean.getNullProperty());
    1433
    1434     }
    1435
    1436
    1437     /***
    1438      * Test copying a new value to a write-only property, with and without
    1439      * conversions.
    1440      */
    1441     public void testCopyPropertyWriteOnly() throws Exception {
    1442
    1443         bean.setWriteOnlyProperty("Original value");
    1444
    1445         // No conversion required
    1446         BeanUtils.copyProperty(bean, "writeOnlyProperty", "New value");
    1447         assertEquals("New value", bean.getWriteOnlyPropertyValue());
    1448
    1449         // Integer->String conversion required
    1450         BeanUtils.copyProperty(bean, "writeOnlyProperty", new Integer(123));
    1451         assertEquals("123", bean.getWriteOnlyPropertyValue());
    1452
    1453     }
    1454
    1455
    1456     /***
    1457      * Test setting a new value to a write-only property, with and without
    1458      * conversions.
    1459      */
    1460     public void testSetPropertyWriteOnly() throws Exception {
    1461
    1462         bean.setWriteOnlyProperty("Original value");
    1463
    1464         // No conversion required
    1465         BeanUtils.setProperty(bean, "writeOnlyProperty", "New value");
    1466         assertEquals("New value", bean.getWriteOnlyPropertyValue());
    1467
    1468         // Integer->String conversion required
    1469         BeanUtils.setProperty(bean, "writeOnlyProperty", new Integer(123));
    1470         assertEquals("123", bean.getWriteOnlyPropertyValue());
    1471
    1472     }
    1473
    1474     /*** Tests that separate instances can register separate instances */
    1475     public void testSeparateInstances() throws Exception {
    1476         BeanUtilsBean utilsOne = new BeanUtilsBean(
    1477                                                 new ConvertUtilsBean(),
    1478                                                 new PropertyUtilsBean());
    1479         BeanUtilsBean utilsTwo = new BeanUtilsBean(
    1480                                                 new ConvertUtilsBean(),
    1481                                                 new PropertyUtilsBean());
    1482
    1483
    1484         TestBean bean = new TestBean();
    1485
    1486         // Make sure what we're testing works
    1487         bean.setBooleanProperty(false);
    1488         utilsOne.setProperty(bean, "booleanProperty", "true");
    1489         assertEquals("Set property failed (1)", bean.getBooleanProperty(), true);
    1490
    1491         bean.setBooleanProperty(false);
    1492         utilsTwo.setProperty(bean, "booleanProperty", "true");
    1493         assertEquals("Set property failed (2)", bean.getBooleanProperty(), true);
    1494
    1495         // now change the registered conversion
    1496
    1497         utilsOne.getConvertUtils().register(new ThrowExceptionConverter(), Boolean.TYPE);
    1498         try {
    1499
    1500             bean.setBooleanProperty(false);
    1501             utilsOne.setProperty(bean, "booleanProperty", "true");
    1502             fail("Registered conversion not used.");
    1503
    1504         } catch (PassTestException e) { /* Do nothing */ }
    1505
    1506         // make sure that this conversion has no been registered in the other instance
    1507         try {
    1508
    1509             bean.setBooleanProperty(false);
    1510             utilsTwo.setProperty(bean, "booleanProperty", "true");
    1511             assertEquals("Set property failed (3)", bean.getBooleanProperty(), true);
    1512
    1513         } catch (PassTestException e) {
    1514             fail("Registed converter is used by other instances");
    1515         }
    1516     }
    1517
    1518     public void testArrayPropertyConversion() throws Exception {
    1519         BeanUtilsBean beanUtils = new BeanUtilsBean(
    1520                                                     new ConvertUtilsBean(),
    1521                                                     new PropertyUtilsBean());
    1522
    1523         TestBean bean = new TestBean();
    1524         String [] results = beanUtils.getArrayProperty(bean, "intArray");
    1525
    1526         int[] values = bean.getIntArray();
    1527         assertEquals(
    1528                     "Converted array size not equal to property array size.",
    1529                     results.length,
    1530                     values.length);
    1531         for (int i=0, size=values.length ;  i<size; i++) {
    1532             assertEquals(
    1533                     "Value " + i + " incorrectly converted ",
    1534                     values[i] + "",
    1535                     results[i]);
    1536         }
    1537     }
    1538
    1539     // Ensure that the actual int[] matches the expected int[]
    1540     protected void checkIntArray(int actual[], int expected[]) {
    1541         assertNotNull("actual array not null", actual);
    1542         assertEquals("actual array length", expected.length, actual.length);
    1543         for (int i = 0; i < actual.length; i++) {
    1544             assertEquals("actual array value[" + i + "]",
    1545                          expected[i], actual[i]);
    1546         }
    1547     }
    1548
    1549
    1550     // Ensure that the actual Map matches the expected Map
    1551     protected void checkMap(Map actual, Map expected) {
    1552         assertNotNull("actual map not null", actual);
    1553         assertEquals("actual map size", expected.size(), actual.size());
    1554         Iterator keys = expected.keySet().iterator();
    1555         while (keys.hasNext()) {
    1556             Object key = keys.next();
    1557             assertEquals("actual map value(" + key + ")",
    1558                          expected.get(key), actual.get(key));
    1559         }
    1560     }
    1561
    1562     public void testMappedProperty() throws Exception {
    1563         MappedPropertyTestBean bean = new MappedPropertyTestBean();
    1564
    1565         BeanUtils.setProperty(bean, "mapproperty(this.that.the-other)", "some.dotty.value");
    1566
    1567         assertEquals(
    1568                         "Mapped property set correctly",
    1569                         "some.dotty.value",
    1570                         bean.getMapproperty("this.that.the-other"));
    1571     }
    1572
    1573     /***
    1574      * Test for {@link BeanUtilsBean#initCause(Throwable, Throwable)} method.
    1575      */
    1576     public void testInitCause() {
    1577         if (isPre14JVM()) {
    1578             return;
    1579         }
    1580         String parentMsg = "PARENT-THROWABLE";
    1581         String causeMsg  = "THROWABLE-CAUSE";
    1582         try {
    1583             initCauseAndThrowException(parentMsg, causeMsg);
    1584         } catch (Throwable thrownParent) {
    1585             assertEquals("Parent", parentMsg, thrownParent.getMessage());
    1586             try {
    1587                 assertEquals("Parent", parentMsg, thrownParent.getMessage());
    1588                 Throwable thrownCause = getCause(thrownParent);
    1589                 assertNotNull("Cause Null", thrownCause);
    1590                 assertEquals("Cause", causeMsg, thrownCause.getMessage());
    1591             } catch (Throwable testError) {
    1592                 fail("If you're running JDK 1.3 then don't worry this should fail," +
    1593                         " if not then needs checking out: " + testError);
    1594             }
    1595         }
    1596     }
    1597
    1598     /***
    1599      * Use reflection to get the cause
    1600      */
    1601     private Throwable getCause(Throwable t) throws Throwable {
    1602         return (Throwable)PropertyUtils.getProperty(t, "cause");
    1603     }
    1604
    1605     /***
    1606      * Catch a cause, initialize using BeanUtils.initCause() and throw new exception
    1607      */
    1608     private void initCauseAndThrowException(String parent, String cause) throws Throwable {
    1609         try {
    1610             throwException(cause);
    1611         } catch (Throwable e) {
    1612             Throwable t = new Exception(parent);
    1613             BeanUtils.initCause(t, e);
    1614             throw t;
    1615         }
    1616     }
    1617
    1618     /***
    1619      * Throw an exception with the specified message.
    1620      */
    1621     private void throwException(String msg) throws Throwable {
    1622         throw new Exception(msg);
    1623     }
    1624
    1625     /***
    1626      * Test for JDK 1.4
    1627      */
    1628     private boolean isPre14JVM() {
    1629         String version = System.getProperty("java.specification.version");
    1630         StringTokenizer tokenizer = new StringTokenizer(version,".");
    1631         if (tokenizer.nextToken().equals("1")) {
    1632             String minorVersion = tokenizer.nextToken();
    1633             if (minorVersion.equals("0")) return true;
    1634             if (minorVersion.equals("1")) return true;
    1635             if (minorVersion.equals("2")) return true;
    1636             if (minorVersion.equals("3")) return true;
    1637         }
    1638         return false;
    1639     }
    1640 }