    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 org.apache.commons.beanutils.ConvertUtils;
    21  import org.apache.commons.beanutils.ConversionException;
    22
    23  import junit.framework.TestCase;
    24
    25  /***
    26   * Test conversions of String[]->boolean[] and String->boolean[].
    27   *
    28   * <p>Note that the tests here don't rigorously test conversions of individual
    29   * strings to booleans, as the BooleanArrayConverter class uses a
    30   * BooleanConverter instance to do those conversions, and the BooleanConverter
    31   * class has its own unit tests. Here, the tests focus on the array-related
    32   * behaviour.</p>
    33   */
    34  public class BooleanArrayConverterTestCase extends TestCase {
    35
    36      public static final String[] STANDARD_TRUES = new String[] {
    37              "yes", "y", "true", "on", "1"
    38          };
    39
    40      public static final String[] STANDARD_FALSES = new String[] {
    41              "no", "n", "false", "off", "0"
    42          };
    43
    44
    45      public BooleanArrayConverterTestCase(String name) {
    46          super(name);
    47      }
    48
    49      /***
    50       * Check that an object of type String[] with valid boolean string
    51       * values gets converted nicely.
    52       */
    53      public void testStandardStringArrayConversion() {
    54          String[] values = {
    55              "true", "false",
    56              "yes", "no",
    57              "y", "n",
    58              "1", "0",
    59          };
    60
    61          BooleanArrayConverter converter = new BooleanArrayConverter();
    62          boolean[] results = (boolean[]) converter.convert(null, values);
    63
    64          assertNotNull(results);
    65          assertEquals(8, results.length);
    66          assertTrue(results[0]);
    67          assertFalse(results[1]);
    68          assertTrue(results[2]);
    69          assertFalse(results[3]);
    70          assertTrue(results[4]);
    71          assertFalse(results[5]);
    72          assertTrue(results[6]);
    73          assertFalse(results[7]);
    74      }
    75
    76      /***
    77       * Check that an object whose toString method returns a list of boolean
    78       * values gets converted nicely.
    79       */
    80      public void testStandardStringConversion() {
    81          BooleanArrayConverter converter = new BooleanArrayConverter();
    82
    83          StringBuffer input = new StringBuffer();
    84          boolean[] results;
    85
    86          // string has {}
    87          input.setLength(0);
    88          input.append("{true, 'yes', Y, 1, 'FALSE', \"no\", 'n', 0}");
    89          results = (boolean[]) converter.convert(null, input);
    90
    91          assertNotNull(results);
    92          assertEquals(8, results.length);
    93          assertTrue(results[0]);
    94          assertTrue(results[1]);
    95          assertTrue(results[2]);
    96          assertTrue(results[3]);
    97          assertFalse(results[4]);
    98          assertFalse(results[5]);
    99          assertFalse(results[6]);
    100         assertFalse(results[7]);
    101
    102         // string does not have {}
    103         input.setLength(0);
    104         input.append("'falsE', 'no', 'N', 0, \"truE\", yeS, 'y', '1'");
    105         results = (boolean[]) converter.convert(null, input);
    106
    107         assertNotNull(results);
    108         assertEquals(8, results.length);
    109         assertFalse(results[0]);
    110         assertFalse(results[1]);
    111         assertFalse(results[2]);
    112         assertFalse(results[3]);
    113         assertTrue(results[4]);
    114         assertTrue(results[5]);
    115         assertTrue(results[6]);
    116         assertTrue(results[7]);
    117
    118         // string has only one element, non-quoted
    119         input.setLength(0);
    120         input.append("y");
    121         results = (boolean[]) converter.convert(null, input);
    122
    123         assertNotNull(results);
    124         assertEquals(1, results.length);
    125         assertTrue(results[0]);
    126
    127         // string has only one element, quoted with ".
    128         input.setLength(0);
    129         input.append("\"1\"");
    130         results = (boolean[]) converter.convert(null, input);
    131
    132         assertNotNull(results);
    133         assertEquals(1, results.length);
    134         assertTrue(results[0]);
    135
    136         // string has only one element, quoted with '
    137         // Here we also pass an object of type String rather than the
    138         // StringBuffer
    139         results = (boolean[]) converter.convert(null, "'yes'");
    140
    141         assertNotNull(results);
    142         assertEquals(1, results.length);
    143         assertTrue(results[0]);
    144
    145     }
    146
    147     /***
    148      * Check that the user can specify non-standard true/false values by
    149      * providing a customised BooleanConverter.
    150      */
    151     public void testAdditionalStrings() {
    152         String[] trueStrings = {"sure"};
    153         String[] falseStrings = {"nope"};
    154         BooleanConverter bc = new BooleanConverter(
    155             trueStrings, falseStrings, BooleanConverter.NO_DEFAULT);
    156         BooleanArrayConverter converter = new BooleanArrayConverter(
    157             bc, BooleanArrayConverter.NO_DEFAULT);
    158
    159         boolean[] results = (boolean[]) converter.convert(null, "NOPE, sure, sure");
    160         assertNotNull(results);
    161         assertEquals(3, results.length);
    162         assertFalse(results[0]);
    163         assertTrue(results[1]);
    164         assertTrue(results[2]);
    165
    166         try {
    167             // the literal string 'true' should no longer be recognised as
    168             // a true value..
    169             converter.convert(null, "true");
    170             fail("Converting invalid string should have generated an exception");
    171         } catch(Exception ex) {
    172             // ok, expected
    173         }
    174     }
    175
    176     /***
    177      * Check that when the input string cannot be split into a String[], and
    178      * there is no default value then an exception is thrown.
    179      */
    180     public void testInvalidStringWithoutDefault() {
    181         BooleanArrayConverter converter = new BooleanArrayConverter();
    182         try {
    183             converter.convert(null, "true!");
    184             fail("Converting invalid string should have generated an exception");
    185         } catch (ConversionException expected) {
    186             // Exception is successful test
    187         }
    188     }
    189
    190     /***
    191      * Check that when the input string cannot be split into a String[], and
    192      * there is a default value then that default is returned.
    193      */
    194     public void testInvalidStringWithDefault() {
    195         boolean[] defaults = new boolean[1];
    196         BooleanArrayConverter converter = new BooleanArrayConverter(defaults);
    197         Object o = converter.convert(null, "true!");
    198         assertSame("Unexpected object returned for failed conversion", o, defaults);
    199     }
    200
    201     /***
    202      * Check that when one of the elements in a comma-separated string is not
    203      * a valid boolean, and there is no default value then an exception is thrown.
    204      */
    205     public void testInvalidElementWithoutDefault() {
    206         BooleanArrayConverter converter = new BooleanArrayConverter();
    207         try {
    208             converter.convert(null, "true,bogus");
    209             fail("Converting invalid string should have generated an exception");
    210         } catch (ConversionException expected) {
    211             // Exception is successful test
    212         }
    213     }
    214
    215     /***
    216      * Check that when one of the elements in a comma-separated string is not
    217      * a valid boolean, and there is a default value then the default value
    218      * is returned.
    219      * <p>
    220      * Note that the default value is for the complete array object returned,
    221      * not for the failed element.
    222      */
    223     public void testInvalidElementWithDefault() {
    224         boolean[] defaults = new boolean[1];
    225         BooleanArrayConverter converter = new BooleanArrayConverter(defaults);
    226         Object o = converter.convert(null, "true,bogus");
    227         assertSame("Unexpected object returned for failed conversion", o, defaults);
    228     }
    229
    230     /***
    231      * Check that when a custom BooleanConverter is used, and that converter
    232      * has a (per-element) default, then that element (and just that element)
    233      * is assigned the default value.
    234      * <p>
    235      * With the standard BooleanArrayConverter, if <i>any</i> of the elements
    236      * in the array are bad, then the array-wide default value is returned.
    237      * However by specifying a custom BooleanConverter which has a per-element
    238      * default, the unrecognised elements get that per-element default but the
    239      * others are converted as expected.
    240      */
    241     public void testElementDefault() {
    242         boolean[] defaults = new boolean[1];
    243         BooleanConverter bc = new BooleanConverter(Boolean.TRUE);
    244         BooleanArrayConverter converter = new BooleanArrayConverter(bc, defaults);
    245         boolean[] results = (boolean[]) converter.convert(null, "true,bogus");
    246
    247         assertEquals(2, results.length);
    248         assertTrue(results[0]);
    249         assertTrue(results[1]);
    250     }
    251
    252     /***
    253      * Check that registration of a custom converter works.
    254      */
    255     public void testRegistration() {
    256         String[] trueStrings = {"sure"};
    257         String[] falseStrings = {"nope"};
    258         BooleanConverter bc = new BooleanConverter(
    259             trueStrings, falseStrings, BooleanConverter.NO_DEFAULT);
    260
    261         BooleanArrayConverter converter = new BooleanArrayConverter(
    262             bc, BooleanArrayConverter.NO_DEFAULT);
    263
    264         ConvertUtils.register(converter, BooleanArrayConverter.MODEL);
    265         boolean[] sample = new boolean[0];
    266         boolean[] results = (boolean[]) ConvertUtils.convert("sure,nope", sample.getClass());
    267
    268         assertEquals(2, results.length);
    269         assertTrue(results[0]);
    270         assertFalse(results[1]);
    271     }
    272 }