    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.locale.converters;
    19
    20  import java.text.SimpleDateFormat;
    21  import java.text.ParseException;
    22  import java.text.DateFormatSymbols;
    23
    24  import java.util.Locale;
    25
    26  import org.apache.commons.beanutils.ConversionException;
    27  import org.apache.commons.beanutils.locale.BaseLocaleConverter;
    28  import org.apache.commons.logging.LogFactory;
    29  import org.apache.commons.logging.Log;
    30
    31  /***
    32   * Test Case for the DateLocaleConverter class.
    33   *
    34   * @author Robert Burrell Donkin
    35   * @author Niall Pemberton
    36   * @version $Revision: 555645 $ $Date: 2007-07-12 15:40:37 +0100 (Thu, 12 Jul 2007) $
    37   */
    38
    39  public class DateLocaleConverterTestCase extends BaseLocaleConverterTestCase {
    40
    41      /*** All logging goes through this logger */
    42      private Log log = LogFactory.getLog(DateLocaleConverterTestCase.class);
    43
    44      protected String localizedDatePattern;
    45      protected String localizedDateValue;
    46      protected String localizedShortDateValue;
    47      protected String defaultDatePattern;
    48      protected String defaultDateValue;
    49      protected String defaultShortDateValue;
    50
    51      protected boolean validLocalDateSymbols;
    52
    53      // ------------------------------------------------------------------------
    54
    55      public DateLocaleConverterTestCase(String name) {
    56          super(name);
    57      }
    58
    59      // -------------------------------------------------- Overall Test Methods
    60
    61      /***
    62       * Set up instance variables required by this test case.
    63       */
    64      public void setUp() throws Exception {
    65
    66          super.setUp();
    67
    68          String version = System.getProperty("java.specification.version");
    69          log.warn("JDK Version "+version);
    70
    71
    72          try {
    73              SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
    74              expectedValue      = format.parse("20041001");
    75              defaultValue       = format.parse("19670316");
    76          } catch (Exception ex) {
    77              log.error("Error creating expected/default dates", ex);
    78          }
    79
    80          // Default Locale (Use US)
    81          defaultLocale           = Locale.US;
    82          defaultDatePattern      = "d MMMM yyyy";
    83          defaultDateValue        = "1 October 2004";
    84          defaultShortDateValue   = "10/01/04";
    85
    86          // Use German Locale
    87  //        localizedLocale         = Locale.GERMAN;  // N.B. doesn't work for dates
    88  //        localizedLocale         = Locale.GERMANY; // N.B. doesn't work for dates
    89          localizedLocale         = new Locale("de", "AT"); // Austria/German works
    90          localizedDatePattern    = "t MMMM uuuu";
    91          localizedDateValue      = "1 Oktober 2004";
    92          localizedShortDateValue = "01.10.04";
    93
    94          // Test whether the "local pattern characters" are what we
    95          // are expecting - Locale.GERMAN and Locale.GERMANY, Locale.FRENCH all
    96          // returned the standard "English" pattern characters on my machine
    97          // for JDK 1.4 (JDK 1.3 was OK). The Austria/German locale was OK though
    98          String expectedChars = "GuMtkHmsSEDFwWahKzZ";
    99          DateFormatSymbols localizedSymbols = new DateFormatSymbols(localizedLocale);
    100         String localChars    = localizedSymbols.getLocalPatternChars();
    101
    102         // different JDK versions seem to have different numbers of pattern characters
    103         int lth = localChars.length() > expectedChars.length() ? expectedChars.length() :
    104                      localChars.length() < expectedChars.length() ? localChars.length() : expectedChars.length();
    105         validLocalDateSymbols = expectedChars.substring(0, lth).equals(localChars.substring(0, lth));
    106
    107     }
    108
    109     /***
    110      * Tear down instance variables required by this test case.
    111      */
    112     public void tearDown() {
    113         super.tearDown();
    114     }
    115
    116
    117     // ------------------------------------------------------------------------
    118
    119     public void testSetLenient() {
    120         // make sure that date format works as expected
    121         SimpleDateFormat dateFormat = new SimpleDateFormat("MMM dd, yyyy", Locale.UK);
    122
    123         // test with no leniency
    124         dateFormat.setLenient(false);
    125
    126         try {
    127
    128             dateFormat.parse("Feb 10, 2001");
    129
    130         } catch (ParseException e) {
    131             fail("Could not parse date (1) - " + e.getMessage());
    132         }
    133
    134         try {
    135
    136             dateFormat.parse("Feb 31, 2001");
    137             fail("Parsed illegal date (1)");
    138
    139         } catch (ParseException e) {
    140             // that's what we expected
    141         }
    142
    143         // test with leniency
    144         dateFormat.setLenient(true);
    145
    146         try {
    147
    148             dateFormat.parse("Feb 10, 2001");
    149
    150         } catch (ParseException e) {
    151             fail("Could not parse date (2) - " + e.getMessage());
    152         }
    153
    154         try {
    155
    156             dateFormat.parse("Feb 31, 2001");
    157
    158         } catch (ParseException e) {
    159             fail("Could not parse date (3) - " + e.getMessage());
    160         }
    161
    162         // now repeat tests for converter
    163         DateLocaleConverter converter = new DateLocaleConverter(Locale.UK, "MMM dd, yyyy");
    164
    165         // test with no leniency
    166         converter.setLenient(false);
    167         assertEquals("Set lenient failed", converter.isLenient(), false);
    168
    169         try {
    170
    171             converter.convert("Feb 10, 2001");
    172
    173         } catch (ConversionException e) {
    174             fail("Could not parse date (4) - " + e.getMessage());
    175         }
    176
    177         try {
    178
    179             converter.convert("Feb 31, 2001");
    180             assertEquals("Set lenient failed", converter.isLenient(), false);
    181             fail("Parsed illegal date (2)");
    182
    183         } catch (ConversionException e) {
    184             // that's what we expected
    185         }
    186
    187         // test with leniency
    188         converter.setLenient(true);
    189         assertEquals("Set lenient failed", converter.isLenient(), true);
    190
    191         try {
    192
    193             converter.convert("Feb 10, 2001");
    194
    195         } catch (ConversionException e) {
    196             fail("Could not parse date (5) - " + e.getMessage());
    197         }
    198
    199         try {
    200
    201             converter.convert("Feb 31, 2001");
    202
    203         } catch (ConversionException e) {
    204             fail("Could not parse date (6) - " + e.getMessage());
    205         }
    206     }
    207
    208     /***
    209      * Test Converter(defaultValue, locale, pattern, localizedPattern) constructor
    210      */
    211     public void testConstructorMain() {
    212
    213         // Skip this test if no valid symbols for the locale
    214         if (!validLocalDateSymbols) {
    215             log.error("Invalid locale symbols *** skipping testConstructorMain() **");
    216             return;
    217         }
    218
    219         // ------------- Construct with localized pattern ------------
    220         converter = new DateLocaleConverter(defaultValue,
    221                                             localizedLocale,
    222                                             localizedDatePattern,
    223                                             true);
    224
    225
    226         convertValueNoPattern(converter, "(A)", localizedDateValue, expectedValue);
    227         convertValueWithPattern(converter, "(A)", localizedDateValue, localizedDatePattern, expectedValue);
    228         convertInvalid(converter, "(A)", defaultValue);
    229         convertNull(converter, "(A)", defaultValue);
    230
    231
    232         // Convert value in the wrong format - should return default value
    233         convertValueNoPattern(converter, "(B)", defaultDateValue, defaultValue);
    234
    235         // Convert with non-localized pattern - should return default value
    236         convertValueWithPattern(converter, "(B)", localizedDateValue, defaultDatePattern, defaultValue);
    237
    238         // **************************************************************************
    239         // Convert with specified type
    240         //
    241         // BaseLocaleConverter completely ignores the type - so even if we specify
    242         // Double.class here it still returns a Date.
    243         //  **** SHOULD IMPLEMENT THIS BEHAVIOUR ****
    244         // **************************************************************************
    245         convertValueToType(converter, "(B)", String.class, localizedDateValue, localizedDatePattern, expectedValue);
    246
    247
    248         // ------------- Construct with non-localized pattern ------------
    249         converter = new DateLocaleConverter(defaultValue,
    250                                             localizedLocale,
    251                                             defaultDatePattern,
    252                                             false);
    253
    254
    255         convertValueNoPattern(converter, "(C)", localizedDateValue, expectedValue);
    256         convertValueWithPattern(converter, "(C)", localizedDateValue, defaultDatePattern, expectedValue);
    257         convertInvalid(converter, "(C)", defaultValue);
    258         convertNull(converter, "(C)", defaultValue);
    259
    260     }
    261
    262     /***
    263      * Test Converter() constructor
    264      *
    265      * Uses the default locale, no default value
    266      *
    267      */
    268     public void testConstructor_2() {
    269
    270         // ------------- Construct using default pattern & default locale ------------
    271         converter = new DateLocaleConverter();
    272
    273         // Perform Tests
    274         convertValueNoPattern(converter, defaultShortDateValue, expectedValue);
    275         convertValueWithPattern(converter, defaultDateValue, defaultDatePattern, expectedValue);
    276         convertInvalid(converter, null);
    277         convertNull(converter, null);
    278
    279     }
    280
    281     /***
    282      * Test Converter(locPattern) constructor
    283      *
    284      * Uses the default locale, no default value
    285      *
    286      */
    287     public void testConstructor_3() {
    288
    289         // ------------- Construct using default pattern & default locale --------
    290         converter = new DateLocaleConverter(true);
    291
    292         // Perform Tests
    293         convertValueNoPattern(converter, defaultShortDateValue, expectedValue);
    294         convertValueWithPattern(converter, defaultDateValue, defaultDatePattern, expectedValue);
    295         convertInvalid(converter, null);
    296         convertNull(converter, null);
    297
    298
    299     }
    300
    301     /***
    302      * Test Converter(Locale) constructor
    303      */
    304     public void testConstructor_4() {
    305
    306         // ------------- Construct using specified Locale --------
    307         converter = new DateLocaleConverter(localizedLocale);
    308
    309         // Perform Tests
    310         convertValueNoPattern(converter, localizedShortDateValue, expectedValue);
    311         convertValueWithPattern(converter, localizedDateValue, defaultDatePattern, expectedValue);
    312         convertInvalid(converter, null);
    313         convertNull(converter, null);
    314
    315
    316     }
    317
    318
    319     /***
    320      * Test Converter(Locale, locPattern) constructor
    321      */
    322     public void testConstructor_5() {
    323
    324         // Skip this test if no valid symbols for the locale
    325         if (!validLocalDateSymbols) {
    326             log.error("Invalid locale symbols *** skipping testConstructor_5() **");
    327             return;
    328         }
    329
    330         // ------------- Construct using specified Locale --------
    331         converter = new DateLocaleConverter(localizedLocale, true);
    332
    333         // Perform Tests
    334         convertValueNoPattern(converter, localizedShortDateValue, expectedValue);
    335         convertValueWithPattern(converter, localizedDateValue, localizedDatePattern, expectedValue);
    336         convertInvalid(converter, null);
    337         convertNull(converter, null);
    338
    339
    340     }
    341
    342     /***
    343      * Test Converter(Locale, pattern) constructor
    344      */
    345     public void testConstructor_6() {
    346
    347         // ------------- Construct using specified Locale --------
    348         converter = new DateLocaleConverter(localizedLocale, defaultDatePattern);
    349
    350         // Perform Tests
    351         convertValueNoPattern(converter, localizedDateValue, expectedValue);
    352         convertValueWithPattern(converter, localizedDateValue, defaultDatePattern, expectedValue);
    353         convertInvalid(converter, null);
    354         convertNull(converter, null);
    355
    356     }
    357
    358     /***
    359      * Test Converter(Locale, pattern, locPattern) constructor
    360      */
    361     public void testConstructor_7() {
    362
    363         // Skip this test if no valid symbols for the locale
    364         if (!validLocalDateSymbols) {
    365             log.error("Invalid locale symbols *** skipping testConstructor_7() **");
    366             return;
    367         }
    368
    369         // ------------- Construct using specified Locale --------
    370         converter = new DateLocaleConverter(localizedLocale, localizedDatePattern, true);
    371
    372         // Perform Tests
    373         convertValueNoPattern(converter, localizedDateValue, expectedValue);
    374         convertValueWithPattern(converter, localizedDateValue, localizedDatePattern, expectedValue);
    375         convertInvalid(converter, null);
    376         convertNull(converter, null);
    377
    378     }
    379
    380     /***
    381      * Test Converter(defaultValue) constructor
    382      */
    383     public void testConstructor_8() {
    384
    385         // ------------- Construct using specified Locale --------
    386         converter = new DateLocaleConverter(defaultValue);
    387
    388         // Perform Tests
    389         convertValueNoPattern(converter, defaultShortDateValue, expectedValue);
    390         convertValueWithPattern(converter, defaultDateValue, defaultDatePattern, expectedValue);
    391         convertInvalid(converter, defaultValue);
    392         convertNull(converter, defaultValue);
    393
    394     }
    395
    396     /***
    397      * Test Converter(defaultValue, locPattern) constructor
    398      */
    399     public void testConstructor_9() {
    400
    401         // ------------- Construct using specified Locale --------
    402         converter = new DateLocaleConverter(defaultValue, true);
    403
    404         // Perform Tests
    405         convertValueNoPattern(converter, defaultShortDateValue, expectedValue);
    406         convertValueWithPattern(converter, defaultDateValue, defaultDatePattern, expectedValue);
    407         convertInvalid(converter, defaultValue);
    408         convertNull(converter, defaultValue);
    409
    410     }
    411
    412     /***
    413      * Test invalid date
    414      */
    415     public void testInvalidDate() {
    416
    417         converter = new DateLocaleConverter(defaultLocale);
    418
    419         try {
    420             converter.convert("01/10/2004", "dd-MM-yyyy");
    421         } catch (ConversionException e) {
    422             assertEquals("Parse Error", "Error parsing date '01/10/2004' at position=2", e.getMessage());
    423         }
    424
    425         try {
    426             converter.convert("01-10-2004X", "dd-MM-yyyy");
    427         } catch (ConversionException e) {
    428             assertEquals("Parse Length", "Date '01-10-2004X' contains unparsed characters from position=10", e.getMessage());
    429         }
    430
    431     }
    432
    433     /***
    434      * Test java.util.Date
    435      */
    436     public void testDateObject() {
    437         converter = new DateLocaleConverter(defaultLocale);
    438         assertEquals("java.util.Date", expectedValue, converter.convert(expectedValue));
    439     }
    440
    441     /***
    442      * Test Calendar
    443      */
    444     public void testCalendarObject() {
    445         converter = new DateLocaleConverter(defaultLocale);
    446         java.util.Calendar calendar = java.util.Calendar.getInstance();
    447         calendar.setTime((java.util.Date)expectedValue);
    448         assertEquals("java.util.Calendar", expectedValue, converter.convert(calendar));
    449     }
    450
    451 }
    452