1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.lang3;
18
19 import static org.apache.commons.lang3.JavaVersion.JAVA_1_4;
20 import static org.junit.jupiter.api.Assertions.assertEquals;
21 import static org.junit.jupiter.api.Assertions.assertFalse;
22 import static org.junit.jupiter.api.Assertions.assertNotEquals;
23 import static org.junit.jupiter.api.Assertions.assertNotNull;
24 import static org.junit.jupiter.api.Assertions.assertNull;
25 import static org.junit.jupiter.api.Assertions.assertSame;
26 import static org.junit.jupiter.api.Assertions.assertThrows;
27 import static org.junit.jupiter.api.Assertions.assertTrue;
28
29 import java.lang.reflect.Constructor;
30 import java.lang.reflect.Modifier;
31 import java.util.Arrays;
32 import java.util.Collection;
33 import java.util.HashSet;
34 import java.util.Iterator;
35 import java.util.List;
36 import java.util.Locale;
37 import java.util.Set;
38
39 import org.junit.jupiter.api.BeforeEach;
40 import org.junit.jupiter.api.Test;
41 import org.junit.jupiter.params.ParameterizedTest;
42 import org.junit.jupiter.params.provider.MethodSource;
43
44
45
46
47 public class LocaleUtilsTest extends AbstractLangTest {
48
49 private static final Locale LOCALE_EN = new Locale("en", "");
50 private static final Locale LOCALE_EN_US = new Locale("en", "US");
51 private static final Locale LOCALE_EN_US_ZZZZ = new Locale("en", "US", "ZZZZ");
52 private static final Locale LOCALE_FR = new Locale("fr", "");
53 private static final Locale LOCALE_FR_CA = new Locale("fr", "CA");
54 private static final Locale LOCALE_QQ = new Locale("qq", "");
55 private static final Locale LOCALE_QQ_ZZ = new Locale("qq", "ZZ");
56
57
58
59
60
61
62
63
64
65
66
67 private static void assertCountriesByLanguage(final String language, final String[] countries) {
68 final List<Locale> list = LocaleUtils.countriesByLanguage(language);
69 final List<Locale> list2 = LocaleUtils.countriesByLanguage(language);
70 assertNotNull(list);
71 assertSame(list, list2);
72
73 for (final String country : countries) {
74 final Iterator<Locale> iterator = list.iterator();
75 boolean found = false;
76
77 while (iterator.hasNext()) {
78 final Locale locale = iterator.next();
79
80 assertTrue(StringUtils.isEmpty(locale.getVariant()));
81 assertEquals(language, locale.getLanguage());
82 if (country.equals(locale.getCountry())) {
83 found = true;
84 break;
85 }
86 }
87 assertTrue(found, "Could not find language: " + country + " for country: " + language);
88 }
89 assertUnmodifiableCollection(list);
90 }
91
92
93
94
95
96
97
98
99
100
101 private static void assertLanguageByCountry(final String country, final String[] languages) {
102 final List<Locale> list = LocaleUtils.languagesByCountry(country);
103 final List<Locale> list2 = LocaleUtils.languagesByCountry(country);
104 assertNotNull(list);
105 assertSame(list, list2);
106
107 for (final String language : languages) {
108 final Iterator<Locale> iterator = list.iterator();
109 boolean found = false;
110
111 while (iterator.hasNext()) {
112 final Locale locale = iterator.next();
113
114 assertTrue(StringUtils.isEmpty(locale.getVariant()));
115 assertEquals(country, locale.getCountry());
116 if (language.equals(locale.getLanguage())) {
117 found = true;
118 break;
119 }
120 }
121 assertTrue(found, "Could not find language: " + language + " for country: " + country);
122 }
123 assertUnmodifiableCollection(list);
124 }
125
126
127
128
129
130
131
132
133 private static void assertLocaleLookupList(final Locale locale, final Locale defaultLocale, final Locale[] expected) {
134 final List<Locale> localeList = defaultLocale == null ?
135 LocaleUtils.localeLookupList(locale) :
136 LocaleUtils.localeLookupList(locale, defaultLocale);
137
138 assertEquals(expected.length, localeList.size());
139 assertEquals(Arrays.asList(expected), localeList);
140 assertUnmodifiableCollection(localeList);
141 }
142
143
144
145
146 private static void assertUnmodifiableCollection(final Collection<?> coll) {
147 assertThrows(UnsupportedOperationException.class, () -> coll.add(null));
148 }
149
150
151
152
153
154
155 private static void assertValidToLocale(final String language) {
156 final Locale locale = LocaleUtils.toLocale(language);
157 assertNotNull(locale, "valid locale");
158 assertEquals(language, locale.getLanguage());
159
160 assertTrue(StringUtils.isEmpty(locale.getCountry()));
161 assertTrue(StringUtils.isEmpty(locale.getVariant()));
162 }
163
164
165
166
167
168
169
170
171 private static void assertValidToLocale(final String localeString, final String language, final String country) {
172 final Locale locale = LocaleUtils.toLocale(localeString);
173 assertNotNull(locale, "valid locale");
174 assertEquals(language, locale.getLanguage());
175 assertEquals(country, locale.getCountry());
176
177 assertTrue(StringUtils.isEmpty(locale.getVariant()));
178 }
179
180
181
182
183
184
185
186
187
188 private static void assertValidToLocale(
189 final String localeString, final String language,
190 final String country, final String variant) {
191 final Locale locale = LocaleUtils.toLocale(localeString);
192 assertNotNull(locale, "valid locale");
193 assertEquals(language, locale.getLanguage());
194 assertEquals(country, locale.getCountry());
195 assertEquals(variant, locale.getVariant());
196 }
197
198 @BeforeEach
199 public void setUp() {
200
201 LocaleUtils.isAvailableLocale(Locale.getDefault());
202 }
203
204
205
206
207 @Test
208 public void testAvailableLocaleList() {
209 final List<Locale> list = LocaleUtils.availableLocaleList();
210 final List<Locale> list2 = LocaleUtils.availableLocaleList();
211 assertNotNull(list);
212 assertSame(list, list2);
213 assertUnmodifiableCollection(list);
214
215 final Locale[] jdkLocaleArray = Locale.getAvailableLocales();
216 final List<Locale> jdkLocaleList = Arrays.asList(jdkLocaleArray);
217 assertEquals(jdkLocaleList, list);
218 }
219
220
221
222
223 @Test
224 public void testAvailableLocaleSet() {
225 final Set<Locale> set = LocaleUtils.availableLocaleSet();
226 final Set<Locale> set2 = LocaleUtils.availableLocaleSet();
227 assertNotNull(set);
228 assertSame(set, set2);
229 assertUnmodifiableCollection(set);
230
231 final Locale[] jdkLocaleArray = Locale.getAvailableLocales();
232 final List<Locale> jdkLocaleList = Arrays.asList(jdkLocaleArray);
233 final Set<Locale> jdkLocaleSet = new HashSet<>(jdkLocaleList);
234 assertEquals(jdkLocaleSet, set);
235 }
236
237
238
239
240 @Test
241 public void testConstructor() {
242 assertNotNull(new LocaleUtils());
243 final Constructor<?>[] cons = LocaleUtils.class.getDeclaredConstructors();
244 assertEquals(1, cons.length);
245 assertTrue(Modifier.isPublic(cons[0].getModifiers()));
246 assertTrue(Modifier.isPublic(LocaleUtils.class.getModifiers()));
247 assertFalse(Modifier.isFinal(LocaleUtils.class.getModifiers()));
248 }
249
250
251
252
253 @Test
254 public void testCountriesByLanguage() {
255 assertCountriesByLanguage(null, new String[0]);
256 assertCountriesByLanguage("de", new String[]{"DE", "CH", "AT", "LU"});
257 assertCountriesByLanguage("zz", new String[0]);
258 assertCountriesByLanguage("it", new String[]{"IT", "CH"});
259 }
260
261
262
263
264 @SuppressWarnings("boxing")
265 @Test
266 public void testIsAvailableLocale() {
267 final Set<Locale> set = LocaleUtils.availableLocaleSet();
268 assertEquals(set.contains(LOCALE_EN), LocaleUtils.isAvailableLocale(LOCALE_EN));
269 assertEquals(set.contains(LOCALE_EN_US), LocaleUtils.isAvailableLocale(LOCALE_EN_US));
270 assertEquals(set.contains(LOCALE_EN_US_ZZZZ), LocaleUtils.isAvailableLocale(LOCALE_EN_US_ZZZZ));
271 assertEquals(set.contains(LOCALE_FR), LocaleUtils.isAvailableLocale(LOCALE_FR));
272 assertEquals(set.contains(LOCALE_FR_CA), LocaleUtils.isAvailableLocale(LOCALE_FR_CA));
273 assertEquals(set.contains(LOCALE_QQ), LocaleUtils.isAvailableLocale(LOCALE_QQ));
274 assertEquals(set.contains(LOCALE_QQ_ZZ), LocaleUtils.isAvailableLocale(LOCALE_QQ_ZZ));
275 }
276
277 @Test
278 public void testIsLanguageUndetermined() {
279 final Set<Locale> set = LocaleUtils.availableLocaleSet();
280
281 assertNotEquals(set.contains(LOCALE_EN), LocaleUtils.isLanguageUndetermined(LOCALE_EN));
282 assertNotEquals(set.contains(LOCALE_EN_US), LocaleUtils.isLanguageUndetermined(LOCALE_EN_US));
283 assertNotEquals(set.contains(LOCALE_FR), LocaleUtils.isLanguageUndetermined(LOCALE_FR));
284 assertNotEquals(set.contains(LOCALE_FR_CA), LocaleUtils.isLanguageUndetermined(LOCALE_FR_CA));
285
286 assertEquals(set.contains(LOCALE_EN_US_ZZZZ), LocaleUtils.isLanguageUndetermined(LOCALE_EN_US_ZZZZ));
287 assertEquals(set.contains(LOCALE_QQ), LocaleUtils.isLanguageUndetermined(LOCALE_QQ));
288 assertEquals(set.contains(LOCALE_QQ_ZZ), LocaleUtils.isLanguageUndetermined(LOCALE_QQ_ZZ));
289
290 assertTrue(LocaleUtils.isLanguageUndetermined(null));
291 }
292
293
294
295
296 @Test
297 public void testLang328() {
298 assertValidToLocale("fr__P", "fr", "", "P");
299 assertValidToLocale("fr__POSIX", "fr", "", "POSIX");
300 }
301
302
303
304
305 @Test
306 public void testLang865() {
307 assertValidToLocale("_GB", "", "GB", "");
308 assertValidToLocale("_GB_P", "", "GB", "P");
309 assertValidToLocale("_GB_POSIX", "", "GB", "POSIX");
310 assertThrows(
311 IllegalArgumentException.class,
312 () -> LocaleUtils.toLocale("_G"),
313 "Must be at least 3 chars if starts with underscore");
314 assertThrows(
315 IllegalArgumentException.class,
316 () -> LocaleUtils.toLocale("_Gb"),
317 "Must be uppercase if starts with underscore");
318 assertThrows(
319 IllegalArgumentException.class,
320 () -> LocaleUtils.toLocale("_gB"),
321 "Must be uppercase if starts with underscore");
322 assertThrows(
323 IllegalArgumentException.class,
324 () -> LocaleUtils.toLocale("_1B"),
325 "Must be letter if starts with underscore");
326 assertThrows(
327 IllegalArgumentException.class,
328 () -> LocaleUtils.toLocale("_G1"),
329 "Must be letter if starts with underscore");
330 assertThrows(
331 IllegalArgumentException.class,
332 () -> LocaleUtils.toLocale("_GB_"),
333 "Must be at least 5 chars if starts with underscore");
334 assertThrows(
335 IllegalArgumentException.class,
336 () -> LocaleUtils.toLocale("_GBAP"),
337 "Must have underscore after the country if starts with underscore and is at least 5 chars");
338 }
339
340 @Test
341 public void testLanguageAndUNM49Numeric3AreaCodeLang1312() {
342 assertValidToLocale("en_001", "en", "001");
343 assertValidToLocale("en_150", "en", "150");
344 assertValidToLocale("ar_001", "ar", "001");
345
346
347 assertValidToLocale("en_001_GB", "en", "001", "GB");
348 assertValidToLocale("en_150_US", "en", "150", "US");
349 }
350
351
352
353
354 @Test
355 public void testLanguagesByCountry() {
356 assertLanguageByCountry(null, new String[0]);
357 assertLanguageByCountry("GB", new String[]{"en"});
358 assertLanguageByCountry("ZZ", new String[0]);
359 assertLanguageByCountry("CH", new String[]{"fr", "de", "it"});
360 }
361
362
363
364
365 @Test
366 public void testLocaleLookupList_Locale() {
367 assertLocaleLookupList(null, null, new Locale[0]);
368 assertLocaleLookupList(LOCALE_QQ, null, new Locale[]{LOCALE_QQ});
369 assertLocaleLookupList(LOCALE_EN, null, new Locale[]{LOCALE_EN});
370 assertLocaleLookupList(LOCALE_EN, null, new Locale[]{LOCALE_EN});
371 assertLocaleLookupList(LOCALE_EN_US, null,
372 new Locale[] {
373 LOCALE_EN_US,
374 LOCALE_EN});
375 assertLocaleLookupList(LOCALE_EN_US_ZZZZ, null,
376 new Locale[] {
377 LOCALE_EN_US_ZZZZ,
378 LOCALE_EN_US,
379 LOCALE_EN});
380 }
381
382
383
384
385 @Test
386 public void testLocaleLookupList_LocaleLocale() {
387 assertLocaleLookupList(LOCALE_QQ, LOCALE_QQ,
388 new Locale[]{LOCALE_QQ});
389 assertLocaleLookupList(LOCALE_EN, LOCALE_EN,
390 new Locale[]{LOCALE_EN});
391
392 assertLocaleLookupList(LOCALE_EN_US, LOCALE_EN_US,
393 new Locale[]{
394 LOCALE_EN_US,
395 LOCALE_EN});
396 assertLocaleLookupList(LOCALE_EN_US, LOCALE_QQ,
397 new Locale[] {
398 LOCALE_EN_US,
399 LOCALE_EN,
400 LOCALE_QQ});
401 assertLocaleLookupList(LOCALE_EN_US, LOCALE_QQ_ZZ,
402 new Locale[] {
403 LOCALE_EN_US,
404 LOCALE_EN,
405 LOCALE_QQ_ZZ});
406
407 assertLocaleLookupList(LOCALE_EN_US_ZZZZ, null,
408 new Locale[] {
409 LOCALE_EN_US_ZZZZ,
410 LOCALE_EN_US,
411 LOCALE_EN});
412 assertLocaleLookupList(LOCALE_EN_US_ZZZZ, LOCALE_EN_US_ZZZZ,
413 new Locale[] {
414 LOCALE_EN_US_ZZZZ,
415 LOCALE_EN_US,
416 LOCALE_EN});
417 assertLocaleLookupList(LOCALE_EN_US_ZZZZ, LOCALE_QQ,
418 new Locale[] {
419 LOCALE_EN_US_ZZZZ,
420 LOCALE_EN_US,
421 LOCALE_EN,
422 LOCALE_QQ});
423 assertLocaleLookupList(LOCALE_EN_US_ZZZZ, LOCALE_QQ_ZZ,
424 new Locale[] {
425 LOCALE_EN_US_ZZZZ,
426 LOCALE_EN_US,
427 LOCALE_EN,
428 LOCALE_QQ_ZZ});
429 assertLocaleLookupList(LOCALE_FR_CA, LOCALE_EN,
430 new Locale[] {
431 LOCALE_FR_CA,
432 LOCALE_FR,
433 LOCALE_EN});
434 }
435
436 @ParameterizedTest
437 @MethodSource("java.util.Locale#getAvailableLocales")
438 public void testParseAllLocales(final Locale actualLocale) {
439
440 final Locale locale = new Locale(actualLocale.getLanguage(), actualLocale.getCountry(), actualLocale.getVariant());
441 if (actualLocale.equals(locale)) {
442 final String str = actualLocale.toString();
443
444 int suff = str.indexOf("_#");
445 if (suff == - 1) {
446 suff = str.indexOf("#");
447 }
448 String localeStr = str;
449 if (suff >= 0) {
450 assertThrows(IllegalArgumentException.class, () -> LocaleUtils.toLocale(str));
451
452 localeStr = str.substring(0, suff);
453 }
454 final Locale loc = LocaleUtils.toLocale(localeStr);
455 assertEquals(actualLocale, loc);
456 }
457 }
458
459
460
461
462
463 @Test
464 public void testThreeCharsLocale() {
465 for (final String str : Arrays.asList("udm", "tet")) {
466 final Locale locale = LocaleUtils.toLocale(str);
467 assertNotNull(locale);
468 assertEquals(str, locale.getLanguage());
469 assertTrue(StringUtils.isBlank(locale.getCountry()));
470 assertEquals(new Locale(str), locale);
471 }
472 }
473
474
475
476
477 @Test
478 public void testToLocale_1Part() {
479 assertNull(LocaleUtils.toLocale((String) null));
480
481 assertValidToLocale("us");
482 assertValidToLocale("fr");
483 assertValidToLocale("de");
484 assertValidToLocale("zh");
485
486 assertValidToLocale("qq");
487
488 assertValidToLocale("");
489
490 assertThrows(IllegalArgumentException.class, () -> LocaleUtils.toLocale("Us"), "Should fail if not lowercase");
491 assertThrows(IllegalArgumentException.class, () -> LocaleUtils.toLocale("uS"), "Should fail if not lowercase");
492 assertThrows(IllegalArgumentException.class, () -> LocaleUtils.toLocale("u#"), "Should fail if not lowercase");
493 assertThrows(
494 IllegalArgumentException.class, () -> LocaleUtils.toLocale("u"), "Must be 2 chars if less than 5");
495 assertThrows(
496 IllegalArgumentException.class, () -> LocaleUtils.toLocale("uu_U"), "Must be 2 chars if less than 5");
497 }
498
499
500
501
502 @Test
503 public void testToLocale_2Part() {
504 assertValidToLocale("us_EN", "us", "EN");
505 assertValidToLocale("us-EN", "us", "EN");
506
507 assertValidToLocale("us_ZH", "us", "ZH");
508
509 assertThrows(
510 IllegalArgumentException.class,
511 () -> LocaleUtils.toLocale("us_En"),
512 "Should fail second part not uppercase");
513 assertThrows(
514 IllegalArgumentException.class,
515 () -> LocaleUtils.toLocale("us_en"),
516 "Should fail second part not uppercase");
517 assertThrows(
518 IllegalArgumentException.class,
519 () -> LocaleUtils.toLocale("us_eN"),
520 "Should fail second part not uppercase");
521 assertThrows(
522 IllegalArgumentException.class,
523 () -> LocaleUtils.toLocale("uS_EN"),
524 "Should fail first part not lowercase");
525 assertThrows(
526 IllegalArgumentException.class,
527 () -> LocaleUtils.toLocale("us_E3"),
528 "Should fail second part not uppercase");
529 }
530
531
532
533
534 @Test
535 public void testToLocale_3Part() {
536 assertValidToLocale("us_EN_A", "us", "EN", "A");
537 assertValidToLocale("us-EN-A", "us", "EN", "A");
538
539
540 if (SystemUtils.isJavaVersionAtLeast(JAVA_1_4)) {
541 assertValidToLocale("us_EN_a", "us", "EN", "a");
542 assertValidToLocale("us_EN_SFsafdFDsdfF", "us", "EN", "SFsafdFDsdfF");
543 } else {
544 assertValidToLocale("us_EN_a", "us", "EN", "A");
545 assertValidToLocale("us_EN_SFsafdFDsdfF", "us", "EN", "SFSAFDFDSDFF");
546 }
547
548 assertThrows(
549 IllegalArgumentException.class, () -> LocaleUtils.toLocale("us_EN-a"), "Should fail as no consistent delimiter");
550 assertThrows(
551 IllegalArgumentException.class, () -> LocaleUtils.toLocale("uu_UU_"), "Must be 3, 5 or 7+ in length");
552 }
553
554
555
556
557 @Test
558 public void testToLocale_Locale_defaults() {
559 assertNull(LocaleUtils.toLocale((String) null));
560 assertEquals(Locale.getDefault(), LocaleUtils.toLocale((Locale) null));
561 assertEquals(Locale.getDefault(), LocaleUtils.toLocale(Locale.getDefault()));
562 }
563
564
565
566
567 @ParameterizedTest
568 @MethodSource("java.util.Locale#getAvailableLocales")
569 public void testToLocales(final Locale actualLocale) {
570 assertEquals(actualLocale, LocaleUtils.toLocale(actualLocale));
571 }
572 }