1 /*
2  * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 /**
25  * @test
26  * @bug 4326988 6990146 8231213
27  * @summary test SimpleDateFormat, check its pattern in the constructor
28  * @run testng/othervm SimpleDateFormatPatternTest
29  */
30 package test.java.text.Format.DateFormat;
31 
32 import android.platform.test.annotations.LargeTest;
33 
34 import java.lang.IllegalArgumentException;
35 import java.text.DateFormat;
36 import java.text.DateFormatSymbols;
37 import java.text.SimpleDateFormat;
38 import java.util.Locale;
39 
40 import org.testng.annotations.DataProvider;
41 import org.testng.annotations.Test;
42 
43 public class SimpleDateFormatPatternTest {
44     private static String[] validPat = {
45             "yyyy-MM-dd h.mm.ss.a z",
46             "yyyy'M'd' ahh'mm'ss' z",
47             "dd MMMM yyyy hh:mm:ss",
48             "d MMM yy HH:mm:ss",
49             "dd/MM/yyyy HH:mm:ss",
50             "d' / 'MMMM' / 'yyyy HH:mm:ss z",
51             "d.M.yyyy H:mm:ss",
52             "d' de 'MMMM' de 'yyyy H'h'm'min's's' z",
53             "dd. MMMM yyyy HH:mm:ss z",
54             "d-M-yyyy H:mm:ss",
55             "EEEE''d MMMM G yyyy, H'  'm'  'ss' '",
56             "dd.MMM.yyyy HH:mm:ss",
57             "yy-MM-dd h:mm:ss.a",
58             "d' de 'MMMM' de 'yyyy hh:mm:ss a z",
59             "EEEE d MMMM yyyy H' h 'mm' min 'ss' s 'z",
60             "d MMMM yyyy H:mm:ss",
61             "d/MM/yyyy hh:mm:ss a",
62             "EEEE, d, MMMM yyyy HH:mm:ss z",
63             "EEEE, d. MMMM yyyy HH.mm.' h' z",
64             "EEEE, d' / 'MMMM' / 'yyyy HH:mm:ss z",
65             "d/MM/yyyy HH:mm:ss",
66             "d MMMM yyyy H:mm:ss z",
67             "MMMM d, yyyy h:mm:ss a z",
68             "yyyy. MMMM d. H:mm:ss z",
69             "d' de 'MMMM' de 'yyyy H:mm:ss z",
70             "EEEE, MMMM d, yyyy h:mm:ss a z",
71             "d/M/yyyy H:mm:ss",
72             "d-MMM-yy HH:mm:ss",
73             "EEEE d' de 'MMMM' de 'yyyy hh:mm:ss a z",
74             "yyyy'M'd' ahh'mm'ss'",
75             "yyyy'MM'dd' EEEE ahh'mm'ss'",
76             "EEEE, d MMMM yyyy HH:mm:ss z",
77 
78             //6990146: 'Y' for year; 'X' for time zone; 'u' for day number of the week
79             "d/M/YYYY H:mm:ss",
80             "d-MMM-YY HH:mm:ss",
81             "EEEE d' de 'MMMM' de 'YYYY hh:mm:ss a X",
82             "YYYY M d ahh:mm:ss",
83             "YYYY MM dd EEEE u ahh/mm/ss",
84             "EEEE, u, d MMMM YYYY HH:mm:ss X",
85             "YYYY M d Z ahh mm ss",
86             "YYYY-MM-dd EEEE u ahh-mm-ss",
87 
88             //*added for sr-Latn*
89             "EEEE, dd. MMMM y. HH.mm.ss zzzz",
90             "dd. MMMM y. HH.mm.ss z",
91             "dd.MM.y. HH.mm.ss",
92             "d.M.yy. HH.mm"
93     };
94 
95     private static String[] invalidPat = {
96             "yyyy'M'd' ahh:mm:ss",
97             "EEEe d MM MM yyyy HH' h 'mm zzzZ",
98             "d MMMM\\ yyyy, H'  'm' 'g",
99             "EEEE d' @# MMMMde 'yyys HHH'mm z",
100             "yyyy'MMe 2 #dd' EEEEahh'mm'ss' z,z",
101             "yyyy.M.d H;mm.ses",
102             "EEEe, d MMMM yyyy h:mm:ss a z",
103             "EEEE, MMMM d, 'y y y y h:mm:ss 'o''clock' a z",
104             "dd MMMM yyyy 0HHcl:mm:ss z",
105             "d.M_M_y.yy1yy HextH:mm|45:",
106             "d,D MMMTTTTTTTTTKM yy|+yy HH:m m:ss z",
107             "d-MDtM M-yy H:mm:ss",
108             "yyyy/M///m/nM/d Dd H:m$m:s s",
109             "EEEE, dd. MMMM yyyy HH:m'''m' Uhr 'z",
110             //6990146
111             "EEEE d' de 'MMMM' de 'YYYY hh:mm:ss a x",
112             "EEEE, U, d MMMM YYYY HH:mm:ss Z"
113     };
114 
115     private static Locale[] locales = DateFormat.getAvailableLocales();
116     private static Object[][] dfAllLocalesObj = createAllLocales();
117     private static Object[][] invalidPatObj = createPatternObj(invalidPat);
118     private static Object[][] validPatObj = createPatternObj(validPat);
119 
createAllLocales()120     private static Object[][] createAllLocales() {
121         Object[][] objArray = new Object[locales.length][];
122         for (int i = 0; i < locales.length; i++) {
123             objArray[i] = new Object[1];
124             objArray[i][0] = locales[i];
125         }
126         return objArray;
127     }
128 
createPatternObj(String[] pattern)129     private static Object[][] createPatternObj(String[] pattern) {
130         Object[][] objArray = new Object[locales.length * pattern.length][];
131         int k = 0;
132         for (int i = 0; i < locales.length; i++) {
133             for (int j = 0; j < pattern.length; j++) {
134                 objArray[k] = new Object[2];
135                 objArray[k][0] = pattern[j];
136                 objArray[k][1] = locales[i];
137                 k = k + 1;
138             }
139         }
140         return objArray;
141     }
142 
143     @DataProvider(name = "dfAllLocalesObj")
dfAllLocalesObj()144     Object[][] dfAllLocalesObj() {
145         return dfAllLocalesObj;
146     }
147 
148     @DataProvider(name = "invalidPatternObj")
invalidPatternObj()149     Object[][] invalidPatternObj() {
150         return invalidPatObj;
151     }
152 
153     @DataProvider(name = "validPatternObj")
validPatternObj()154     Object[][] validPatternObj() {
155         return validPatObj;
156     }
157 
158     //check Constructors for invalid pattern
159     @LargeTest
160     @Test(dataProvider = "invalidPatternObj",
161             expectedExceptions = IllegalArgumentException.class)
testIllegalArgumentException1(String pattern, Locale loc)162     public void testIllegalArgumentException1(String pattern, Locale loc)
163             throws IllegalArgumentException {
164         Locale.setDefault(loc);
165         new SimpleDateFormat(pattern);
166     }
167 
168     @LargeTest
169     @Test(dataProvider = "invalidPatternObj",
170             expectedExceptions = IllegalArgumentException.class)
testIllegalArgumentException2(String pattern, Locale loc)171     public void testIllegalArgumentException2(String pattern, Locale loc)
172             throws IllegalArgumentException {
173         Locale.setDefault(loc);
174         new SimpleDateFormat(pattern, new DateFormatSymbols());
175     }
176 
177     @LargeTest
178     @Test(dataProvider = "invalidPatternObj",
179             expectedExceptions = IllegalArgumentException.class)
testIllegalArgumentException3(String pattern, Locale loc)180     public void testIllegalArgumentException3(String pattern, Locale loc)
181             throws IllegalArgumentException {
182         Locale.setDefault(loc);
183         new SimpleDateFormat(pattern, Locale.getDefault());
184     }
185 
186     @LargeTest
187     @Test(dataProvider = "invalidPatternObj",
188             expectedExceptions = IllegalArgumentException.class)
testIllegalArgumentException4(String pattern, Locale loc)189     public void testIllegalArgumentException4(String pattern, Locale loc)
190             throws IllegalArgumentException {
191         Locale.setDefault(loc);
192         new SimpleDateFormat().applyPattern(pattern);
193     }
194 
195     // Android-added: Add a smaller test for IllegalArgumentException
196     @Test(dataProvider = "invalidPat", expectedExceptions = IllegalArgumentException.class)
testIllegalArgumentException_enUS(String pattern)197     public void testIllegalArgumentException_enUS(String pattern) {
198         Locale.setDefault(Locale.US);
199         new SimpleDateFormat(pattern);
200         new SimpleDateFormat(pattern, new DateFormatSymbols());
201         new SimpleDateFormat(pattern, Locale.getDefault());
202         new SimpleDateFormat().applyPattern(pattern);
203 
204     }
205 
206     //check Constructors for null pattern
207     @Test(dataProvider = "dfAllLocalesObj",
208             expectedExceptions = NullPointerException.class)
testNullPointerException1(Locale loc)209     public void testNullPointerException1(Locale loc)
210             throws NullPointerException {
211         Locale.setDefault(loc);
212         new SimpleDateFormat(null);
213     }
214 
215     @Test(dataProvider = "dfAllLocalesObj",
216             expectedExceptions = NullPointerException.class)
testNullPointerException2(Locale loc)217     public void testNullPointerException2(Locale loc)
218             throws NullPointerException {
219         Locale.setDefault(loc);
220         new SimpleDateFormat(null, new DateFormatSymbols());
221     }
222 
223     @Test(dataProvider = "dfAllLocalesObj",
224             expectedExceptions = NullPointerException.class)
testNullPointerException3(Locale loc)225     public void testNullPointerException3(Locale loc)
226             throws NullPointerException {
227         Locale.setDefault(loc);
228         new SimpleDateFormat(null, Locale.getDefault());
229     }
230 
231     @Test(dataProvider = "dfAllLocalesObj",
232             expectedExceptions = NullPointerException.class)
testNullPointerException4(Locale loc)233     public void testNullPointerException4(Locale loc)
234             throws NullPointerException {
235         Locale.setDefault(loc);
236         new SimpleDateFormat().applyPattern(null);
237     }
238 
239     // Shard the testValidPattern test.
240     @LargeTest
241     @Test(dataProvider = "validPatternObj")
242     //check Constructors for valid pattern
testValidPattern(String pattern, Locale loc)243     public void testValidPattern(String pattern, Locale loc) {
244         Locale.setDefault(loc);
245         new SimpleDateFormat(pattern);
246         new SimpleDateFormat(pattern, new DateFormatSymbols());
247         new SimpleDateFormat(pattern, Locale.getDefault());
248         new SimpleDateFormat().applyPattern(pattern);
249     }
250 
251     // Android-added: Add a smaller test for testValidPattern
252     @Test(dataProvider = "validPat")
testValidPattern_enUS(String pattern)253     public void testValidPattern_enUS(String pattern) {
254         Locale.setDefault(Locale.US);
255         new SimpleDateFormat(pattern);
256         new SimpleDateFormat(pattern, new DateFormatSymbols());
257         new SimpleDateFormat(pattern, Locale.getDefault());
258         new SimpleDateFormat().applyPattern(pattern);
259     }
260 }
261