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