View Javadoc
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 <Number>Converter classes.
33   *
34   * @version $Id$
35   */
36  
37  public abstract class NumberConverterTestBase extends TestCase {
38  
39      /** Test Number values */
40      protected Number[] numbers = new Number[4];
41  
42      // ------------------------------------------------------------------------
43  
44      public NumberConverterTestBase(final String name) {
45          super(name);
46      }
47  
48      // ------------------------------------------------------------------------
49  
50      protected abstract NumberConverter makeConverter();
51      protected abstract NumberConverter makeConverter(Object defaultValue);
52      protected abstract Class<?> getExpectedType();
53  
54      // ------------------------------------------------------------------------
55  
56      /**
57       * Assumes ConversionException in response to covert(getExpectedType(),null).
58       */
59      public void testConvertNull() {
60          try {
61              makeConverter().convert(getExpectedType(),null);
62              fail("Expected ConversionException");
63          } catch(final ConversionException e) {
64              // expected
65          }
66      }
67  
68      /**
69       * Assumes convert(getExpectedType(),Number) returns some non-null
70       * instance of getExpectedType().
71       */
72      public void testConvertNumber() {
73          final String[] message= {
74              "from Byte",
75              "from Short",
76              "from Integer",
77              "from Long",
78              "from Float",
79              "from Double",
80              "from BigDecimal",
81              "from BigInteger",
82              "from Integer array",
83          };
84  
85          final Object[] number = {
86              new Byte((byte)7),
87              new Short((short)8),
88              new Integer(9),
89              new Long(10),
90              new Float(11.1),
91              new Double(12.2),
92              new BigDecimal("17.2"),
93              new BigInteger("33"),
94              new Integer[] {new Integer(3), new Integer(2), new Integer(1)}
95          };
96  
97          for(int i=0;i<number.length;i++) {
98              final Object val = makeConverter().convert(getExpectedType(),number[i]);
99              assertNotNull("Convert " + message[i] + " should not be null",val);
100             assertTrue(
101                 "Convert " + message[i] + " should return a " + getExpectedType().getName(),
102                 getExpectedType().isInstance(val));
103         }
104     }
105     /**
106      * Convert Number --> String (using a Pattern, with default and specified Locales)
107      */
108     public void testNumberToStringPattern() {
109 
110         // Re-set the default Locale to Locale.US
111         final Locale defaultLocale = Locale.getDefault();
112         Locale.setDefault(Locale.US);
113 
114         final NumberConverter converter = makeConverter();
115         converter.setPattern("[0,0.0];(0,0.0)");
116 
117         // Default Locale
118         assertEquals("Default Locale " + numbers[0], "(12.0)", converter.convert(String.class, numbers[0]));
119         assertEquals("Default Locale " + numbers[1], "[13.0]", converter.convert(String.class, numbers[1]));
120 
121         // Locale.GERMAN
122         converter.setLocale(Locale.GERMAN);
123         assertEquals("Locale.GERMAN " + numbers[2], "(22,0)", converter.convert(String.class, numbers[2]));
124         assertEquals("Locale.GERMAN " + numbers[3], "[23,0]", converter.convert(String.class, numbers[3]));
125 
126         // Restore the default Locale
127         Locale.setDefault(defaultLocale);
128     }
129 
130     /**
131      * Convert Number --> String (using default and specified Locales)
132      */
133     public void testNumberToStringLocale() {
134 
135         // Re-set the default Locale to Locale.US
136         final Locale defaultLocale = Locale.getDefault();
137         Locale.setDefault(Locale.US);
138 
139         final NumberConverter converter = makeConverter();
140         converter.setUseLocaleFormat(true);
141 
142         // Default Locale
143         assertEquals("Default Locale " + numbers[0], "-12", converter.convert(String.class, numbers[0]));
144         assertEquals("Default Locale " + numbers[1], "13",  converter.convert(String.class, numbers[1]));
145 
146         // Locale.GERMAN
147         converter.setLocale(Locale.GERMAN);
148         assertEquals("Locale.GERMAN " + numbers[2], "-22", converter.convert(String.class, numbers[2]));
149         assertEquals("Locale.GERMAN " + numbers[3], "23",  converter.convert(String.class, numbers[3]));
150 
151         // Restore the default Locale
152         Locale.setDefault(defaultLocale);
153     }
154 
155     /**
156      * Convert Array --> Number
157      */
158     public void testStringArrayToInteger() {
159 
160         final Integer defaultValue = new Integer(-1);
161         final NumberConverter converter = makeConverter(defaultValue);
162 
163         // Default Locale
164         assertEquals("Valid First",   new Integer(5), converter.convert(Integer.class, new String[] {"5", "4", "3"}));
165         assertEquals("Invalid First", defaultValue,   converter.convert(Integer.class, new String[] {"FOO", "1", "2"}));
166         assertEquals("Null First",    defaultValue,   converter.convert(Integer.class, new String[] {null, "1", "2"}));
167         assertEquals("Long Array",    new Integer(9), converter.convert(Integer.class, new long[] {9, 2, 6}));
168     }
169 
170     /**
171      * Convert Number --> String (default conversion)
172      */
173     public void testNumberToStringDefault() {
174 
175         final NumberConverter converter = makeConverter();
176 
177         // Default Number --> String conversion
178         assertEquals("Default Convert " + numbers[0], numbers[0].toString(), converter.convert(String.class, numbers[0]));
179         assertEquals("Default Convert " + numbers[1], numbers[1].toString(), converter.convert(String.class, numbers[1]));
180 
181     }
182 
183     /**
184      * Convert String --> Number (using a Pattern, with default and specified Locales)
185      */
186     public void testStringToNumberPattern() {
187 
188         // Re-set the default Locale to Locale.US
189         final Locale defaultLocale = Locale.getDefault();
190         Locale.setDefault(Locale.US);
191 
192         final NumberConverter converter = makeConverter();
193         converter.setPattern("[0,0];(0,0)");
194 
195         // Default Locale
196         assertEquals("Default Locale " + numbers[0], numbers[0], converter.convert(getExpectedType(), "(1,2)"));
197         assertEquals("Default Locale " + numbers[1], numbers[1], converter.convert(getExpectedType(), "[1,3]"));
198 
199         // Locale.GERMAN
200         converter.setLocale(Locale.GERMAN);
201         assertEquals("Locale.GERMAN " + numbers[2], numbers[2], converter.convert(getExpectedType(), "(2.2)"));
202         assertEquals("Locale.GERMAN " + numbers[3], numbers[3], converter.convert(getExpectedType(), "[2.3]"));
203 
204         // Invalid Value
205         try {
206             converter.convert(getExpectedType(), "1,2");
207             fail("Expected invalid value to cause ConversionException");
208         } catch (final Exception e) {
209             // expected result
210         }
211 
212         // Invalid Type (will try via String)
213         final Object obj =  new Object() {
214             @Override
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 (final 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         final Locale defaultLocale = Locale.getDefault();
237         Locale.setDefault(Locale.US);
238 
239         final 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 (final 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 (final 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         final 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 (final Exception e) {
287             // expected result
288         }
289     }
290 
291     /**
292      * Convert String --> Number if the target type is not defined. Then the
293      * default type should be used.
294      */
295     public void testStringToNumberDefaultType() {
296         final NumberConverter converter = makeConverter();
297         converter.setUseLocaleFormat(false);
298 
299         assertEquals("Default Convert " + numbers[0], numbers[0], converter.convert(null, numbers[0].toString()));
300     }
301 
302     /**
303      * Convert Boolean --> Number (default conversion)
304      */
305     public void testBooleanToNumberDefault() {
306 
307         final NumberConverter converter = makeConverter();
308 
309         // Other type --> String conversion
310         assertEquals("Boolean.FALSE to Number ", 0, ((Number)converter.convert(getExpectedType(), Boolean.FALSE)).intValue());
311         assertEquals("Boolean.TRUE to Number ",  1, ((Number)converter.convert(getExpectedType(), Boolean.TRUE)).intValue());
312 
313     }
314 
315     /**
316      * Convert Date --> Long
317      */
318     public void testDateToNumber() {
319 
320         final NumberConverter converter = makeConverter();
321 
322         final Date dateValue = new Date();
323         final long longValue = dateValue.getTime();
324 
325         // Date --> Long conversion
326         assertEquals("Date to Long", new Long(longValue), converter.convert(Long.class, dateValue));
327 
328         // Date --> Integer
329         try {
330             converter.convert(Integer.class, dateValue);
331             fail("Date to Integer - expected a ConversionException");
332         } catch (final ConversionException e) {
333             // expected result - too large for Integer
334         }
335 
336     }
337 
338     /**
339      * Convert Calendar --> Long
340      */
341     public void testCalendarToNumber() {
342 
343         final NumberConverter converter = makeConverter();
344 
345         final Calendar calendarValue = Calendar.getInstance();
346         final long longValue = calendarValue.getTime().getTime();
347 
348         // Calendar --> Long conversion
349         assertEquals("Calendar to Long", new Long(longValue), converter.convert(Long.class, calendarValue));
350 
351         // Calendar --> Integer
352         try {
353             converter.convert(Integer.class, calendarValue);
354             fail("Calendar to Integer - expected a ConversionException");
355         } catch (final ConversionException e) {
356             // expected result - too large for Integer
357         }
358 
359     }
360 
361     /**
362      * Convert Other --> String (default conversion)
363      */
364     public void testOtherToStringDefault() {
365 
366         final NumberConverter converter = makeConverter();
367 
368         // Other type --> String conversion
369         assertEquals("Default Convert ", "ABC", converter.convert(String.class, new StringBuilder("ABC")));
370 
371     }
372 
373     /**
374      * Convert Number --> String (using default and specified Locales)
375      */
376     public void testInvalidDefault() {
377 
378         final Object defaultvalue = numbers[0];
379         final NumberConverter converter = makeConverter(defaultvalue);
380 
381         // Default String --> Number conversion
382         assertEquals("Invalid null ", defaultvalue, converter.convert(getExpectedType(), null));
383         assertEquals("Default XXXX ", defaultvalue, converter.convert(getExpectedType(), "XXXX"));
384     }
385 
386     /**
387      * Convert Number --> String (using default and specified Locales)
388      */
389     public void testInvalidException() {
390 
391         final NumberConverter converter = makeConverter();
392 
393         try {
394             converter.convert(getExpectedType(), null);
395             fail("Null test, expected ConversionException");
396         } catch (final ConversionException e) {
397             // expected result
398         }
399         try {
400             converter.convert(getExpectedType(), "XXXX");
401             fail("Invalid test, expected ConversionException");
402         } catch (final ConversionException e) {
403             // expected result
404         }
405     }
406 
407     /**
408      * Test specifying an invalid type.
409      */
410     public void testInvalidType() {
411 
412         final NumberConverter converter = makeConverter();
413 
414         try {
415             converter.convert(Object.class, numbers[0]);
416             fail("Invalid type test, expected ConversionException");
417         } catch (final ConversionException e) {
418             // expected result
419         }
420     }
421 
422     /**
423      * Tests a conversion to an unsupported type if a default value is set.
424      */
425     public void testInvalidTypeWithDefault() {
426 
427         final NumberConverter converter = makeConverter(42);
428 
429         try {
430             converter.convert(Object.class, numbers[0]);
431             fail("Invalid type with default test, expected ConversionException");
432         } catch(final ConversionException e) {
433             // expected result
434         }
435     }
436 
437 }
438