001    // Copyright 2004, 2005 The Apache Software Foundation
002    //
003    // Licensed under the Apache License, Version 2.0 (the "License");
004    // you may not use this file except in compliance with the License.
005    // You may obtain a copy of the License at
006    //
007    //     http://www.apache.org/licenses/LICENSE-2.0
008    //
009    // Unless required by applicable law or agreed to in writing, software
010    // distributed under the License is distributed on an "AS IS" BASIS,
011    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012    // See the License for the specific language governing permissions and
013    // limitations under the License.
014    
015    package org.apache.tapestry.coerce;
016    
017    import static org.easymock.EasyMock.expect;
018    
019    import java.util.Collections;
020    import java.util.Date;
021    
022    import org.apache.hivemind.ApplicationRuntimeException;
023    import org.apache.tapestry.BaseComponentTestCase;
024    import org.testng.annotations.Test;
025    
026    /**
027     * Tests for {@link org.apache.tapestry.coerce.ValueConverterImpl}.
028     * 
029     * @author Howard M. Lewis Ship
030     * @since 4.0
031     */
032    @Test
033    public class TestValueConverter extends BaseComponentTestCase
034    {
035    
036        public void testAlreadyCorrectType()
037        {
038            ValueConverter v = new ValueConverterImpl();
039    
040            Object input = new Integer(7);
041    
042            assertSame(input, v.coerceValue(input, Integer.class));
043            assertSame(input, v.coerceValue(input, Number.class));
044        }
045    
046        /**
047         * Check that primitive types are converted to equivalent wrapper classes for the assignable
048         * check. Ok, maybe we should check all the primitive types.
049         */
050    
051        public void testAlreadyCorrectPrimitiveType()
052        {
053            ValueConverter v = new ValueConverterImpl();
054    
055            Object input = new Integer(9);
056    
057            assertSame(input, v.coerceValue(input, int.class));
058        }
059    
060        public void testNoConverter()
061        {
062            ValueConverter v = new ValueConverterImpl();
063    
064            try
065            {
066                v.coerceValue("FRED", Date.class);
067                unreachable();
068            }
069            catch (ApplicationRuntimeException ex)
070            {
071                assertEquals(CoerceMessages.noConverter(String.class, Date.class), ex.getMessage());
072            }
073        }
074    
075        /**
076         * Verify that the message generated for a primtive type identifies the wrapper class.
077         */
078    
079        public void testNoConverterPrimitive()
080        {
081            ValueConverter v = new ValueConverterImpl();
082    
083            try
084            {
085                v.coerceValue(new Object(), int.class);
086                unreachable();
087            }
088            catch (ApplicationRuntimeException ex)
089            {
090                assertEquals(CoerceMessages.noConverter(Object.class, Integer.class), ex.getMessage());
091            }
092        }
093    
094        public void testConverterFound()
095        {
096            TypeConverter tc = newMock(TypeConverter.class);
097    
098            Object input = new Integer(7);
099            Object output = "SEVEN";
100    
101            expect(tc.convertValue(input)).andReturn(output);
102    
103            replay();
104    
105            ValueConverterImpl v = new ValueConverterImpl();
106    
107            TypeConverterContribution contrib = new TypeConverterContribution();
108    
109            contrib.setSubjectClass(String.class);
110            contrib.setConverter(tc);
111    
112            v.setContributions(Collections.singletonList(contrib));
113    
114            v.initializeService();
115    
116            assertSame(output, v.coerceValue(input, String.class));
117    
118            verify();
119        }
120    
121        public void testConverterFoundForNullValue()
122        {
123            TypeConverter tc = newMock(TypeConverter.class);
124    
125            Object output = "NULL";
126    
127            expect(tc.convertValue(null)).andReturn(output);
128    
129            replay();
130    
131            ValueConverterImpl v = new ValueConverterImpl();
132    
133            TypeConverterContribution contrib = new TypeConverterContribution();
134    
135            contrib.setSubjectClass(String.class);
136            contrib.setConverter(tc);
137    
138            v.setContributions(Collections.singletonList(contrib));
139    
140            v.initializeService();
141    
142            assertSame(output, v.coerceValue(null, String.class));
143    
144            verify();
145        }
146    
147        public void testNoConverterFoundForNullValue()
148        {
149            ValueConverterImpl v = new ValueConverterImpl();
150    
151            assertNull(v.coerceValue(null, Date.class));
152        }
153    
154        public void testStringToNumberPrimitive()
155        {
156            ValueConverterImpl v = new ValueConverterImpl();
157    
158            Object result = v.coerceValue("123", int.class);
159    
160            assertEquals(new Integer(123), result);
161        }
162    
163        public void testStringToNumberWrapper()
164        {
165            ValueConverterImpl v = new ValueConverterImpl();
166    
167            Object result = v.coerceValue("47347437", Long.class);
168    
169            assertEquals(new Long(47347437), result);
170        }
171    
172        public void testInvalidStringToNumber()
173        {
174            ValueConverterImpl v = new ValueConverterImpl();
175    
176            try
177            {
178                v.coerceValue("fred12345", double.class);
179                unreachable();
180            }
181            catch (ApplicationRuntimeException ex)
182            {
183                assertExceptionSubstring(
184                        ex,
185                        "Unable to convert 'fred12345' to an instance of java.lang.Double");
186            }
187    
188        }
189    
190        public void testStringToNonNumericPrimitive()
191        {
192            TypeConverter tc = newMock(TypeConverter.class);
193    
194            Object input = "false";
195            Object output = Boolean.FALSE;
196    
197            expect(tc.convertValue(input)).andReturn(output);
198    
199            replay();
200    
201            ValueConverterImpl v = new ValueConverterImpl();
202    
203            TypeConverterContribution contrib = new TypeConverterContribution();
204    
205            contrib.setSubjectClass(Boolean.class);
206            contrib.setConverter(tc);
207    
208            v.setContributions(Collections.singletonList(contrib));
209    
210            v.initializeService();
211    
212            assertSame(output, v.coerceValue(input, Boolean.class));
213    
214            verify();
215        }
216    
217        public void testNumberToNumber()
218        {
219            ValueConverterImpl v = new ValueConverterImpl();
220    
221            Object result = v.coerceValue(new Integer(123), long.class);
222    
223            assertEquals(new Long(123), result);
224        }
225    }