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   * @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