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