    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.converters;
    19
    20  import java.math.BigDecimal;
    21  import java.math.BigInteger;
    22  import java.util.Calendar;
    23  import java.util.Date;
    24  import java.util.Locale;
    25
    26  import junit.framework.TestCase;
    27
    28  import org.apache.commons.beanutils.ConversionException;
    29
    30
    31  /***
    32   * Abstract base for &lt;Number&gt;Converter classes.
    33   *
    34   * @author Rodney Waldhoff
    35   * @version $Revision: 541692 $ $Date: 2007-05-25 16:34:19 +0100 (Fri, 25 May 2007) $
    36   */
    37
    38  public abstract class NumberConverterTestBase extends TestCase {
    39
    40      /*** Test Number values */
    41      protected Number[] numbers = new Number[4];
    42
    43      // ------------------------------------------------------------------------
    44
    45      public NumberConverterTestBase(String name) {
    46          super(name);
    47      }
    48
    49      // ------------------------------------------------------------------------
    50
    51      protected abstract NumberConverter makeConverter();
    52      protected abstract NumberConverter makeConverter(Object defaultValue);
    53      protected abstract Class getExpectedType();
    54
    55      // ------------------------------------------------------------------------
    56
    57      /***
    58       * Assumes ConversionException in response to covert(getExpectedType(),null).
    59       */
    60      public void testConvertNull() {
    61          try {
    62              makeConverter().convert(getExpectedType(),null);
    63              fail("Expected ConversionException");
    64          } catch(ConversionException e) {
    65              // expected
    66          }
    67      }
    68
    69      /***
    70       * Assumes convert(getExpectedType(),Number) returns some non-null
    71       * instance of getExpectedType().
    72       */
    73      public void testConvertNumber() {
    74          String[] message= {
    75              "from Byte",
    76              "from Short",
    77              "from Integer",
    78              "from Long",
    79              "from Float",
    80              "from Double",
    81              "from BigDecimal",
    82              "from BigInteger",
    83              "from Integer array",
    84          };
    85
    86          Object[] number = {
    87              new Byte((byte)7),
    88              new Short((short)8),
    89              new Integer(9),
    90              new Long(10),
    91              new Float(11.1),
    92              new Double(12.2),
    93              new BigDecimal("17.2"),
    94              new BigInteger("33"),
    95              new Integer[] {new Integer(3), new Integer(2), new Integer(1)}
    96          };
    97
    98          for(int i=0;i<number.length;i++) {
    99              Object val = makeConverter().convert(getExpectedType(),number[i]);
    100             assertNotNull("Convert " + message[i] + " should not be null",val);
    101             assertTrue(
    102                 "Convert " + message[i] + " should return a " + getExpectedType().getName(),
    103                 getExpectedType().isInstance(val));
    104         }
    105     }
    106     /***
    107      * Convert Number --> String (using a Pattern, with default and specified Locales)
    108      */
    109     public void testNumberToStringPattern() {
    110
    111         // Re-set the default Locale to Locale.US
    112         Locale defaultLocale = Locale.getDefault();
    113         Locale.setDefault(Locale.US);
    114
    115         NumberConverter converter = makeConverter();
    116         converter.setPattern("[0,0.0];(0,0.0)");
    117
    118         // Default Locale
    119         assertEquals("Default Locale " + numbers[0], "(12.0)", converter.convert(String.class, numbers[0]));
    120         assertEquals("Default Locale " + numbers[1], "[13.0]", converter.convert(String.class, numbers[1]));
    121
    122         // Locale.GERMAN
    123         converter.setLocale(Locale.GERMAN);
    124         assertEquals("Locale.GERMAN " + numbers[2], "(22,0)", converter.convert(String.class, numbers[2]));
    125         assertEquals("Locale.GERMAN " + numbers[3], "[23,0]", converter.convert(String.class, numbers[3]));
    126
    127         // Restore the default Locale
    128         Locale.setDefault(defaultLocale);
    129     }
    130
    131     /***
    132      * Convert Number --> String (using default and specified Locales)
    133      */
    134     public void testNumberToStringLocale() {
    135
    136         // Re-set the default Locale to Locale.US
    137         Locale defaultLocale = Locale.getDefault();
    138         Locale.setDefault(Locale.US);
    139
    140         NumberConverter converter = makeConverter();
    141         converter.setUseLocaleFormat(true);
    142
    143         // Default Locale
    144         assertEquals("Default Locale " + numbers[0], "-12", converter.convert(String.class, numbers[0]));
    145         assertEquals("Default Locale " + numbers[1], "13",  converter.convert(String.class, numbers[1]));
    146
    147         // Locale.GERMAN
    148         converter.setLocale(Locale.GERMAN);
    149         assertEquals("Locale.GERMAN " + numbers[2], "-22", converter.convert(String.class, numbers[2]));
    150         assertEquals("Locale.GERMAN " + numbers[3], "23",  converter.convert(String.class, numbers[3]));
    151
    152         // Restore the default Locale
    153         Locale.setDefault(defaultLocale);
    154     }
    155
    156     /***
    157      * Convert Array --> Number
    158      */
    159     public void testStringArrayToInteger() {
    160
    161         Integer defaultValue = new Integer(-1);
    162         NumberConverter converter = makeConverter(defaultValue);
    163
    164         // Default Locale
    165         assertEquals("Valid First",   new Integer(5), converter.convert(Integer.class, new String[] {"5", "4", "3"}));
    166         assertEquals("Invalid First", defaultValue,   converter.convert(Integer.class, new String[] {"FOO", "1", "2"}));
    167         assertEquals("Null First",    defaultValue,   converter.convert(Integer.class, new String[] {null, "1", "2"}));
    168         assertEquals("Long Array",    new Integer(9), converter.convert(Integer.class, new long[] {9, 2, 6}));
    169     }
    170
    171     /***
    172      * Convert Number --> String (default conversion)
    173      */
    174     public void testNumberToStringDefault() {
    175
    176         NumberConverter converter = makeConverter();
    177
    178         // Default Number --> String conversion
    179         assertEquals("Default Convert " + numbers[0], numbers[0].toString(), converter.convert(String.class, numbers[0]));
    180         assertEquals("Default Convert " + numbers[1], numbers[1].toString(), converter.convert(String.class, numbers[1]));
    181
    182     }
    183
    184     /***
    185      * Convert String --> Number (using a Pattern, with default and specified Locales)
    186      */
    187     public void testStringToNumberPattern() {
    188
    189         // Re-set the default Locale to Locale.US
    190         Locale defaultLocale = Locale.getDefault();
    191         Locale.setDefault(Locale.US);
    192
    193         NumberConverter converter = makeConverter();
    194         converter.setPattern("[0,0];(0,0)");
    195
    196         // Default Locale
    197         assertEquals("Default Locale " + numbers[0], numbers[0], converter.convert(getExpectedType(), "(1,2)"));
    198         assertEquals("Default Locale " + numbers[1], numbers[1], converter.convert(getExpectedType(), "[1,3]"));
    199
    200         // Locale.GERMAN
    201         converter.setLocale(Locale.GERMAN);
    202         assertEquals("Locale.GERMAN " + numbers[2], numbers[2], converter.convert(getExpectedType(), "(2.2)"));
    203         assertEquals("Locale.GERMAN " + numbers[3], numbers[3], converter.convert(getExpectedType(), "[2.3]"));
    204
    205         // Invalid Value
    206         try {
    207             converter.convert(getExpectedType(), "1,2");
    208             fail("Expected invalid value to cause ConversionException");
    209         } catch (Exception e) {
    210             // expected result
    211         }
    212
    213         // Invalid Type (will try via String)
    214         Object obj =  new Object() {
    215             public String toString() {
    216                 return "dsdgsdsdg";
    217             }
    218         };
    219         try {
    220             converter.convert(getExpectedType(), obj);
    221             fail("Expected invalid value to cause ConversionException");
    222         } catch (Exception e) {
    223             // expected result
    224         }
    225
    226         // Restore the default Locale
    227         Locale.setDefault(defaultLocale);
    228     }
    229
    230     /***
    231      * Convert String --> Number (using default and specified Locales)
    232      */
    233     public void testStringToNumberLocale() {
    234
    235         // Re-set the default Locale to Locale.US
    236         Locale defaultLocale = Locale.getDefault();
    237         Locale.setDefault(Locale.US);
    238
    239         NumberConverter converter = makeConverter();
    240         converter.setUseLocaleFormat(true);
    241
    242         // Default Locale
    243         assertEquals("Default Locale " + numbers[0], numbers[0], converter.convert(getExpectedType(), "-0,012"));
    244         assertEquals("Default Locale " + numbers[1], numbers[1], converter.convert(getExpectedType(), "0,013"));
    245
    246         // Invalid Value
    247         try {
    248             converter.convert(getExpectedType(), "0,02x");
    249             fail("Expected invalid value to cause ConversionException");
    250         } catch (Exception e) {
    251             // expected result
    252         }
    253
    254         // Locale.GERMAN
    255         converter.setLocale(Locale.GERMAN);
    256         assertEquals("Locale.GERMAN " + numbers[2], numbers[2], converter.convert(getExpectedType(), "-0.022"));
    257         assertEquals("Locale.GERMAN " + numbers[3], numbers[3], converter.convert(getExpectedType(), "0.023"));
    258
    259         // Invalid Value
    260         try {
    261             converter.convert(getExpectedType(), "0.02x");
    262             fail("Expected invalid value to cause ConversionException");
    263         } catch (Exception e) {
    264             // expected result
    265         }
    266
    267         // Restore the default Locale
    268         Locale.setDefault(defaultLocale);
    269     }
    270
    271     /***
    272      * Convert String --> Number (default conversion)
    273      */
    274     public void testStringToNumberDefault() {
    275
    276         NumberConverter converter = makeConverter();
    277         converter.setUseLocaleFormat(false);
    278
    279         // Default String --> Number conversion
    280         assertEquals("Default Convert " + numbers[0], numbers[0], converter.convert(getExpectedType(), numbers[0].toString()));
    281
    282         // Invalid
    283         try {
    284             converter.convert(getExpectedType(), "12x");
    285             fail("Expected invalid value to cause ConversionException");
    286         } catch (Exception e) {
    287             // expected result
    288         }
    289     }
    290
    291     /***
    292      * Convert Boolean --> Number (default conversion)
    293      */
    294     public void testBooleanToNumberDefault() {
    295
    296         NumberConverter converter = makeConverter();
    297
    298         // Other type --> String conversion
    299         assertEquals("Boolean.FALSE to Number ", 0, ((Number)converter.convert(getExpectedType(), Boolean.FALSE)).intValue());
    300         assertEquals("Boolean.TRUE to Number ",  1, ((Number)converter.convert(getExpectedType(), Boolean.TRUE)).intValue());
    301
    302     }
    303
    304     /***
    305      * Convert Date --> Long
    306      */
    307     public void testDateToNumber() {
    308
    309         NumberConverter converter = makeConverter();
    310
    311         Date dateValue = new Date();
    312         long longValue = dateValue.getTime();
    313
    314         // Date --> Long conversion
    315         assertEquals("Date to Long", new Long(longValue), converter.convert(Long.class, dateValue));
    316
    317         // Date --> Integer
    318         try {
    319             converter.convert(Integer.class, dateValue);
    320             fail("Date to Integer - expected a ConversionException");
    321         } catch (ConversionException e) {
    322             // expected result - too large for Integer
    323         }
    324
    325     }
    326
    327     /***
    328      * Convert Calendar --> Long
    329      */
    330     public void testCalendarToNumber() {
    331
    332         NumberConverter converter = makeConverter();
    333
    334         Calendar calendarValue = Calendar.getInstance();
    335         long longValue = calendarValue.getTime().getTime();
    336
    337         // Calendar --> Long conversion
    338         assertEquals("Calendar to Long", new Long(longValue), converter.convert(Long.class, calendarValue));
    339
    340         // Calendar --> Integer
    341         try {
    342             converter.convert(Integer.class, calendarValue);
    343             fail("Calendar to Integer - expected a ConversionException");
    344         } catch (ConversionException e) {
    345             // expected result - too large for Integer
    346         }
    347
    348     }
    349
    350     /***
    351      * Convert Other --> String (default conversion)
    352      */
    353     public void testOtherToStringDefault() {
    354
    355         NumberConverter converter = makeConverter();
    356
    357         // Other type --> String conversion
    358         assertEquals("Default Convert ", "ABC", converter.convert(String.class, new StringBuffer("ABC")));
    359
    360     }
    361
    362     /***
    363      * Convert Number --> String (using default and specified Locales)
    364      */
    365     public void testInvalidDefault() {
    366
    367         Object defaultvalue = numbers[0];
    368         NumberConverter converter = makeConverter(defaultvalue);
    369
    370         // Default String --> Number conversion
    371         assertEquals("Invalid null ", defaultvalue, converter.convert(getExpectedType(), null));
    372         assertEquals("Default XXXX ", defaultvalue, converter.convert(getExpectedType(), "XXXX"));
    373     }
    374
    375     /***
    376      * Convert Number --> String (using default and specified Locales)
    377      */
    378     public void testInvalidException() {
    379
    380         NumberConverter converter = makeConverter();
    381
    382         try {
    383             converter.convert(getExpectedType(), null);
    384             fail("Null test, expected ConversionException");
    385         } catch (ConversionException e) {
    386             // expected result
    387         }
    388         try {
    389             converter.convert(getExpectedType(), "XXXX");
    390             fail("Invalid test, expected ConversionException");
    391         } catch (ConversionException e) {
    392             // expected result
    393         }
    394     }
    395
    396     /***
    397      * Test specifying an invalid type.
    398      */
    399     public void testInvalidType() {
    400
    401         NumberConverter converter = makeConverter();
    402
    403         try {
    404             converter.convert(Object.class, numbers[0]);
    405             fail("Invalid type test, expected ConversionException");
    406         } catch (ConversionException e) {
    407             // expected result
    408         }
    409     }
    410 }
    411