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.valid;
016    
017    import static org.easymock.EasyMock.expect;
018    
019    import java.math.BigDecimal;
020    import java.math.BigInteger;
021    import java.util.Locale;
022    
023    import org.apache.tapestry.IPage;
024    import org.apache.tapestry.form.IFormComponent;
025    import org.testng.annotations.Configuration;
026    import org.testng.annotations.Test;
027    
028    /**
029     * Test the {@link NumberValidator}.
030     * 
031     * @author Howard Lewis Ship
032     * @since 1.0.8
033     */
034    @Test(sequential=true)
035    public class TestNumberValidator extends BaseValidatorTestCase
036    {
037        private NumberValidator v = new NumberValidator();
038    
039        @Configuration(afterTestMethod = true)
040        public void reset()
041        {
042            v.setInvalidIntegerFormatMessage(null);
043            v.setInvalidNumericFormatMessage(null);
044            v.setMaximum(null);
045            v.setMinimum(null);
046            v.setNumberRangeMessage(null);
047            v.setNumberTooLargeMessage(null);
048            v.setNumberTooSmallMessage(null);
049            v.setRequired(false);
050            v.setRequiredMessage(null);
051        }
052        
053        private void testPassThru(Class valueTypeClass, Number input) throws ValidatorException
054        {
055            IFormComponent field = newField();
056            IPage page = newMock(IPage.class);
057            
058            expect(field.getPage()).andReturn(page).anyTimes();
059            
060            expect(page.getLocale()).andReturn(Locale.GERMAN).anyTimes();
061            
062            expect(field.getDisplayName()).andReturn(null).anyTimes();
063            
064            replay();
065            
066            testPassThru(field, valueTypeClass, input);
067    
068            verify();
069        }
070    
071        private void testPassThru(IFormComponent field, Class valueTypeClass, Number input)
072                throws ValidatorException
073        {
074            v.setValueTypeClass(valueTypeClass);
075    
076            String s = v.toString(field, input);
077    
078            Object o = v.toObject(field, s);
079            
080            assertEquals(input, o);
081        }
082    
083        public void testShort() throws ValidatorException
084        {
085            testPassThru(Short.class, new Short((short) 1000));
086        }
087    
088        public void testInteger() throws ValidatorException
089        {
090            testPassThru(Integer.class, new Integer(373));
091        }
092    
093        public void testByte() throws ValidatorException
094        {
095            testPassThru(Byte.class, new Byte((byte) 131));
096        }
097    
098        public void testFloat() throws ValidatorException
099        {
100            testPassThru(Float.class, new Float(3.1415));
101        }
102    
103        public void testDouble() throws ValidatorException
104        {
105            testPassThru(Double.class, new Double(348348.484854848));
106        }
107    
108        public void testLong() throws ValidatorException
109        {
110            testPassThru(Long.class, new Long(37373218723l));
111        }
112    
113        public void testInRange() throws ValidatorException
114        {
115            v.setMinimum(new Integer(100));
116            v.setMaximum(new Integer(200));
117    
118            testPassThru(Integer.class, new Integer(150));
119        }
120    
121        public void testUnderMinimum()
122        {
123            IFormComponent field = newField("testUnderMinimum");
124    
125            replay();
126    
127            v.setMinimum(new Integer(100));
128            v.setMaximum(new Integer(200));
129    
130            try
131            {
132                testPassThru(field, Integer.class, new Integer(50));
133    
134                unreachable();
135            }
136            catch (ValidatorException ex)
137            {
138                assertEquals("testUnderMinimum must not be smaller than 100.", ex.getMessage());
139                assertEquals(ValidationConstraint.TOO_SMALL, ex.getConstraint());
140            }
141    
142            verify();
143        }
144    
145        public void testOverrideNumberTooSmallMessage()
146        {
147            IFormComponent field = newField("underMinimum");
148    
149            replay();
150    
151            v.setMinimum(new Integer(100));
152            v.setNumberTooSmallMessage("Anything under 100 for {0} is worth jack.");
153    
154            try
155            {
156                testPassThru(field, Integer.class, new Integer(50));
157                unreachable();
158            }
159            catch (ValidatorException ex)
160            {
161                assertEquals("Anything under 100 for underMinimum is worth jack.", ex.getMessage());
162            }
163    
164            verify();
165        }
166    
167        public void testOverMaximum()
168        {
169            IFormComponent field = newField("overMaximum");
170    
171            replay();
172    
173            v.setMinimum(new Integer(100));
174            v.setMaximum(new Integer(200));
175    
176            try
177            {
178                testPassThru(field, Integer.class, new Integer(250));
179    
180                unreachable();
181            }
182            catch (ValidatorException ex)
183            {
184                assertEquals("overMaximum must not be larger than 200.", ex.getMessage());
185                assertEquals(ValidationConstraint.TOO_LARGE, ex.getConstraint());
186            }
187    
188            verify();
189        }
190    
191        public void testOverrideNumberTooLargeMessage()
192        {
193            IFormComponent field = newField("overMaximum");
194    
195            replay();
196    
197            v.setMaximum(new Integer(200));
198            v.setNumberTooLargeMessage("You think I want a value larger than {1} for {0}?");
199    
200            try
201            {
202                testPassThru(field, Integer.class, new Integer(1000));
203                unreachable();
204            }
205            catch (ValidatorException ex)
206            {
207                assertEquals("You think I want a value larger than 200 for overMaximum?", ex
208                        .getMessage());
209            }
210    
211            verify();
212        }
213    
214        public void testInvalidFormat()
215        {
216            v.setValueTypeClass(Integer.class);
217            IFormComponent field = newField("invalidFormat");
218    
219            replay();
220    
221            try
222            {
223                v.toObject(field, "xyz");
224                unreachable();
225            }
226            catch (ValidatorException ex)
227            {
228                assertEquals(ex.getMessage(), "invalidFormat must be a numeric value. ");
229                assertEquals(ValidationConstraint.NUMBER_FORMAT, ex.getConstraint());
230            }
231    
232            verify();
233        }
234    
235        public void testOverrideInvalidNumericFormatMessage()
236        {
237            v.setValueTypeClass(Integer.class);
238            v.setInvalidNumericFormatMessage("Dude, gimme a number for {0}.");
239    
240            IFormComponent field = newField("invalidFormat");
241    
242            replay();
243    
244            try
245            {
246                v.toObject(field, "xyz");
247                unreachable();
248            }
249            catch (ValidatorException ex)
250            {
251                assertEquals("Dude, gimme a number for invalidFormat.", ex.getMessage());
252                assertEquals(ValidationConstraint.NUMBER_FORMAT, ex.getConstraint());
253            }
254    
255            verify();
256        }
257    
258        public void testBigInteger() throws ValidatorException
259        {
260            testPassThru(BigInteger.class, new BigInteger(
261                    "234905873490587234905724908252390487590234759023487523489075"));
262        }
263    
264        public void testBigDecimal() throws ValidatorException
265        {
266            testPassThru(BigDecimal.class, new BigDecimal(
267                    "-29574923857342908744.19058734289734907543289752345897234590872349085"));
268        }
269    
270        /** @since 3.0 * */
271    
272        private void checkAdaptorType(int expectedType, Class numberType)
273        {
274            NumberValidator.NumberStrategy a = NumberValidator.getStrategy(numberType);
275    
276            assertEquals(expectedType, a.getNumberType());
277        }
278    
279        /** @since 3.0 * */
280    
281        public void testAdaptorTypes() throws Exception
282        {
283            checkAdaptorType(NumberValidator.NUMBER_TYPE_INTEGER, Byte.class);
284            checkAdaptorType(NumberValidator.NUMBER_TYPE_INTEGER, Short.class);
285            checkAdaptorType(NumberValidator.NUMBER_TYPE_INTEGER, Integer.class);
286            checkAdaptorType(NumberValidator.NUMBER_TYPE_INTEGER, Long.class);
287            checkAdaptorType(NumberValidator.NUMBER_TYPE_INTEGER, BigInteger.class);
288            checkAdaptorType(NumberValidator.NUMBER_TYPE_REAL, Float.class);
289            checkAdaptorType(NumberValidator.NUMBER_TYPE_REAL, Double.class);
290            checkAdaptorType(NumberValidator.NUMBER_TYPE_REAL, BigDecimal.class);
291        }
292    
293        /** @since 3.0 * */
294    
295        private void checkCompare(Number left, Number right)
296        {
297            NumberValidator.NumberStrategy a = NumberValidator.getStrategy(left.getClass());
298    
299            assertEquals(0, a.compare(left, right));
300        }
301    
302        public void testByteCompare()
303        {
304            checkCompare(new Byte((byte) 3), new Long(3));
305        }
306    
307        public void testShortCompare()
308        {
309            checkCompare(new Short((short) 14), new Double(14.0));
310        }
311    
312        public void testIntegerCompare()
313        {
314            checkCompare(new Integer(19), new Long(19));
315        }
316    
317        public void testLongCompare()
318        {
319            checkCompare(new Long(-22), new Short((short) -22));
320        }
321    
322        public void testBigIntegerCompare()
323        {
324            checkCompare(new BigInteger("300"), new Long("300"));
325        }
326    
327        public void testFloatCompare()
328        {
329            checkCompare(new Float("0"), new Double("0"));
330        }
331    
332        public void testDoubleCompare()
333        {
334            checkCompare(new Double("0"), new Float("0"));
335        }
336    
337        public void testBigDecimalCompare()
338        {
339            checkCompare(new BigDecimal("-137.75"), new Double("-137.75"));
340        }
341    }