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    *      https://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  package org.apache.commons.validator.routines;
18  
19  import static org.junit.jupiter.api.Assertions.assertEquals;
20  import static org.junit.jupiter.api.Assertions.assertFalse;
21  import static org.junit.jupiter.api.Assertions.assertNotNull;
22  import static org.junit.jupiter.api.Assertions.assertNull;
23  import static org.junit.jupiter.api.Assertions.assertTrue;
24  import static org.junit.jupiter.api.Assertions.fail;
25  
26  import java.io.ByteArrayInputStream;
27  import java.io.ByteArrayOutputStream;
28  import java.io.ObjectInputStream;
29  import java.io.ObjectOutputStream;
30  import java.util.Calendar;
31  import java.util.Date;
32  import java.util.Locale;
33  import java.util.TimeZone;
34  
35  import org.junit.jupiter.api.AfterEach;
36  import org.junit.jupiter.api.Test;
37  
38  /**
39   * Base Calendar Test Case.
40   */
41  public abstract class AbstractCalendarValidatorTest {
42  
43      /**
44       * Create a calendar instance for a specified time zone, date and time.
45       *
46       * @param zone The time zone
47       * @param date The date in yyyyMMdd format
48       * @param time the time in HH:mm:ss format
49       * @return the new Calendar instance.
50       */
51      protected static Calendar createCalendar(final TimeZone zone, final int date, final int time) {
52          final Calendar calendar = zone == null ? Calendar.getInstance() : Calendar.getInstance(zone);
53          final int year = date / 10000 * 10000;
54          final int mth = date / 100 * 100 - year;
55          final int day = date - (year + mth);
56          final int hour = time / 10000 * 10000;
57          final int min = time / 100 * 100 - hour;
58          final int sec = time - (hour + min);
59          calendar.set(Calendar.YEAR, year / 10000);
60          calendar.set(Calendar.MONTH, mth / 100 - 1);
61          calendar.set(Calendar.DATE, day);
62          calendar.set(Calendar.HOUR_OF_DAY, hour / 10000);
63          calendar.set(Calendar.MINUTE, min / 100);
64          calendar.set(Calendar.SECOND, sec);
65          calendar.set(Calendar.MILLISECOND, 0);
66          return calendar;
67      }
68  
69      /**
70       * Create a date instance for a specified time zone, date and time.
71       *
72       * @param zone The time zone
73       * @param date The date in yyyyMMdd format
74       * @param time the time in HH:mm:ss format
75       * @return the new Date instance.
76       */
77      protected static Date createDate(final TimeZone zone, final int date, final int time) {
78          final Calendar calendar = createCalendar(zone, date, time);
79          return calendar.getTime();
80      }
81  
82      protected AbstractCalendarValidator validator;
83      protected String[] patternValid = { "2005-01-01", "2005-12-31", "2004-02-29" // valid leap
84              , "2005-04-30", "05-12-31", "2005-1-1", "05-1-1" };
85      protected String[] localeValid = { "01/01/2005", "12/31/2005", "02/29/2004" // valid leap
86              , "04/30/2005", "12/31/05", "1/1/2005", "1/1/05" };
87      protected Date[] patternExpect = { createDate(null, 20050101, 0), createDate(null, 20051231, 0), createDate(null, 20040229, 0),
88              createDate(null, 20050430, 0), createDate(null, 20051231, 0), createDate(null, 20050101, 0), createDate(null, 20050101, 0) };
89  
90      protected String[] patternInvalid = { "2005-00-01" // zero month
91              , "2005-01-00" // zero day
92              , "2005-13-03" // month invalid
93              , "2005-04-31" // invalid day
94              , "2005-03-32" // invalid day
95              , "2005-02-29" // invalid leap
96              , "200X-01-01" // invalid char
97              , "2005-0X-01" // invalid char
98              , "2005-01-0X" // invalid char
99              , "01/01/2005" // invalid pattern
100             , "2005-01" // invalid pattern
101             , "2005--01" // invalid pattern
102             , "2005-01-" }; // invalid pattern
103 
104     protected String[] localeInvalid = { "01/00/2005" // zero month
105             , "00/01/2005" // zero day
106             , "13/01/2005" // month invalid
107             , "04/31/2005" // invalid day
108             , "03/32/2005" // invalid day
109             , "02/29/2005" // invalid leap
110             , "01/01/200X" // invalid char
111             , "01/0X/2005" // invalid char
112             , "0X/01/2005" // invalid char
113             , "01-01-2005" // invalid pattern
114             , "01/2005" // invalid pattern
115             // -------- ,"/01/2005" ---- passes on some JDK
116             , "01//2005" }; // invalid pattern
117 
118     /**
119      * Tear down
120      */
121     @AfterEach
122     protected void tearDown() {
123         validator = null;
124     }
125 
126     /**
127      * Test Invalid Dates with "locale" validation
128      */
129     @Test
130     void testFormat() {
131 
132         // Create a Date or Calendar
133         final Object test = validator.parse("2005-11-28", "yyyy-MM-dd", null, null);
134         assertNotNull(test, "Test Date");
135         assertEquals("28.11.05", validator.format(test, "dd.MM.yy"), "Format pattern");
136         assertEquals("11/28/05", validator.format(test, Locale.US), "Format locale");
137     }
138 
139     /**
140      * Test Invalid Dates with "locale" validation
141      */
142     @Test
143     void testLocaleInvalid() {
144         for (int i = 0; i < localeInvalid.length; i++) {
145             final String text = i + " value=[" + localeInvalid[i] + "] passed ";
146             final Object date = validator.parse(localeInvalid[i], null, Locale.US, null);
147             assertNull(date, "validateObj() " + text + date);
148             assertFalse(validator.isValid(localeInvalid[i], Locale.US), "isValid() " + text);
149         }
150     }
151 
152     /**
153      * Test Valid Dates with "locale" validation
154      */
155     @Test
156     void testLocaleValid() {
157         for (int i = 0; i < localeValid.length; i++) {
158             final String text = i + " value=[" + localeValid[i] + "] failed ";
159             Object date = validator.parse(localeValid[i], null, Locale.US, null);
160             assertNotNull(date, "validateObj() " + text + date);
161             assertTrue(validator.isValid(localeValid[i], Locale.US), "isValid() " + text);
162             if (date instanceof Calendar) {
163                 date = ((Calendar) date).getTime();
164             }
165             assertEquals(patternExpect[i], date, "compare " + text);
166         }
167     }
168 
169     /**
170      * Test Invalid Dates with "pattern" validation
171      */
172     @Test
173     void testPatternInvalid() {
174         for (int i = 0; i < patternInvalid.length; i++) {
175             final String text = i + " value=[" + patternInvalid[i] + "] passed ";
176             final Object date = validator.parse(patternInvalid[i], "yy-MM-dd", null, null);
177             assertNull(date, "validateObj() " + text + date);
178             assertFalse(validator.isValid(patternInvalid[i], "yy-MM-dd"), "isValid() " + text);
179         }
180     }
181 
182     /**
183      * Test Valid Dates with "pattern" validation
184      */
185     @Test
186     void testPatternValid() {
187         for (int i = 0; i < patternValid.length; i++) {
188             final String text = i + " value=[" + patternValid[i] + "] failed ";
189             Object date = validator.parse(patternValid[i], "yy-MM-dd", null, null);
190             assertNotNull(date, "validateObj() " + text + date);
191             assertTrue(validator.isValid(patternValid[i], "yy-MM-dd"), "isValid() " + text);
192             if (date instanceof Calendar) {
193                 date = ((Calendar) date).getTime();
194             }
195             assertEquals(patternExpect[i], date, "compare " + text);
196         }
197     }
198 
199     /**
200      * Test validator serialization.
201      */
202     @Test
203     void testSerialization() {
204         // Serialize the check digit routine
205         final ByteArrayOutputStream baos = new ByteArrayOutputStream();
206         try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
207             oos.writeObject(validator);
208             oos.flush();
209         } catch (final Exception e) {
210             fail(validator.getClass().getName() + " error during serialization: " + e);
211         }
212 
213         // Deserialize the test object
214         Object result = null;
215         try (ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray())) {
216             final ObjectInputStream ois = new ObjectInputStream(bais);
217             result = ois.readObject();
218         } catch (final Exception e) {
219             fail(validator.getClass().getName() + " error during deserialization: " + e);
220         }
221         assertNotNull(result);
222     }
223 
224 }