1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /*
4  *******************************************************************************
5  * Copyright (C) 2009-2012, International Business Machines Corporation and    *
6  * others. All Rights Reserved.                                                *
7  *******************************************************************************
8  */
9 package com.ibm.icu.dev.test.util;
10 
11 import java.util.Arrays;
12 
13 import org.junit.Test;
14 import org.junit.runner.RunWith;
15 import org.junit.runners.JUnit4;
16 
17 import com.ibm.icu.dev.test.TestFmwk;
18 import com.ibm.icu.util.IllformedLocaleException;
19 import com.ibm.icu.util.ULocale;
20 import com.ibm.icu.util.ULocale.Builder;
21 
22 /**
23  * Test cases for ULocale.LocaleBuilder
24  */
25 @RunWith(JUnit4.class)
26 public class LocaleBuilderTest extends TestFmwk {
27     @Test
TestLocaleBuilder()28     public void TestLocaleBuilder() {
29         // "L": +1 = language
30         // "S": +1 = script
31         // "R": +1 = region
32         // "V": +1 = variant
33         // "K": +1 = Unicode locale key / +2 = Unicode locale type
34         // "A": +1 = Unicode locale attribute
35         // "E": +1 = extension letter / +2 = extension value
36         // "P": +1 = private use
37         // "U": +1 = ULocale
38         // "B": +1 = BCP47 language tag
39 
40         // "C": Clear all
41         // "N": Clear extensions
42         // "D": +1 = Unicode locale attribute to be removed
43 
44         // "X": indicates an exception must be thrown
45         // "T": +1 = expected language tag / +2 = expected locale string
46         String[][] TESTCASE = {
47                 {"L", "en", "R", "us", "T", "en-US", "en_US"},
48                 {"L", "en", "R", "CA", "L", null, "T", "und-CA", "_CA"},
49                 {"L", "en", "R", "CA", "L", "", "T", "und-CA", "_CA"},
50                 {"L", "en", "R", "FR", "L", "fr", "T", "fr-FR", "fr_FR"},
51                 {"L", "123", "X"},
52                 {"R", "us", "T", "und-US", "_US"},
53                 {"R", "usa", "X"},
54                 {"R", "123", "L", "it", "R", null, "T", "it", "it"},
55                 {"R", "123", "L", "it", "R", "", "T", "it", "it"},
56                 {"R", "123", "L", "en", "T", "en-123", "en_123"},
57                 {"S", "LATN", "L", "DE", "T", "de-Latn", "de_Latn"},
58                 {"L", "De", "S", "latn", "R", "de", "S", "", "T", "de-DE", "de_DE"},
59                 {"L", "De", "S", "latn", "R", "de", "S", null, "T", "de-DE", "de_DE"},
60                 {"S", "latin", "X"},
61                 {"V", "1234", "L", "en", "T", "en-1234", "en__1234"},
62                 {"V", "1234", "L", "en", "V", "5678", "T", "en-5678", "en__5678"},
63                 {"V", "1234", "L", "en", "V", null, "T", "en", "en"},
64                 {"V", "1234", "L", "en", "V", "", "T", "en", "en"},
65                 {"V", "123", "X"},
66                 {"U", "en_US", "T", "en-US", "en_US"},
67                 {"U", "en_US_WIN", "X"},
68                 {"B", "fr-FR-1606nict-u-ca-gregory-x-test", "T", "fr-FR-1606nict-u-ca-gregory-x-test", "fr_FR_1606NICT@calendar=gregorian;x=test"},
69                 {"B", "ab-cde-fghij", "T", "cde-fghij", "cde__FGHIJ"},
70                 {"B", "und-CA", "T", "und-CA", "_CA"},
71                 {"B", "en-US-x-test-lvariant-var", "T", "en-US-x-test-lvariant-var", "en_US_VAR@x=test"},
72                 {"B", "en-US-VAR", "X"},
73                 {"U", "ja_JP@calendar=japanese;currency=JPY", "L", "ko", "T", "ko-JP-u-ca-japanese-cu-jpy", "ko_JP@calendar=japanese;currency=jpy"},
74                 {"U", "ja_JP@calendar=japanese;currency=JPY", "K", "ca", null, "T", "ja-JP-u-cu-jpy", "ja_JP@currency=jpy"},
75                 {"U", "ja_JP@calendar=japanese;currency=JPY", "E", "u", "attr1-ca-gregory", "T", "ja-JP-u-attr1-ca-gregory", "ja_JP@attribute=attr1;calendar=gregorian"},
76                 {"U", "en@colnumeric=yes", "K", "kn", "", "T", "en-u-kn", "en@colnumeric=yes"},
77                 {"L", "th", "R", "th", "K", "nu", "thai", "T", "th-TH-u-nu-thai", "th_TH@numbers=thai"},
78                 {"U", "zh_Hans", "R", "sg", "K", "ca", "badcalendar", "X"},
79                 {"U", "zh_Hans", "R", "sg", "K", "cal", "gregory", "X"},
80                 {"E", "z", "ExtZ", "L", "en", "T", "en-z-extz", "en@z=extz"},
81                 {"E", "z", "ExtZ", "L", "en", "E", "z", "", "T", "en", "en"},
82                 {"E", "z", "ExtZ", "L", "en", "E", "z", null, "T", "en", "en"},
83                 {"E", "a", "x", "X"},
84                 {"E", "a", "abc_def", "T", "und-a-abc-def", "@a=abc-def"},
85                 // Design limitation - typeless u extension keyword 0a below is interpreted as a boolean value true/yes.
86                 // With the legacy keyword syntax, "yes" is used for such boolean value instead of "true".
87                 // However, once the legacy keyword is translated back to BCP 47 u extension, key "0a" is unknown,
88                 // so "yes" is preserved - not mapped to "true". We could change the code to automatically transform
89                 // "yes" to "true", but it will break roundtrip conversion if BCP 47 u extension has "0a-yes".
90                 {"L", "en", "E", "u", "bbb-aaa-0a", "T", "en-u-aaa-bbb-0a", "en@0a=yes;attribute=aaa-bbb"},
91                 {"L", "fr", "R", "FR", "P", "Yoshito-ICU", "T", "fr-FR-x-yoshito-icu", "fr_FR@x=yoshito-icu"},
92                 {"L", "ja", "R", "jp", "K", "ca", "japanese", "T", "ja-JP-u-ca-japanese", "ja_JP@calendar=japanese"},
93                 {"K", "co", "PHONEBK", "K", "ca", "gregory", "L", "De", "T", "de-u-ca-gregory-co-phonebk", "de@calendar=gregorian;collation=phonebook"},
94                 {"E", "o", "OPQR", "E", "a", "aBcD", "T", "und-a-abcd-o-opqr", "@a=abcd;o=opqr"},
95                 {"E", "u", "nu-thai-ca-gregory", "L", "TH", "T", "th-u-ca-gregory-nu-thai", "th@calendar=gregorian;numbers=thai"},
96                 {"L", "en", "K", "tz", "usnyc", "R", "US", "T", "en-US-u-tz-usnyc", "en_US@timezone=America/New_York"},
97                 {"L", "de", "K", "co", "phonebk", "K", "ks", "level1", "K", "kk", "true", "T", "de-u-co-phonebk-kk-ks-level1", "de@collation=phonebook;colnormalization=yes;colstrength=primary"},
98                 {"L", "en", "R", "US", "K", "ca", "gregory", "T", "en-US-u-ca-gregory", "en_US@calendar=gregorian"},
99                 {"L", "en", "R", "US", "K", "cal", "gregory", "X"},
100                 {"L", "en", "R", "US", "K", "ca", "gregorian", "X"},
101                 {"L", "en", "R", "US", "K", "kn", "", "T", "en-US-u-kn", "en_US@colnumeric=yes"},
102                 {"B", "de-DE-u-co-phonebk", "C", "L", "pt", "T", "pt", "pt"},
103                 {"B", "ja-jp-u-ca-japanese", "N", "T", "ja-JP", "ja_JP"},
104                 {"B", "es-u-def-abc-co-trad", "A", "hij", "D", "def", "T", "es-u-abc-hij-co-trad", "es@attribute=abc-hij;collation=traditional"},
105                 {"B", "es-u-def-abc-co-trad", "A", "hij", "D", "def", "D", "def", "T", "es-u-abc-hij-co-trad", "es@attribute=abc-hij;collation=traditional"},
106                 {"L", "en", "A", "aa", "X"},
107                 {"B", "fr-u-attr1-cu-eur", "D", "attribute1", "X"},
108         };
109 
110         Builder bld_st = new Builder();
111 
112         for (int tidx = 0; tidx < TESTCASE.length; tidx++) {
113             int i = 0;
114             String[] expected = null;
115 
116             Builder bld = bld_st;
117 
118             bld.clear();
119 
120             while (true) {
121                 String method = TESTCASE[tidx][i++];
122                 try {
123                     // setters
124                     if (method.equals("L")) {
125                         bld.setLanguage(TESTCASE[tidx][i++]);
126                     } else if (method.equals("S")) {
127                         bld.setScript(TESTCASE[tidx][i++]);
128                     } else if (method.equals("R")) {
129                         bld.setRegion(TESTCASE[tidx][i++]);
130                     } else if (method.equals("V")) {
131                         bld.setVariant(TESTCASE[tidx][i++]);
132                     } else if (method.equals("K")) {
133                         String key = TESTCASE[tidx][i++];
134                         String type = TESTCASE[tidx][i++];
135                         bld.setUnicodeLocaleKeyword(key, type);
136                     } else if (method.equals("A")) {
137                         bld.addUnicodeLocaleAttribute(TESTCASE[tidx][i++]);
138                     } else if (method.equals("E")) {
139                         String key = TESTCASE[tidx][i++];
140                         String value = TESTCASE[tidx][i++];
141                         bld.setExtension(key.charAt(0), value);
142                     } else if (method.equals("P")) {
143                         bld.setExtension(ULocale.PRIVATE_USE_EXTENSION, TESTCASE[tidx][i++]);
144                     } else if (method.equals("U")) {
145                         bld.setLocale(new ULocale(TESTCASE[tidx][i++]));
146                     } else if (method.equals("B")) {
147                         bld.setLanguageTag(TESTCASE[tidx][i++]);
148                     }
149                     // clear / remove
150                     else if (method.equals("C")) {
151                         bld.clear();
152                     } else if (method.equals("N")) {
153                         bld.clearExtensions();
154                     } else if (method.equals("D")) {
155                         bld.removeUnicodeLocaleAttribute(TESTCASE[tidx][i++]);
156                     }
157                     // result
158                     else if (method.equals("X")) {
159                         errln("FAIL: No excetion was thrown - test csae: "
160                                 + Arrays.toString(TESTCASE[tidx]));
161                     } else if (method.equals("T")) {
162                         expected = new String[2];
163                         expected[0] = TESTCASE[tidx][i];
164                         expected[1] = TESTCASE[tidx][i + 1];
165                         break;
166                     } else {
167                         // Unknow test method
168                         errln("Unknown test case method: There is an error in the test case data.");
169                     }
170 
171                 } catch (IllformedLocaleException e) {
172                     if (TESTCASE[tidx][i].equals("X")) {
173                         // This exception is expected
174                         break;
175                     } else {
176                         errln("FAIL: IllformedLocaleException at offset " + i
177                                 + " in test case: " + Arrays.toString(TESTCASE[tidx]));
178                     }
179                 }
180             }
181             if (expected != null) {
182                 ULocale loc = bld.build();
183                 if (!expected[1].equals(loc.toString())) {
184                     errln("FAIL: Wrong locale ID - " + loc +
185                             " for test case: " + Arrays.toString(TESTCASE[tidx]));
186                 }
187                 String langtag = loc.toLanguageTag();
188                 if (!expected[0].equals(langtag)) {
189                     errln("FAIL: Wrong language tag - " + langtag +
190                             " for test case: " + Arrays.toString(TESTCASE[tidx]));
191                 }
192                 ULocale loc1 = ULocale.forLanguageTag(langtag);
193                 if (!loc.equals(loc1)) {
194                     errln("FAIL: Language tag round trip failed for " + loc);
195                 }
196             }
197         }
198     }
199 
200     @Test
TestSetLocale()201     public void TestSetLocale() {
202         ULocale loc = new ULocale("th_TH@calendar=gregorian");
203         Builder bld = new Builder();
204         try {
205             bld.setLocale(loc);
206             ULocale loc1 = bld.build();
207             if (!loc.equals(loc1)) {
208                 errln("FAIL: Locale loc1 " + loc1 + " was returned by the builder.  Expected " + loc);
209             }
210             bld.setLanguage("").setUnicodeLocaleKeyword("ca", "buddhist")
211                 .setLanguage("TH").setUnicodeLocaleKeyword("ca", "gregory");
212             ULocale loc2 = bld.build();
213             if (!loc.equals(loc2)) {
214                 errln("FAIL: Locale loc2 " + loc2 + " was returned by the builder.  Expected " + loc);
215             }
216         } catch (IllformedLocaleException e) {
217             errln("FAIL: IllformedLocaleException: " + e.getMessage());
218         }
219     }
220 }
221