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