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  
18  package org.apache.commons.lang3.time;
19  
20  import java.text.ParseException;
21  import java.text.SimpleDateFormat;
22  import java.util.Calendar;
23  import java.util.GregorianCalendar;
24  import java.util.Locale;
25  import java.util.TimeZone;
26  
27  import org.apache.commons.lang3.AbstractLangTest;
28  import org.apache.commons.lang3.LocaleProblems;
29  import org.apache.commons.lang3.LocaleUtils;
30  import org.apache.commons.lang3.function.TriFunction;
31  import org.junit.jupiter.api.Test;
32  import org.junit.jupiter.params.ParameterizedTest;
33  import org.junit.jupiter.params.provider.MethodSource;
34  
35  /**
36   * These tests fail on Java 15 due to a bug which was only fixed for Java 16.
37   * <ul>
38   * <li>https://bugs.openjdk.java.net/browse/JDK-8248434</li>
39   * <li>https://bugs.openjdk.java.net/browse/JDK-8248655</li>
40   * </ul>
41   */
42  class FastDateParserJava15BugTest extends AbstractLangTest {
43  
44      /** @see org.apache.commons.lang3.time.FastDateParserTest#dateParserParameters() */
45      private static final String DATE_PARSER_PARAMETERS = "org.apache.commons.lang3.time.FastDateParserTest#dateParserParameters()";
46  
47      @Test
48      void testJava15BuggyLocaleTest() throws ParseException {
49          final String buggyLocaleName = "ff_LR_#Adlm";
50          Locale buggyLocale = null;
51          for (final Locale locale : LocaleUtils.availableLocaleList()) {
52              if (buggyLocaleName.equals(locale.toString())) {
53                  buggyLocale = locale;
54                  break;
55              }
56          }
57          if (buggyLocale == null) {
58              return;
59          }
60          testSingleLocale(buggyLocale);
61      }
62  
63      @ParameterizedTest
64      @MethodSource("org.apache.commons.lang3.LocaleUtils#availableLocaleList()")
65      void testJava15BuggyLocaleTestAll(final Locale locale) throws ParseException {
66          testSingleLocale(locale);
67      }
68  
69      private void testLocale(final TriFunction<String, TimeZone, Locale, DateParser> dbProvider, final String format, final boolean eraBC, final Calendar cal,
70              final Locale locale) {
71          LocaleProblems.assumeLocaleSupportedA(locale);
72          // ja_JP_JP cannot handle dates before 1868 properly
73          if (eraBC && locale.equals(FastDateParser.JAPANESE_IMPERIAL)) {
74              return;
75          }
76          final SimpleDateFormat sdf = new SimpleDateFormat(format, locale);
77          final DateParser fdf = dbProvider.apply(format, TimeZone.getDefault(), locale);
78          // If parsing fails, a ParseException will be thrown and the test will fail
79          FastDateParserTest.checkParse(locale, cal, sdf, fdf);
80      }
81  
82      private void testLocales(final TriFunction<String, TimeZone, Locale, DateParser> dbProvider, final String format,
83              final boolean eraBC) throws Exception {
84          final Calendar cal = Calendar.getInstance(TimeZones.GMT);
85          cal.clear();
86          cal.set(2003, Calendar.FEBRUARY, 10);
87          if (eraBC) {
88              cal.set(Calendar.ERA, GregorianCalendar.BC);
89          }
90          for (final Locale locale : LocaleUtils.availableLocaleList()) {
91              testLocale(dbProvider, format, eraBC, cal, locale);
92          }
93      }
94  
95      @ParameterizedTest
96      @MethodSource(DATE_PARSER_PARAMETERS)
97      void testLocales_Long_AD(final TriFunction<String, TimeZone, Locale, DateParser> dpProvider)
98          throws Exception {
99          testLocales(dpProvider, FastDateParserTest.LONG_FORMAT, false);
100     }
101 
102     @ParameterizedTest
103     @MethodSource(DATE_PARSER_PARAMETERS)
104     void testLocales_Long_BC(final TriFunction<String, TimeZone, Locale, DateParser> dpProvider)
105         throws Exception {
106         testLocales(dpProvider, FastDateParserTest.LONG_FORMAT, true);
107     }
108 
109     @ParameterizedTest
110     @MethodSource(DATE_PARSER_PARAMETERS)
111     void testLocales_LongNoEra_AD(final TriFunction<String, TimeZone, Locale, DateParser> dpProvider)
112         throws Exception {
113         testLocales(dpProvider, FastDateParserTest.LONG_FORMAT_NOERA, false);
114     }
115 
116     @ParameterizedTest
117     @MethodSource(DATE_PARSER_PARAMETERS)
118     void testLocales_LongNoEra_BC(final TriFunction<String, TimeZone, Locale, DateParser> dpProvider)
119         throws Exception {
120         testLocales(dpProvider, FastDateParserTest.LONG_FORMAT_NOERA, true);
121     }
122 
123     @ParameterizedTest
124     @MethodSource(DATE_PARSER_PARAMETERS)
125     void testLocales_Short_AD(final TriFunction<String, TimeZone, Locale, DateParser> dpProvider)
126         throws Exception {
127         testLocales(dpProvider, FastDateParserTest.SHORT_FORMAT, false);
128     }
129 
130     @ParameterizedTest
131     @MethodSource(DATE_PARSER_PARAMETERS)
132     void testLocales_Short_BC(final TriFunction<String, TimeZone, Locale, DateParser> dpProvider)
133         throws Exception {
134         testLocales(dpProvider, FastDateParserTest.SHORT_FORMAT, true);
135     }
136 
137     @ParameterizedTest
138     @MethodSource(DATE_PARSER_PARAMETERS)
139     void testLocales_ShortNoEra_AD(final TriFunction<String, TimeZone, Locale, DateParser> dpProvider)
140         throws Exception {
141         testLocales(dpProvider, FastDateParserTest.SHORT_FORMAT_NOERA, false);
142     }
143 
144     @ParameterizedTest
145     @MethodSource(DATE_PARSER_PARAMETERS)
146     void testLocales_ShortNoEra_BC(final TriFunction<String, TimeZone, Locale, DateParser> dpProvider)
147         throws Exception {
148         testLocales(dpProvider, FastDateParserTest.SHORT_FORMAT_NOERA, true);
149     }
150 
151     private void testSingleLocale(final Locale locale) throws ParseException {
152         final Calendar cal = Calendar.getInstance(TimeZones.GMT);
153         cal.clear();
154         cal.set(2003, Calendar.FEBRUARY, 10);
155         final SimpleDateFormat sdf = new SimpleDateFormat(FastDateParserTest.LONG_FORMAT, locale);
156         final String formattedDate = sdf.format(cal.getTime());
157         sdf.parse(formattedDate);
158         sdf.parse(formattedDate.toUpperCase(locale));
159         sdf.parse(formattedDate.toLowerCase(locale));
160     }
161 
162 }