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