Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/java/util/Locale/LocaleEnhanceTest.java
38813 views
1
/*
2
* Copyright (c) 2010, 2020, 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
import java.io.BufferedReader;
25
import java.io.ByteArrayInputStream;
26
import java.io.ByteArrayOutputStream;
27
import java.io.File;
28
import java.io.FileInputStream;
29
import java.io.InputStreamReader;
30
import java.io.ObjectInputStream;
31
import java.io.ObjectOutputStream;
32
import java.net.URISyntaxException;
33
import java.net.URL;
34
import java.text.DecimalFormatSymbols;
35
import java.util.ArrayList;
36
import java.util.Arrays;
37
import java.util.Calendar;
38
import java.util.IllformedLocaleException;
39
import java.util.List;
40
import java.util.Locale;
41
import java.util.Locale.Builder;
42
import java.util.Set;
43
44
/**
45
* @test
46
* @bug 6875847 6992272 7002320 7015500 7023613 7032820 7033504 7004603
47
* 7044019 8255086
48
* @summary test API changes to Locale
49
* @compile LocaleEnhanceTest.java
50
* @run main/othervm -esa LocaleEnhanceTest
51
*/
52
public class LocaleEnhanceTest extends LocaleTestFmwk {
53
54
public static void main(String[] args) throws Exception {
55
List<String> argList = new ArrayList<String>();
56
argList.addAll(Arrays.asList(args));
57
argList.add("-nothrow");
58
new LocaleEnhanceTest().run(argList.toArray(new String[argList.size()]));
59
}
60
61
public LocaleEnhanceTest() {
62
}
63
64
///
65
/// Generic sanity tests
66
///
67
68
/** A canonical language code. */
69
private static final String l = "en";
70
71
/** A canonical script code.. */
72
private static final String s = "Latn";
73
74
/** A canonical region code. */
75
private static final String c = "US";
76
77
/** A canonical variant code. */
78
private static final String v = "NewYork";
79
80
/**
81
* Ensure that Builder builds locales that have the expected
82
* tag and java6 ID. Note the odd cases for the ID.
83
*/
84
public void testCreateLocaleCanonicalValid() {
85
String[] valids = {
86
"en-Latn-US-NewYork", "en_US_NewYork_#Latn",
87
"en-Latn-US", "en_US_#Latn",
88
"en-Latn-NewYork", "en__NewYork_#Latn", // double underscore
89
"en-Latn", "en__#Latn", // double underscore
90
"en-US-NewYork", "en_US_NewYork",
91
"en-US", "en_US",
92
"en-NewYork", "en__NewYork", // double underscore
93
"en", "en",
94
"und-Latn-US-NewYork", "_US_NewYork_#Latn",
95
"und-Latn-US", "_US_#Latn",
96
"und-Latn-NewYork", "", // variant only not supported
97
"und-Latn", "",
98
"und-US-NewYork", "_US_NewYork",
99
"und-US", "_US",
100
"und-NewYork", "", // variant only not supported
101
"und", ""
102
};
103
104
Builder builder = new Builder();
105
106
for (int i = 0; i < valids.length; i += 2) {
107
String tag = valids[i];
108
String id = valids[i+1];
109
110
String idl = (i & 16) == 0 ? l : "";
111
String ids = (i & 8) == 0 ? s : "";
112
String idc = (i & 4) == 0 ? c : "";
113
String idv = (i & 2) == 0 ? v : "";
114
115
String msg = String.valueOf(i/2) + ": '" + tag + "' ";
116
117
try {
118
Locale l = builder
119
.setLanguage(idl)
120
.setScript(ids)
121
.setRegion(idc)
122
.setVariant(idv)
123
.build();
124
assertEquals(msg + "language", idl, l.getLanguage());
125
assertEquals(msg + "script", ids, l.getScript());
126
assertEquals(msg + "country", idc, l.getCountry());
127
assertEquals(msg + "variant", idv, l.getVariant());
128
assertEquals(msg + "tag", tag, l.toLanguageTag());
129
assertEquals(msg + "id", id, l.toString());
130
}
131
catch (IllegalArgumentException e) {
132
errln(msg + e.getMessage());
133
}
134
}
135
}
136
137
/**
138
* Test that locale construction works with 'multiple variants'.
139
* <p>
140
* The string "Newer__Yorker" is treated as three subtags,
141
* "Newer", "", and "Yorker", and concatenated into one
142
* subtag by omitting empty subtags and joining the remainer
143
* with underscores. So the resulting variant tag is "Newer_Yorker".
144
* Note that 'New' and 'York' are invalid BCP47 variant subtags
145
* because they are too short.
146
*/
147
public void testCreateLocaleMultipleVariants() {
148
149
String[] valids = {
150
"en-Latn-US-Newer-Yorker", "en_US_Newer_Yorker_#Latn",
151
"en-Latn-Newer-Yorker", "en__Newer_Yorker_#Latn",
152
"en-US-Newer-Yorker", "en_US_Newer_Yorker",
153
"en-Newer-Yorker", "en__Newer_Yorker",
154
"und-Latn-US-Newer-Yorker", "_US_Newer_Yorker_#Latn",
155
"und-Latn-Newer-Yorker", "",
156
"und-US-Newer-Yorker", "_US_Newer_Yorker",
157
"und-Newer-Yorker", "",
158
};
159
160
Builder builder = new Builder(); // lenient variant
161
162
final String idv = "Newer_Yorker";
163
for (int i = 0; i < valids.length; i += 2) {
164
String tag = valids[i];
165
String id = valids[i+1];
166
167
String idl = (i & 8) == 0 ? l : "";
168
String ids = (i & 4) == 0 ? s : "";
169
String idc = (i & 2) == 0 ? c : "";
170
171
String msg = String.valueOf(i/2) + ": " + tag + " ";
172
try {
173
Locale l = builder
174
.setLanguage(idl)
175
.setScript(ids)
176
.setRegion(idc)
177
.setVariant(idv)
178
.build();
179
180
assertEquals(msg + " language", idl, l.getLanguage());
181
assertEquals(msg + " script", ids, l.getScript());
182
assertEquals(msg + " country", idc, l.getCountry());
183
assertEquals(msg + " variant", idv, l.getVariant());
184
185
assertEquals(msg + "tag", tag, l.toLanguageTag());
186
assertEquals(msg + "id", id, l.toString());
187
}
188
catch (IllegalArgumentException e) {
189
errln(msg + e.getMessage());
190
}
191
}
192
}
193
194
/**
195
* Ensure that all these invalid formats are not recognized by
196
* forLanguageTag.
197
*/
198
public void testCreateLocaleCanonicalInvalidSeparator() {
199
String[] invalids = {
200
// trailing separator
201
"en_Latn_US_NewYork_",
202
"en_Latn_US_",
203
"en_Latn_",
204
"en_",
205
"_",
206
207
// double separator
208
"en_Latn_US__NewYork",
209
"_Latn_US__NewYork",
210
"en_US__NewYork",
211
"_US__NewYork",
212
213
// are these OK?
214
// "en_Latn__US_NewYork", // variant is 'US_NewYork'
215
// "_Latn__US_NewYork", // variant is 'US_NewYork'
216
// "en__Latn_US_NewYork", // variant is 'Latn_US_NewYork'
217
// "en__US_NewYork", // variant is 'US_NewYork'
218
219
// double separator without language or script
220
"__US",
221
"__NewYork",
222
223
// triple separator anywhere except within variant
224
"en___NewYork",
225
"en_Latn___NewYork",
226
"_Latn___NewYork",
227
"___NewYork",
228
};
229
230
for (int i = 0; i < invalids.length; ++i) {
231
String id = invalids[i];
232
Locale l = Locale.forLanguageTag(id);
233
assertEquals(id, "und", l.toLanguageTag());
234
}
235
}
236
237
/**
238
* Ensure that all current locale ids parse. Use DateFormat as a proxy
239
* for all current locale ids.
240
*/
241
public void testCurrentLocales() {
242
Locale[] locales = java.text.DateFormat.getAvailableLocales();
243
Builder builder = new Builder();
244
245
for (Locale target : locales) {
246
String tag = target.toLanguageTag();
247
248
// the tag recreates the original locale,
249
// except no_NO_NY
250
Locale tagResult = Locale.forLanguageTag(tag);
251
if (!target.getVariant().equals("NY")) {
252
assertEquals("tagResult", target, tagResult);
253
}
254
255
// the builder also recreates the original locale,
256
// except ja_JP_JP, th_TH_TH and no_NO_NY
257
Locale builderResult = builder.setLocale(target).build();
258
if (target.getVariant().length() != 2) {
259
assertEquals("builderResult", target, builderResult);
260
}
261
}
262
}
263
264
/**
265
* Ensure that all icu locale ids parse.
266
*/
267
public void testIcuLocales() throws Exception {
268
BufferedReader br = new BufferedReader(
269
new InputStreamReader(
270
LocaleEnhanceTest.class.getResourceAsStream("icuLocales.txt"),
271
"UTF-8"));
272
String id = null;
273
while (null != (id = br.readLine())) {
274
Locale result = Locale.forLanguageTag(id);
275
assertEquals("ulocale", id, result.toLanguageTag());
276
}
277
}
278
279
///
280
/// Compatibility tests
281
///
282
283
public void testConstructor() {
284
// all the old weirdness still holds, no new weirdness
285
String[][] tests = {
286
// language to lower case, region to upper, variant unchanged
287
// short
288
{ "X", "y", "z", "x", "Y" },
289
// long
290
{ "xXxXxXxXxXxX", "yYyYyYyYyYyYyYyY", "zZzZzZzZzZzZzZzZ",
291
"xxxxxxxxxxxx", "YYYYYYYYYYYYYYYY" },
292
// mapped language ids
293
{ "he", "IW", "", "iw" },
294
{ "iw", "IW", "", "iw" },
295
{ "yi", "DE", "", "ji" },
296
{ "ji", "DE", "", "ji" },
297
{ "id", "ID", "", "in" },
298
{ "in", "ID", "", "in" },
299
// special variants
300
{ "ja", "JP", "JP" },
301
{ "th", "TH", "TH" },
302
{ "no", "NO", "NY" },
303
{ "no", "NO", "NY" },
304
// no canonicalization of 3-letter language codes
305
{ "eng", "US", "" }
306
};
307
for (int i = 0; i < tests.length; ++ i) {
308
String[] test = tests[i];
309
String id = String.valueOf(i);
310
Locale locale = new Locale(test[0], test[1], test[2]);
311
assertEquals(id + " lang", test.length > 3 ? test[3] : test[0], locale.getLanguage());
312
assertEquals(id + " region", test.length > 4 ? test[4] : test[1], locale.getCountry());
313
assertEquals(id + " variant", test.length > 5 ? test[5] : test[2], locale.getVariant());
314
}
315
}
316
317
///
318
/// Locale API tests.
319
///
320
321
public void testGetScript() {
322
// forLanguageTag normalizes case
323
Locale locale = Locale.forLanguageTag("und-latn");
324
assertEquals("forLanguageTag", "Latn", locale.getScript());
325
326
// Builder normalizes case
327
locale = new Builder().setScript("LATN").build();
328
assertEquals("builder", "Latn", locale.getScript());
329
330
// empty string is returned, not null, if there is no script
331
locale = Locale.forLanguageTag("und");
332
assertEquals("script is empty string", "", locale.getScript());
333
}
334
335
public void testGetExtension() {
336
// forLanguageTag does NOT normalize to hyphen
337
Locale locale = Locale.forLanguageTag("und-a-some_ex-tension");
338
assertEquals("some_ex-tension", null, locale.getExtension('a'));
339
340
// regular extension
341
locale = new Builder().setExtension('a', "some-ex-tension").build();
342
assertEquals("builder", "some-ex-tension", locale.getExtension('a'));
343
344
// returns null if extension is not present
345
assertEquals("empty b", null, locale.getExtension('b'));
346
347
// throws exception if extension tag is illegal
348
new ExpectIAE() { public void call() { Locale.forLanguageTag("").getExtension('\uD800'); }};
349
350
// 'x' is not an extension, it's a private use tag, but it's accessed through this API
351
locale = Locale.forLanguageTag("x-y-z-blork");
352
assertEquals("x", "y-z-blork", locale.getExtension('x'));
353
}
354
355
public void testGetExtensionKeys() {
356
Locale locale = Locale.forLanguageTag("und-a-xx-yy-b-zz-ww");
357
Set<Character> result = locale.getExtensionKeys();
358
assertEquals("result size", 2, result.size());
359
assertTrue("'a','b'", result.contains('a') && result.contains('b'));
360
361
// result is not mutable
362
try {
363
result.add('x');
364
errln("expected exception on add to extension key set");
365
}
366
catch (UnsupportedOperationException e) {
367
// ok
368
}
369
370
// returns empty set if no extensions
371
locale = Locale.forLanguageTag("und");
372
assertTrue("empty result", locale.getExtensionKeys().isEmpty());
373
}
374
375
public void testGetUnicodeLocaleAttributes() {
376
Locale locale = Locale.forLanguageTag("en-US-u-abc-def");
377
Set<String> attributes = locale.getUnicodeLocaleAttributes();
378
assertEquals("number of attributes", 2, attributes.size());
379
assertTrue("attribute abc", attributes.contains("abc"));
380
assertTrue("attribute def", attributes.contains("def"));
381
382
locale = Locale.forLanguageTag("en-US-u-ca-gregory");
383
attributes = locale.getUnicodeLocaleAttributes();
384
assertTrue("empty attributes", attributes.isEmpty());
385
}
386
387
public void testGetUnicodeLocaleType() {
388
Locale locale = Locale.forLanguageTag("und-u-co-japanese-nu-thai");
389
assertEquals("collation", "japanese", locale.getUnicodeLocaleType("co"));
390
assertEquals("numbers", "thai", locale.getUnicodeLocaleType("nu"));
391
392
// Unicode locale extension key is case insensitive
393
assertEquals("key case", "japanese", locale.getUnicodeLocaleType("Co"));
394
395
// if keyword is not present, returns null
396
assertEquals("locale keyword not present", null, locale.getUnicodeLocaleType("xx"));
397
398
// if no locale extension is set, returns null
399
locale = Locale.forLanguageTag("und");
400
assertEquals("locale extension not present", null, locale.getUnicodeLocaleType("co"));
401
402
// typeless keyword
403
locale = Locale.forLanguageTag("und-u-kn");
404
assertEquals("typeless keyword", "", locale.getUnicodeLocaleType("kn"));
405
406
// invalid keys throw exception
407
new ExpectIAE() { public void call() { Locale.forLanguageTag("").getUnicodeLocaleType("q"); }};
408
new ExpectIAE() { public void call() { Locale.forLanguageTag("").getUnicodeLocaleType("abcdefghi"); }};
409
410
// null argument throws exception
411
new ExpectNPE() { public void call() { Locale.forLanguageTag("").getUnicodeLocaleType(null); }};
412
}
413
414
public void testGetUnicodeLocaleKeys() {
415
Locale locale = Locale.forLanguageTag("und-u-co-japanese-nu-thai");
416
Set<String> result = locale.getUnicodeLocaleKeys();
417
assertEquals("two keys", 2, result.size());
418
assertTrue("co and nu", result.contains("co") && result.contains("nu"));
419
420
// result is not modifiable
421
try {
422
result.add("frobozz");
423
errln("expected exception when add to locale key set");
424
}
425
catch (UnsupportedOperationException e) {
426
// ok
427
}
428
}
429
430
public void testPrivateUseExtension() {
431
Locale locale = Locale.forLanguageTag("x-y-x-blork-");
432
assertEquals("blork", "y-x-blork", locale.getExtension(Locale.PRIVATE_USE_EXTENSION));
433
434
locale = Locale.forLanguageTag("und");
435
assertEquals("no privateuse", null, locale.getExtension(Locale.PRIVATE_USE_EXTENSION));
436
}
437
438
public void testToLanguageTag() {
439
// lots of normalization to test here
440
// test locales created using the constructor
441
String[][] tests = {
442
// empty locale canonicalizes to 'und'
443
{ "", "", "", "und" },
444
// variant alone is not a valid Locale, but has a valid language tag
445
{ "", "", "NewYork", "und-NewYork" },
446
// standard valid locales
447
{ "", "Us", "", "und-US" },
448
{ "", "US", "NewYork", "und-US-NewYork" },
449
{ "EN", "", "", "en" },
450
{ "EN", "", "NewYork", "en-NewYork" },
451
{ "EN", "US", "", "en-US" },
452
{ "EN", "US", "NewYork", "en-US-NewYork" },
453
// underscore in variant will be emitted as multiple variant subtags
454
{ "en", "US", "Newer_Yorker", "en-US-Newer-Yorker" },
455
// invalid variant subtags are appended as private use
456
{ "en", "US", "new_yorker", "en-US-x-lvariant-new-yorker" },
457
// the first invalid variant subtags and following variant subtags are appended as private use
458
{ "en", "US", "Windows_XP_Home", "en-US-Windows-x-lvariant-XP-Home" },
459
// too long variant and following variant subtags disappear
460
{ "en", "US", "WindowsVista_SP2", "en-US" },
461
// invalid region subtag disappears
462
{ "en", "USA", "", "en" },
463
// invalid language tag disappears
464
{ "e", "US", "", "und-US" },
465
// three-letter language tags are not canonicalized
466
{ "Eng", "", "", "eng" },
467
// legacy languages canonicalize to modern equivalents
468
{ "he", "IW", "", "he-IW" },
469
{ "iw", "IW", "", "he-IW" },
470
{ "yi", "DE", "", "yi-DE" },
471
{ "ji", "DE", "", "yi-DE" },
472
{ "id", "ID", "", "id-ID" },
473
{ "in", "ID", "", "id-ID" },
474
// special values are converted on output
475
{ "ja", "JP", "JP", "ja-JP-u-ca-japanese-x-lvariant-JP" },
476
{ "th", "TH", "TH", "th-TH-u-nu-thai-x-lvariant-TH" },
477
{ "no", "NO", "NY", "nn-NO" }
478
};
479
for (int i = 0; i < tests.length; ++i) {
480
String[] test = tests[i];
481
Locale locale = new Locale(test[0], test[1], test[2]);
482
assertEquals("case " + i, test[3], locale.toLanguageTag());
483
}
484
485
// test locales created from forLanguageTag
486
String[][] tests1 = {
487
// case is normalized during the round trip
488
{ "EN-us", "en-US" },
489
{ "en-Latn-US", "en-Latn-US" },
490
// reordering Unicode locale extensions
491
{ "de-u-co-phonebk-ca-gregory", "de-u-ca-gregory-co-phonebk" },
492
// private use only language tag is preserved (no extra "und")
493
{ "x-elmer", "x-elmer" },
494
{ "x-lvariant-JP", "x-lvariant-JP" },
495
};
496
for (String[] test : tests1) {
497
Locale locale = Locale.forLanguageTag(test[0]);
498
assertEquals("case " + test[0], test[1], locale.toLanguageTag());
499
}
500
501
}
502
503
public void testForLanguageTag() {
504
// forLanguageTag implements the 'Language-Tag' production of
505
// BCP47, so it handles private use and grandfathered tags,
506
// unlike locale builder. Tags listed below (except for the
507
// sample private use tags) come from 4646bis Feb 29, 2009.
508
509
String[][] tests = {
510
// private use tags only
511
{ "x-abc", "x-abc" },
512
{ "x-a-b-c", "x-a-b-c" },
513
{ "x-a-12345678", "x-a-12345678" },
514
515
// grandfathered tags with preferred mappings
516
{ "i-ami", "ami" },
517
{ "i-bnn", "bnn" },
518
{ "i-hak", "hak" },
519
{ "i-klingon", "tlh" },
520
{ "i-lux", "lb" }, // two-letter tag
521
{ "i-navajo", "nv" }, // two-letter tag
522
{ "i-pwn", "pwn" },
523
{ "i-tao", "tao" },
524
{ "i-tay", "tay" },
525
{ "i-tsu", "tsu" },
526
{ "art-lojban", "jbo" },
527
{ "no-bok", "nb" },
528
{ "no-nyn", "nn" },
529
{ "sgn-BE-FR", "sfb" },
530
{ "sgn-BE-NL", "vgt" },
531
{ "sgn-CH-DE", "sgg" },
532
{ "zh-guoyu", "cmn" },
533
{ "zh-hakka", "hak" },
534
{ "zh-min-nan", "nan" },
535
{ "zh-xiang", "hsn" },
536
537
// grandfathered irregular tags, no preferred mappings, drop illegal fields
538
// from end. If no subtag is mappable, fallback to 'und'
539
{ "i-default", "en-x-i-default" },
540
{ "i-enochian", "x-i-enochian" },
541
{ "i-mingo", "see-x-i-mingo" },
542
{ "en-GB-oed", "en-GB-x-oed" },
543
{ "zh-min", "nan-x-zh-min" },
544
{ "cel-gaulish", "xtg-x-cel-gaulish" },
545
};
546
for (int i = 0; i < tests.length; ++i) {
547
String[] test = tests[i];
548
Locale locale = Locale.forLanguageTag(test[0]);
549
assertEquals("grandfathered case " + i, test[1], locale.toLanguageTag());
550
}
551
552
// forLanguageTag ignores everything past the first place it encounters
553
// a syntax error
554
tests = new String[][] {
555
{ "valid",
556
"en-US-Newer-Yorker-a-bb-cc-dd-u-aa-abc-bb-def-x-y-12345678-z",
557
"en-US-Newer-Yorker-a-bb-cc-dd-u-aa-abc-bb-def-x-y-12345678-z" },
558
{ "segment of private use tag too long",
559
"en-US-Newer-Yorker-a-bb-cc-dd-u-aa-abc-bb-def-x-y-123456789-z",
560
"en-US-Newer-Yorker-a-bb-cc-dd-u-aa-abc-bb-def-x-y" },
561
{ "segment of private use tag is empty",
562
"en-US-Newer-Yorker-a-bb-cc-dd-u-aa-abc-bb-def-x-y--12345678-z",
563
"en-US-Newer-Yorker-a-bb-cc-dd-u-aa-abc-bb-def-x-y" },
564
{ "first segment of private use tag is empty",
565
"en-US-Newer-Yorker-a-bb-cc-dd-u-aa-abc-bb-def-x--y-12345678-z",
566
"en-US-Newer-Yorker-a-bb-cc-dd-u-aa-abc-bb-def" },
567
{ "illegal extension tag",
568
"en-US-Newer-Yorker-a-bb-cc-dd-u-aa-abc-bb-def-\uD800-y-12345678-z",
569
"en-US-Newer-Yorker-a-bb-cc-dd-u-aa-abc-bb-def" },
570
{ "locale subtag with no value",
571
"en-US-Newer-Yorker-a-bb-cc-dd-u-aa-abc-bb-x-y-12345678-z",
572
"en-US-Newer-Yorker-a-bb-cc-dd-u-aa-abc-bb-x-y-12345678-z" },
573
{ "locale key subtag invalid",
574
"en-US-Newer-Yorker-a-bb-cc-dd-u-aa-abc-123456789-def-x-y-12345678-z",
575
"en-US-Newer-Yorker-a-bb-cc-dd-u-aa-abc" },
576
// locale key subtag invalid in earlier position, all following subtags
577
// dropped (and so the locale extension dropped as well)
578
{ "locale key subtag invalid in earlier position",
579
"en-US-Newer-Yorker-a-bb-cc-dd-u-123456789-abc-bb-def-x-y-12345678-z",
580
"en-US-Newer-Yorker-a-bb-cc-dd" },
581
};
582
for (int i = 0; i < tests.length; ++i) {
583
String[] test = tests[i];
584
String msg = "syntax error case " + i + " " + test[0];
585
try {
586
Locale locale = Locale.forLanguageTag(test[1]);
587
assertEquals(msg, test[2], locale.toLanguageTag());
588
}
589
catch (IllegalArgumentException e) {
590
errln(msg + " caught exception: " + e);
591
}
592
}
593
594
// duplicated extension are just ignored
595
Locale locale = Locale.forLanguageTag("und-d-aa-00-bb-01-D-AA-10-cc-11-c-1234");
596
assertEquals("extension", "aa-00-bb-01", locale.getExtension('d'));
597
assertEquals("extension c", "1234", locale.getExtension('c'));
598
599
locale = Locale.forLanguageTag("und-U-ca-gregory-u-ca-japanese");
600
assertEquals("Unicode extension", "ca-gregory", locale.getExtension(Locale.UNICODE_LOCALE_EXTENSION));
601
602
// redundant Unicode locale keys in an extension are ignored
603
locale = Locale.forLanguageTag("und-u-aa-000-bb-001-bB-002-cc-003-c-1234");
604
assertEquals("Unicode keywords", "aa-000-bb-001-cc-003", locale.getExtension(Locale.UNICODE_LOCALE_EXTENSION));
605
assertEquals("Duplicated Unicode locake key followed by an extension", "1234", locale.getExtension('c'));
606
}
607
608
public void testGetDisplayScript() {
609
Locale latnLocale = Locale.forLanguageTag("und-latn");
610
Locale hansLocale = Locale.forLanguageTag("und-hans");
611
612
Locale oldLocale = Locale.getDefault();
613
614
Locale.setDefault(Locale.US);
615
assertEquals("latn US", "Latin", latnLocale.getDisplayScript());
616
assertEquals("hans US", "Simplified", hansLocale.getDisplayScript());
617
618
Locale.setDefault(Locale.GERMANY);
619
assertEquals("latn DE", "Lateinisch", latnLocale.getDisplayScript());
620
assertEquals("hans DE", "Vereinfachte Chinesische Schrift", hansLocale.getDisplayScript());
621
622
Locale.setDefault(oldLocale);
623
}
624
625
public void testGetDisplayScriptWithLocale() {
626
Locale latnLocale = Locale.forLanguageTag("und-latn");
627
Locale hansLocale = Locale.forLanguageTag("und-hans");
628
629
assertEquals("latn US", "Latin", latnLocale.getDisplayScript(Locale.US));
630
assertEquals("hans US", "Simplified", hansLocale.getDisplayScript(Locale.US));
631
632
assertEquals("latn DE", "Lateinisch", latnLocale.getDisplayScript(Locale.GERMANY));
633
assertEquals("hans DE", "Vereinfachte Chinesische Schrift", hansLocale.getDisplayScript(Locale.GERMANY));
634
}
635
636
public void testGetDisplayName() {
637
final Locale[] testLocales = {
638
Locale.ROOT,
639
new Locale("en"),
640
new Locale("en", "US"),
641
new Locale("", "US"),
642
new Locale("no", "NO", "NY"),
643
new Locale("", "", "NY"),
644
Locale.forLanguageTag("zh-Hans"),
645
Locale.forLanguageTag("zh-Hant"),
646
Locale.forLanguageTag("zh-Hans-CN"),
647
Locale.forLanguageTag("und-Hans"),
648
};
649
650
final String[] displayNameEnglish = {
651
"",
652
"English",
653
"English (United States)",
654
"United States",
655
"Norwegian (Norway,Nynorsk)",
656
"Nynorsk",
657
"Chinese (Simplified)",
658
"Chinese (Traditional)",
659
"Chinese (Simplified,China)",
660
"Simplified",
661
};
662
663
final String[] displayNameSimplifiedChinese = {
664
"",
665
"\u82f1\u6587",
666
"\u82f1\u6587 (\u7f8e\u56fd)",
667
"\u7f8e\u56fd",
668
"\u632a\u5a01\u6587 (\u632a\u5a01,Nynorsk)",
669
"Nynorsk",
670
"\u4e2d\u6587 (\u7b80\u4f53\u4e2d\u6587)",
671
"\u4e2d\u6587 (\u7e41\u4f53\u4e2d\u6587)",
672
"\u4e2d\u6587 (\u7b80\u4f53\u4e2d\u6587,\u4e2d\u56fd)",
673
"\u7b80\u4f53\u4e2d\u6587",
674
};
675
676
for (int i = 0; i < testLocales.length; i++) {
677
Locale loc = testLocales[i];
678
assertEquals("English display name for " + loc.toLanguageTag(),
679
displayNameEnglish[i], loc.getDisplayName(Locale.ENGLISH));
680
assertEquals("Simplified Chinese display name for " + loc.toLanguageTag(),
681
displayNameSimplifiedChinese[i], loc.getDisplayName(Locale.CHINA));
682
}
683
}
684
685
///
686
/// Builder tests
687
///
688
689
public void testBuilderSetLocale() {
690
Builder builder = new Builder();
691
Builder lenientBuilder = new Builder();
692
693
String languageTag = "en-Latn-US-NewYork-a-bb-ccc-u-co-japanese-x-y-z";
694
String target = "en-Latn-US-NewYork-a-bb-ccc-u-co-japanese-x-y-z";
695
696
Locale locale = Locale.forLanguageTag(languageTag);
697
Locale result = lenientBuilder
698
.setLocale(locale)
699
.build();
700
assertEquals("long tag", target, result.toLanguageTag());
701
assertEquals("long tag", locale, result);
702
703
// null is illegal
704
new BuilderNPE("locale") {
705
public void call() { b.setLocale(null); }
706
};
707
708
// builder canonicalizes the three legacy locales:
709
// ja_JP_JP, th_TH_TH, no_NY_NO.
710
locale = builder.setLocale(new Locale("ja", "JP", "JP")).build();
711
assertEquals("ja_JP_JP languagetag", "ja-JP-u-ca-japanese", locale.toLanguageTag());
712
assertEquals("ja_JP_JP variant", "", locale.getVariant());
713
714
locale = builder.setLocale(new Locale("th", "TH", "TH")).build();
715
assertEquals("th_TH_TH languagetag", "th-TH-u-nu-thai", locale.toLanguageTag());
716
assertEquals("th_TH_TH variant", "", locale.getVariant());
717
718
locale = builder.setLocale(new Locale("no", "NO", "NY")).build();
719
assertEquals("no_NO_NY languagetag", "nn-NO", locale.toLanguageTag());
720
assertEquals("no_NO_NY language", "nn", locale.getLanguage());
721
assertEquals("no_NO_NY variant", "", locale.getVariant());
722
723
// non-canonical, non-legacy locales are invalid
724
new BuilderILE("123_4567_89") {
725
public void call() {
726
b.setLocale(new Locale("123", "4567", "89"));
727
}
728
};
729
}
730
731
public void testBuilderSetLanguageTag() {
732
String source = "eN-LaTn-Us-NewYork-A-Xx-B-Yy-X-1-2-3";
733
String target = "en-Latn-US-NewYork-a-xx-b-yy-x-1-2-3";
734
Builder builder = new Builder();
735
String result = builder
736
.setLanguageTag(source)
737
.build()
738
.toLanguageTag();
739
assertEquals("language", target, result);
740
741
// redundant extensions cause a failure
742
new BuilderILE() { public void call() { b.setLanguageTag("und-a-xx-yy-b-ww-A-00-11-c-vv"); }};
743
744
// redundant Unicode locale extension keys within an Unicode locale extension cause a failure
745
new BuilderILE() { public void call() { b.setLanguageTag("und-u-nu-thai-NU-chinese-xx-1234"); }};
746
}
747
748
public void testBuilderSetLanguage() {
749
// language is normalized to lower case
750
String source = "eN";
751
String target = "en";
752
String defaulted = "";
753
Builder builder = new Builder();
754
String result = builder
755
.setLanguage(source)
756
.build()
757
.getLanguage();
758
assertEquals("en", target, result);
759
760
// setting with empty resets
761
result = builder
762
.setLanguage(target)
763
.setLanguage("")
764
.build()
765
.getLanguage();
766
assertEquals("empty", defaulted, result);
767
768
// setting with null resets too
769
result = builder
770
.setLanguage(target)
771
.setLanguage(null)
772
.build()
773
.getLanguage();
774
assertEquals("null", defaulted, result);
775
776
// language codes must be 2-8 alpha
777
// for forwards compatibility, 4-alpha and 5-8 alpha (registered)
778
// languages are accepted syntax
779
new BuilderILE("q", "abcdefghi", "13") { public void call() { b.setLanguage(arg); }};
780
781
// language code validation is NOT performed, any 2-8-alpha passes
782
assertNotNull("2alpha", builder.setLanguage("zz").build());
783
assertNotNull("8alpha", builder.setLanguage("abcdefgh").build());
784
785
// three-letter language codes are NOT canonicalized to two-letter
786
result = builder
787
.setLanguage("eng")
788
.build()
789
.getLanguage();
790
assertEquals("eng", "eng", result);
791
}
792
793
public void testBuilderSetScript() {
794
// script is normalized to title case
795
String source = "lAtN";
796
String target = "Latn";
797
String defaulted = "";
798
Builder builder = new Builder();
799
String result = builder
800
.setScript(source)
801
.build()
802
.getScript();
803
assertEquals("script", target, result);
804
805
// setting with empty resets
806
result = builder
807
.setScript(target)
808
.setScript("")
809
.build()
810
.getScript();
811
assertEquals("empty", defaulted, result);
812
813
// settting with null also resets
814
result = builder
815
.setScript(target)
816
.setScript(null)
817
.build()
818
.getScript();
819
assertEquals("null", defaulted, result);
820
821
// ill-formed script codes throw IAE
822
// must be 4alpha
823
new BuilderILE("abc", "abcde", "l3tn") { public void call() { b.setScript(arg); }};
824
825
// script code validation is NOT performed, any 4-alpha passes
826
assertEquals("4alpha", "Wxyz", builder.setScript("wxyz").build().getScript());
827
}
828
829
public void testBuilderSetRegion() {
830
// region is normalized to upper case
831
String source = "uS";
832
String target = "US";
833
String defaulted = "";
834
Builder builder = new Builder();
835
String result = builder
836
.setRegion(source)
837
.build()
838
.getCountry();
839
assertEquals("us", target, result);
840
841
// setting with empty resets
842
result = builder
843
.setRegion(target)
844
.setRegion("")
845
.build()
846
.getCountry();
847
assertEquals("empty", defaulted, result);
848
849
// setting with null also resets
850
result = builder
851
.setRegion(target)
852
.setRegion(null)
853
.build()
854
.getCountry();
855
assertEquals("null", defaulted, result);
856
857
// ill-formed region codes throw IAE
858
// 2 alpha or 3 numeric
859
new BuilderILE("q", "abc", "12", "1234", "a3", "12a") { public void call() { b.setRegion(arg); }};
860
861
// region code validation is NOT performed, any 2-alpha or 3-digit passes
862
assertEquals("2alpha", "ZZ", builder.setRegion("ZZ").build().getCountry());
863
assertEquals("3digit", "000", builder.setRegion("000").build().getCountry());
864
}
865
866
public void testBuilderSetVariant() {
867
// Variant case is not normalized in lenient variant mode
868
String source = "NewYork";
869
String target = source;
870
String defaulted = "";
871
Builder builder = new Builder();
872
String result = builder
873
.setVariant(source)
874
.build()
875
.getVariant();
876
assertEquals("NewYork", target, result);
877
878
result = builder
879
.setVariant("NeWeR_YoRkEr")
880
.build()
881
.toLanguageTag();
882
assertEquals("newer yorker", "und-NeWeR-YoRkEr", result);
883
884
// subtags of variant are NOT reordered
885
result = builder
886
.setVariant("zzzzz_yyyyy_xxxxx")
887
.build()
888
.getVariant();
889
assertEquals("zyx", "zzzzz_yyyyy_xxxxx", result);
890
891
// setting to empty resets
892
result = builder
893
.setVariant(target)
894
.setVariant("")
895
.build()
896
.getVariant();
897
assertEquals("empty", defaulted, result);
898
899
// setting to null also resets
900
result = builder
901
.setVariant(target)
902
.setVariant(null)
903
.build()
904
.getVariant();
905
assertEquals("null", defaulted, result);
906
907
// ill-formed variants throw IAE
908
// digit followed by 3-7 characters, or alpha followed by 4-8 characters.
909
new BuilderILE("abcd", "abcdefghi", "1ab", "1abcdefgh") { public void call() { b.setVariant(arg); }};
910
911
// 4 characters is ok as long as the first is a digit
912
assertEquals("digit+3alpha", "1abc", builder.setVariant("1abc").build().getVariant());
913
914
// all subfields must conform
915
new BuilderILE("abcde-fg") { public void call() { b.setVariant(arg); }};
916
}
917
918
public void testBuilderSetExtension() {
919
// upper case characters are normalized to lower case
920
final char sourceKey = 'a';
921
final String sourceValue = "aB-aBcdefgh-12-12345678";
922
String target = "ab-abcdefgh-12-12345678";
923
Builder builder = new Builder();
924
String result = builder
925
.setExtension(sourceKey, sourceValue)
926
.build()
927
.getExtension(sourceKey);
928
assertEquals("extension", target, result);
929
930
// setting with empty resets
931
result = builder
932
.setExtension(sourceKey, sourceValue)
933
.setExtension(sourceKey, "")
934
.build()
935
.getExtension(sourceKey);
936
assertEquals("empty", null, result);
937
938
// setting with null also resets
939
result = builder
940
.setExtension(sourceKey, sourceValue)
941
.setExtension(sourceKey, null)
942
.build()
943
.getExtension(sourceKey);
944
assertEquals("null", null, result);
945
946
// ill-formed extension keys throw IAE
947
// must be in [0-9a-ZA-Z]
948
new BuilderILE("$") { public void call() { b.setExtension('$', sourceValue); }};
949
950
// each segment of value must be 2-8 alphanum
951
new BuilderILE("ab-cd-123456789") { public void call() { b.setExtension(sourceKey, arg); }};
952
953
// no multiple hyphens.
954
new BuilderILE("ab--cd") { public void call() { b.setExtension(sourceKey, arg); }};
955
956
// locale extension key has special handling
957
Locale locale = builder
958
.setExtension('u', "co-japanese")
959
.build();
960
assertEquals("locale extension", "japanese", locale.getUnicodeLocaleType("co"));
961
962
// locale extension has same behavior with set locale keyword
963
Locale locale2 = builder
964
.setUnicodeLocaleKeyword("co", "japanese")
965
.build();
966
assertEquals("locales with extension", locale, locale2);
967
968
// setting locale extension overrides all previous calls to setLocaleKeyword
969
Locale locale3 = builder
970
.setExtension('u', "xxx-nu-thai")
971
.build();
972
assertEquals("remove co", null, locale3.getUnicodeLocaleType("co"));
973
assertEquals("override thai", "thai", locale3.getUnicodeLocaleType("nu"));
974
assertEquals("override attribute", 1, locale3.getUnicodeLocaleAttributes().size());
975
976
// setting locale keyword extends values already set by the locale extension
977
Locale locale4 = builder
978
.setUnicodeLocaleKeyword("co", "japanese")
979
.build();
980
assertEquals("extend", "japanese", locale4.getUnicodeLocaleType("co"));
981
assertEquals("extend", "thai", locale4.getUnicodeLocaleType("nu"));
982
983
// locale extension subtags are reordered
984
result = builder
985
.clear()
986
.setExtension('u', "456-123-zz-123-yy-456-xx-789")
987
.build()
988
.toLanguageTag();
989
assertEquals("reorder", "und-u-123-456-xx-789-yy-456-zz-123", result);
990
991
// multiple keyword types
992
result = builder
993
.clear()
994
.setExtension('u', "nu-thai-foobar")
995
.build()
996
.getUnicodeLocaleType("nu");
997
assertEquals("multiple types", "thai-foobar", result);
998
999
// redundant locale extensions are ignored
1000
result = builder
1001
.clear()
1002
.setExtension('u', "nu-thai-NU-chinese-xx-1234")
1003
.build()
1004
.toLanguageTag();
1005
assertEquals("duplicate keys", "und-u-nu-thai-xx-1234", result);
1006
}
1007
1008
public void testBuilderAddUnicodeLocaleAttribute() {
1009
Builder builder = new Builder();
1010
Locale locale = builder
1011
.addUnicodeLocaleAttribute("def")
1012
.addUnicodeLocaleAttribute("abc")
1013
.build();
1014
1015
Set<String> uattrs = locale.getUnicodeLocaleAttributes();
1016
assertEquals("number of attributes", 2, uattrs.size());
1017
assertTrue("attribute abc", uattrs.contains("abc"));
1018
assertTrue("attribute def", uattrs.contains("def"));
1019
1020
// remove attribute
1021
locale = builder.removeUnicodeLocaleAttribute("xxx")
1022
.build();
1023
1024
assertEquals("remove bogus", 2, uattrs.size());
1025
1026
// add duplicate
1027
locale = builder.addUnicodeLocaleAttribute("abc")
1028
.build();
1029
assertEquals("add duplicate", 2, uattrs.size());
1030
1031
// null attribute throws NPE
1032
new BuilderNPE("null attribute") { public void call() { b.addUnicodeLocaleAttribute(null); }};
1033
1034
// illformed attribute throws IllformedLocaleException
1035
new BuilderILE("invalid attribute") { public void call() { b.addUnicodeLocaleAttribute("ca"); }};
1036
}
1037
1038
public void testBuildersetUnicodeLocaleKeyword() {
1039
// Note: most behavior is tested in testBuilderSetExtension
1040
Builder builder = new Builder();
1041
Locale locale = builder
1042
.setUnicodeLocaleKeyword("co", "japanese")
1043
.setUnicodeLocaleKeyword("nu", "thai")
1044
.build();
1045
assertEquals("co", "japanese", locale.getUnicodeLocaleType("co"));
1046
assertEquals("nu", "thai", locale.getUnicodeLocaleType("nu"));
1047
assertEquals("keys", 2, locale.getUnicodeLocaleKeys().size());
1048
1049
// can clear a keyword by setting to null, others remain
1050
String result = builder
1051
.setUnicodeLocaleKeyword("co", null)
1052
.build()
1053
.toLanguageTag();
1054
assertEquals("empty co", "und-u-nu-thai", result);
1055
1056
// locale keyword extension goes when all keywords are gone
1057
result = builder
1058
.setUnicodeLocaleKeyword("nu", null)
1059
.build()
1060
.toLanguageTag();
1061
assertEquals("empty nu", "und", result);
1062
1063
// locale keywords are ordered independent of order of addition
1064
result = builder
1065
.setUnicodeLocaleKeyword("zz", "012")
1066
.setUnicodeLocaleKeyword("aa", "345")
1067
.build()
1068
.toLanguageTag();
1069
assertEquals("reordered", "und-u-aa-345-zz-012", result);
1070
1071
// null keyword throws NPE
1072
new BuilderNPE("keyword") { public void call() { b.setUnicodeLocaleKeyword(null, "thai"); }};
1073
1074
// well-formed keywords are two alphanum
1075
new BuilderILE("a", "abc") { public void call() { b.setUnicodeLocaleKeyword(arg, "value"); }};
1076
1077
// well-formed values are 3-8 alphanum
1078
new BuilderILE("ab", "abcdefghi") { public void call() { b.setUnicodeLocaleKeyword("ab", arg); }};
1079
}
1080
1081
public void testBuilderPrivateUseExtension() {
1082
// normalizes hyphens to underscore, case to lower
1083
String source = "c-B-a";
1084
String target = "c-b-a";
1085
Builder builder = new Builder();
1086
String result = builder
1087
.setExtension(Locale.PRIVATE_USE_EXTENSION, source)
1088
.build()
1089
.getExtension(Locale.PRIVATE_USE_EXTENSION);
1090
assertEquals("abc", target, result);
1091
1092
// multiple hyphens are ill-formed
1093
new BuilderILE("a--b") { public void call() { b.setExtension(Locale.PRIVATE_USE_EXTENSION, arg); }};
1094
}
1095
1096
public void testBuilderClear() {
1097
String monster = "en-latn-US-NewYork-a-bb-cc-u-co-japanese-x-z-y-x-x";
1098
Builder builder = new Builder();
1099
Locale locale = Locale.forLanguageTag(monster);
1100
String result = builder
1101
.setLocale(locale)
1102
.clear()
1103
.build()
1104
.toLanguageTag();
1105
assertEquals("clear", "und", result);
1106
}
1107
1108
public void testBuilderRemoveUnicodeAttribute() {
1109
// tested in testBuilderAddUnicodeAttribute
1110
}
1111
1112
public void testBuilderBuild() {
1113
// tested in other test methods
1114
}
1115
1116
public void testSerialize() {
1117
final Locale[] testLocales = {
1118
Locale.ROOT,
1119
new Locale("en"),
1120
new Locale("en", "US"),
1121
new Locale("en", "US", "Win"),
1122
new Locale("en", "US", "Win_XP"),
1123
new Locale("ja", "JP"),
1124
new Locale("ja", "JP", "JP"),
1125
new Locale("th", "TH"),
1126
new Locale("th", "TH", "TH"),
1127
new Locale("no", "NO"),
1128
new Locale("nb", "NO"),
1129
new Locale("nn", "NO"),
1130
new Locale("no", "NO", "NY"),
1131
new Locale("nn", "NO", "NY"),
1132
new Locale("he", "IL"),
1133
new Locale("he", "IL", "var"),
1134
new Locale("Language", "Country", "Variant"),
1135
new Locale("", "US"),
1136
new Locale("", "", "Java"),
1137
Locale.forLanguageTag("en-Latn-US"),
1138
Locale.forLanguageTag("zh-Hans"),
1139
Locale.forLanguageTag("zh-Hant-TW"),
1140
Locale.forLanguageTag("ja-JP-u-ca-japanese"),
1141
Locale.forLanguageTag("und-Hant"),
1142
Locale.forLanguageTag("und-a-123-456"),
1143
Locale.forLanguageTag("en-x-java"),
1144
Locale.forLanguageTag("th-TH-u-ca-buddist-nu-thai-x-lvariant-TH"),
1145
};
1146
1147
for (Locale locale : testLocales) {
1148
try {
1149
// write
1150
ByteArrayOutputStream bos = new ByteArrayOutputStream();
1151
ObjectOutputStream oos = new ObjectOutputStream(bos);
1152
oos.writeObject(locale);
1153
1154
// read
1155
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
1156
ObjectInputStream ois = new ObjectInputStream(bis);
1157
Object o = ois.readObject();
1158
1159
assertEquals("roundtrip " + locale, locale, o);
1160
} catch (Exception e) {
1161
errln(locale + " encountered exception:" + e.getLocalizedMessage());
1162
}
1163
}
1164
}
1165
1166
public void testDeserialize6() {
1167
final String TESTFILEPREFIX = "java6locale_";
1168
1169
File dataDir = null;
1170
String dataDirName = System.getProperty("serialized.data.dir");
1171
if (dataDirName == null) {
1172
URL resdirUrl = getClass().getClassLoader().getResource("serialized");
1173
if (resdirUrl != null) {
1174
try {
1175
dataDir = new File(resdirUrl.toURI());
1176
} catch (URISyntaxException urie) {
1177
}
1178
}
1179
} else {
1180
dataDir = new File(dataDirName);
1181
}
1182
1183
if (dataDir == null || !dataDir.isDirectory()) {
1184
errln("Could not locate the serialized test case data location");
1185
return;
1186
}
1187
1188
File[] files = dataDir.listFiles();
1189
for (File testfile : files) {
1190
if (testfile.isDirectory()) {
1191
continue;
1192
}
1193
String name = testfile.getName();
1194
if (!name.startsWith(TESTFILEPREFIX)) {
1195
continue;
1196
}
1197
Locale locale;
1198
String locStr = name.substring(TESTFILEPREFIX.length());
1199
if (locStr.equals("ROOT")) {
1200
locale = Locale.ROOT;
1201
} else {
1202
String[] fields = locStr.split("_", 3);
1203
String lang = fields[0];
1204
String country = (fields.length >= 2) ? fields[1] : "";
1205
String variant = (fields.length == 3) ? fields[2] : "";
1206
locale = new Locale(lang, country, variant);
1207
}
1208
1209
// deserialize
1210
try (FileInputStream fis = new FileInputStream(testfile);
1211
ObjectInputStream ois = new ObjectInputStream(fis))
1212
{
1213
Object o = ois.readObject();
1214
assertEquals("Deserialize Java 6 Locale " + locale, o, locale);
1215
} catch (Exception e) {
1216
errln("Exception while reading " + testfile.getAbsolutePath() + " - " + e.getMessage());
1217
}
1218
}
1219
}
1220
1221
public void testBug7002320() {
1222
// forLanguageTag() and Builder.setLanguageTag(String)
1223
// should add a location extension for following two cases.
1224
//
1225
// 1. language/country are "ja"/"JP" and the resolved variant (x-lvariant-*)
1226
// is exactly "JP" and no BCP 47 extensions are available, then add
1227
// a Unicode locale extension "ca-japanese".
1228
// 2. language/country are "th"/"TH" and the resolved variant is exactly
1229
// "TH" and no BCP 47 extensions are available, then add a Unicode locale
1230
// extension "nu-thai".
1231
//
1232
String[][] testdata = {
1233
{"ja-JP-x-lvariant-JP", "ja-JP-u-ca-japanese-x-lvariant-JP"}, // special case 1
1234
{"ja-JP-x-lvariant-JP-XXX"},
1235
{"ja-JP-u-ca-japanese-x-lvariant-JP"},
1236
{"ja-JP-u-ca-gregory-x-lvariant-JP"},
1237
{"ja-JP-u-cu-jpy-x-lvariant-JP"},
1238
{"ja-x-lvariant-JP"},
1239
{"th-TH-x-lvariant-TH", "th-TH-u-nu-thai-x-lvariant-TH"}, // special case 2
1240
{"th-TH-u-nu-thai-x-lvariant-TH"},
1241
{"en-US-x-lvariant-JP"},
1242
};
1243
1244
Builder bldr = new Builder();
1245
1246
for (String[] data : testdata) {
1247
String in = data[0];
1248
String expected = (data.length == 1) ? data[0] : data[1];
1249
1250
// forLanguageTag
1251
Locale loc = Locale.forLanguageTag(in);
1252
String out = loc.toLanguageTag();
1253
assertEquals("Language tag roundtrip by forLanguageTag with input: " + in, expected, out);
1254
1255
// setLanguageTag
1256
bldr.clear();
1257
bldr.setLanguageTag(in);
1258
loc = bldr.build();
1259
out = loc.toLanguageTag();
1260
assertEquals("Language tag roundtrip by Builder.setLanguageTag with input: " + in, expected, out);
1261
}
1262
}
1263
1264
public void testBug7023613() {
1265
String[][] testdata = {
1266
{"en-Latn", "en__#Latn"},
1267
{"en-u-ca-japanese", "en__#u-ca-japanese"},
1268
};
1269
1270
for (String[] data : testdata) {
1271
String in = data[0];
1272
String expected = (data.length == 1) ? data[0] : data[1];
1273
1274
Locale loc = Locale.forLanguageTag(in);
1275
String out = loc.toString();
1276
assertEquals("Empty country field with non-empty script/extension with input: " + in, expected, out);
1277
}
1278
}
1279
1280
/*
1281
* 7033504: (lc) incompatible behavior change for ja_JP_JP and th_TH_TH locales
1282
*/
1283
public void testBug7033504() {
1284
checkCalendar(new Locale("ja", "JP", "jp"), "java.util.GregorianCalendar");
1285
checkCalendar(new Locale("ja", "jp", "jp"), "java.util.GregorianCalendar");
1286
checkCalendar(new Locale("ja", "JP", "JP"), "java.util.JapaneseImperialCalendar");
1287
checkCalendar(new Locale("ja", "jp", "JP"), "java.util.JapaneseImperialCalendar");
1288
checkCalendar(Locale.forLanguageTag("en-u-ca-japanese"),
1289
"java.util.JapaneseImperialCalendar");
1290
1291
checkDigit(new Locale("th", "TH", "th"), '0');
1292
checkDigit(new Locale("th", "th", "th"), '0');
1293
checkDigit(new Locale("th", "TH", "TH"), '\u0e50');
1294
checkDigit(new Locale("th", "TH", "TH"), '\u0e50');
1295
checkDigit(Locale.forLanguageTag("en-u-nu-thai"), '\u0e50');
1296
}
1297
1298
private void checkCalendar(Locale loc, String expected) {
1299
Calendar cal = Calendar.getInstance(loc);
1300
assertEquals("Wrong calendar", expected, cal.getClass().getName());
1301
}
1302
1303
private void checkDigit(Locale loc, Character expected) {
1304
DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(loc);
1305
Character zero = dfs.getZeroDigit();
1306
assertEquals("Wrong digit zero char", expected, zero);
1307
}
1308
1309
///
1310
/// utility asserts
1311
///
1312
1313
private void assertTrue(String msg, boolean v) {
1314
if (!v) {
1315
errln(msg + ": expected true");
1316
}
1317
}
1318
1319
private void assertFalse(String msg, boolean v) {
1320
if (v) {
1321
errln(msg + ": expected false");
1322
}
1323
}
1324
1325
private void assertEquals(String msg, Object e, Object v) {
1326
if (e == null ? v != null : !e.equals(v)) {
1327
if (e != null) {
1328
e = "'" + e + "'";
1329
}
1330
if (v != null) {
1331
v = "'" + v + "'";
1332
}
1333
errln(msg + ": expected " + e + " but got " + v);
1334
}
1335
}
1336
1337
private void assertNotEquals(String msg, Object e, Object v) {
1338
if (e == null ? v == null : e.equals(v)) {
1339
if (e != null) {
1340
e = "'" + e + "'";
1341
}
1342
errln(msg + ": expected not equal " + e);
1343
}
1344
}
1345
1346
private void assertNull(String msg, Object o) {
1347
if (o != null) {
1348
errln(msg + ": expected null but got '" + o + "'");
1349
}
1350
}
1351
1352
private void assertNotNull(String msg, Object o) {
1353
if (o == null) {
1354
errln(msg + ": expected non null");
1355
}
1356
}
1357
1358
// not currently used, might get rid of exceptions from the API
1359
private abstract class ExceptionTest {
1360
private final Class<? extends Exception> exceptionClass;
1361
1362
ExceptionTest(Class<? extends Exception> exceptionClass) {
1363
this.exceptionClass = exceptionClass;
1364
}
1365
1366
public void run() {
1367
String failMsg = null;
1368
try {
1369
call();
1370
failMsg = "expected " + exceptionClass.getName() + " but no exception thrown.";
1371
}
1372
catch (Exception e) {
1373
if (!exceptionClass.isAssignableFrom(e.getClass())) {
1374
failMsg = "expected " + exceptionClass.getName() + " but caught " + e;
1375
}
1376
}
1377
if (failMsg != null) {
1378
String msg = message();
1379
msg = msg == null ? "" : msg + " ";
1380
errln(msg + failMsg);
1381
}
1382
}
1383
1384
public String message() {
1385
return null;
1386
}
1387
1388
public abstract void call();
1389
}
1390
1391
private abstract class ExpectNPE extends ExceptionTest {
1392
ExpectNPE() {
1393
super(NullPointerException.class);
1394
run();
1395
}
1396
}
1397
1398
private abstract class BuilderNPE extends ExceptionTest {
1399
protected final String msg;
1400
protected final Builder b = new Builder();
1401
1402
BuilderNPE(String msg) {
1403
super(NullPointerException.class);
1404
1405
this.msg = msg;
1406
1407
run();
1408
}
1409
1410
public String message() {
1411
return msg;
1412
}
1413
}
1414
1415
private abstract class ExpectIAE extends ExceptionTest {
1416
ExpectIAE() {
1417
super(IllegalArgumentException.class);
1418
run();
1419
}
1420
}
1421
1422
private abstract class BuilderILE extends ExceptionTest {
1423
protected final String[] args;
1424
protected final Builder b = new Builder();
1425
1426
protected String arg; // mutates during call
1427
1428
BuilderILE(String... args) {
1429
super(IllformedLocaleException.class);
1430
1431
this.args = args;
1432
1433
run();
1434
}
1435
1436
public void run() {
1437
for (String arg : args) {
1438
this.arg = arg;
1439
super.run();
1440
}
1441
}
1442
1443
public String message() {
1444
return "arg: '" + arg + "'";
1445
}
1446
}
1447
}
1448
1449