blob: 35007c815edd729fea4f70250fdab2a1ab934c3c [file] [log] [blame]
Narayan Kamath378c6772014-01-20 13:57:11 +00001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Roozbeh Pournaderb927c552016-01-15 11:23:42 -080017#include <androidfw/LocaleData.h>
Narayan Kamath378c6772014-01-20 13:57:11 +000018#include <androidfw/ResourceTypes.h>
19#include <utils/Log.h>
20#include <utils/String8.h>
21
22#include <gtest/gtest.h>
23namespace android {
24
Adam Lesinski31245b42014-08-22 19:10:56 -070025TEST(ConfigLocaleTest, packAndUnpack2LetterLanguage) {
Narayan Kamath378c6772014-01-20 13:57:11 +000026 ResTable_config config;
27 config.packLanguage("en");
28
29 EXPECT_EQ('e', config.language[0]);
30 EXPECT_EQ('n', config.language[1]);
31
Roozbeh Pournaderb927c552016-01-15 11:23:42 -080032 char out[4] = {1, 1, 1, 1};
Narayan Kamath378c6772014-01-20 13:57:11 +000033 config.unpackLanguage(out);
34 EXPECT_EQ('e', out[0]);
35 EXPECT_EQ('n', out[1]);
36 EXPECT_EQ(0, out[2]);
37 EXPECT_EQ(0, out[3]);
38
39 memset(out, 1, sizeof(out));
40 config.locale = 0;
41 config.unpackLanguage(out);
42 EXPECT_EQ(0, out[0]);
43 EXPECT_EQ(0, out[1]);
44 EXPECT_EQ(0, out[2]);
45 EXPECT_EQ(0, out[3]);
46}
47
Adam Lesinski31245b42014-08-22 19:10:56 -070048TEST(ConfigLocaleTest, packAndUnpack2LetterRegion) {
Narayan Kamath378c6772014-01-20 13:57:11 +000049 ResTable_config config;
50 config.packRegion("US");
51
52 EXPECT_EQ('U', config.country[0]);
53 EXPECT_EQ('S', config.country[1]);
54
Roozbeh Pournaderb927c552016-01-15 11:23:42 -080055 char out[4] = {1, 1, 1, 1};
Narayan Kamath378c6772014-01-20 13:57:11 +000056 config.unpackRegion(out);
57 EXPECT_EQ('U', out[0]);
58 EXPECT_EQ('S', out[1]);
59 EXPECT_EQ(0, out[2]);
60 EXPECT_EQ(0, out[3]);
61}
62
Adam Lesinski31245b42014-08-22 19:10:56 -070063TEST(ConfigLocaleTest, packAndUnpack3LetterLanguage) {
Narayan Kamath378c6772014-01-20 13:57:11 +000064 ResTable_config config;
65 config.packLanguage("eng");
66
67 // 1-00110-01 101-00100
Adam Lesinskif90f2f8d2014-06-06 14:27:00 -070068 EXPECT_EQ('\x99', config.language[0]);
69 EXPECT_EQ('\xA4', config.language[1]);
Narayan Kamath378c6772014-01-20 13:57:11 +000070
Roozbeh Pournaderb927c552016-01-15 11:23:42 -080071 char out[4] = {1, 1, 1, 1};
Narayan Kamath378c6772014-01-20 13:57:11 +000072 config.unpackLanguage(out);
73 EXPECT_EQ('e', out[0]);
74 EXPECT_EQ('n', out[1]);
75 EXPECT_EQ('g', out[2]);
76 EXPECT_EQ(0, out[3]);
77}
78
Adam Lesinski31245b42014-08-22 19:10:56 -070079TEST(ConfigLocaleTest, packAndUnpack3LetterLanguageAtOffset16) {
Narayan Kamathb2975912014-06-30 15:59:39 +010080 ResTable_config config;
81 config.packLanguage("tgp");
82
83 // We had a bug where we would accidentally mask
84 // the 5th bit of both bytes
85 //
86 // packed[0] = 1011 1100
87 // packed[1] = 1101 0011
88 //
89 // which is equivalent to:
90 // 1 [0] [1] [2]
91 // 1-01111-00110-10011
Adam Lesinski31245b42014-08-22 19:10:56 -070092 EXPECT_EQ(char(0xbc), config.language[0]);
93 EXPECT_EQ(char(0xd3), config.language[1]);
Narayan Kamathb2975912014-06-30 15:59:39 +010094
Roozbeh Pournaderb927c552016-01-15 11:23:42 -080095 char out[4] = {1, 1, 1, 1};
Narayan Kamathb2975912014-06-30 15:59:39 +010096 config.unpackLanguage(out);
97 EXPECT_EQ('t', out[0]);
98 EXPECT_EQ('g', out[1]);
99 EXPECT_EQ('p', out[2]);
100 EXPECT_EQ(0, out[3]);
101}
102
Adam Lesinski31245b42014-08-22 19:10:56 -0700103TEST(ConfigLocaleTest, packAndUnpack3LetterRegion) {
Narayan Kamath378c6772014-01-20 13:57:11 +0000104 ResTable_config config;
105 config.packRegion("419");
106
Roozbeh Pournaderb927c552016-01-15 11:23:42 -0800107 char out[4] = {1, 1, 1, 1};
Narayan Kamath378c6772014-01-20 13:57:11 +0000108 config.unpackRegion(out);
109
110 EXPECT_EQ('4', out[0]);
111 EXPECT_EQ('1', out[1]);
112 EXPECT_EQ('9', out[2]);
113}
114
115/* static */ void fillIn(const char* lang, const char* country,
116 const char* script, const char* variant, ResTable_config* out) {
117 memset(out, 0, sizeof(ResTable_config));
118 if (lang != NULL) {
119 out->packLanguage(lang);
120 }
121
122 if (country != NULL) {
123 out->packRegion(country);
124 }
125
126 if (script != NULL) {
127 memcpy(out->localeScript, script, 4);
Roozbeh Pournader79608982016-03-03 15:06:46 -0800128 out->localeScriptWasComputed = false;
Roozbeh Pournaderb927c552016-01-15 11:23:42 -0800129 } else {
130 out->computeScript();
Roozbeh Pournader79608982016-03-03 15:06:46 -0800131 out->localeScriptWasComputed = true;
Narayan Kamath378c6772014-01-20 13:57:11 +0000132 }
133
134 if (variant != NULL) {
135 memcpy(out->localeVariant, variant, strlen(variant));
136 }
137}
138
Adam Lesinski31245b42014-08-22 19:10:56 -0700139TEST(ConfigLocaleTest, IsMoreSpecificThan) {
Narayan Kamath378c6772014-01-20 13:57:11 +0000140 ResTable_config l;
141 ResTable_config r;
142
143 fillIn("en", NULL, NULL, NULL, &l);
144 fillIn(NULL, NULL, NULL, NULL, &r);
145
146 EXPECT_TRUE(l.isMoreSpecificThan(r));
147 EXPECT_FALSE(r.isMoreSpecificThan(l));
148
149 fillIn("eng", NULL, NULL, NULL, &l);
150 EXPECT_TRUE(l.isMoreSpecificThan(r));
151 EXPECT_FALSE(r.isMoreSpecificThan(l));
152
153 fillIn("eng", "419", NULL, NULL, &r);
154 EXPECT_FALSE(l.isMoreSpecificThan(r));
155 EXPECT_TRUE(r.isMoreSpecificThan(l));
156
157 fillIn("en", NULL, NULL, NULL, &l);
158 fillIn("en", "US", NULL, NULL, &r);
159 EXPECT_FALSE(l.isMoreSpecificThan(r));
160 EXPECT_TRUE(r.isMoreSpecificThan(l));
161
162 fillIn("en", "US", NULL, NULL, &l);
163 fillIn("en", "US", "Latn", NULL, &r);
164 EXPECT_FALSE(l.isMoreSpecificThan(r));
165 EXPECT_TRUE(r.isMoreSpecificThan(l));
166
167 fillIn("en", "US", NULL, NULL, &l);
168 fillIn("en", "US", NULL, "POSIX", &r);
169 EXPECT_FALSE(l.isMoreSpecificThan(r));
170 EXPECT_TRUE(r.isMoreSpecificThan(l));
171
172 fillIn("en", "US", "Latn", NULL, &l);
173 fillIn("en", "US", NULL, "POSIX", &r);
174 EXPECT_FALSE(l.isMoreSpecificThan(r));
175 EXPECT_TRUE(r.isMoreSpecificThan(l));
176}
177
Adam Lesinski31245b42014-08-22 19:10:56 -0700178TEST(ConfigLocaleTest, setLocale) {
Narayan Kamath91447d82014-01-21 15:32:36 +0000179 ResTable_config test;
180 test.setBcp47Locale("en-US");
181 EXPECT_EQ('e', test.language[0]);
182 EXPECT_EQ('n', test.language[1]);
183 EXPECT_EQ('U', test.country[0]);
184 EXPECT_EQ('S', test.country[1]);
Roozbeh Pournader79608982016-03-03 15:06:46 -0800185 EXPECT_TRUE(test.localeScriptWasComputed);
Roozbeh Pournaderb927c552016-01-15 11:23:42 -0800186 EXPECT_EQ(0, memcmp("Latn", test.localeScript, 4));
Narayan Kamath91447d82014-01-21 15:32:36 +0000187 EXPECT_EQ(0, test.localeVariant[0]);
Igor Viarheichyke7bc60a2017-10-20 15:09:13 -0700188 EXPECT_EQ(0, test.localeNumberingSystem[0]);
Narayan Kamath91447d82014-01-21 15:32:36 +0000189
190 test.setBcp47Locale("eng-419");
Roozbeh Pournaderb927c552016-01-15 11:23:42 -0800191 char out[4] = {1, 1, 1, 1};
Narayan Kamath91447d82014-01-21 15:32:36 +0000192 test.unpackLanguage(out);
193 EXPECT_EQ('e', out[0]);
194 EXPECT_EQ('n', out[1]);
195 EXPECT_EQ('g', out[2]);
196 EXPECT_EQ(0, out[3]);
197 memset(out, 1, 4);
198 test.unpackRegion(out);
199 EXPECT_EQ('4', out[0]);
200 EXPECT_EQ('1', out[1]);
201 EXPECT_EQ('9', out[2]);
Igor Viarheichyke7bc60a2017-10-20 15:09:13 -0700202 EXPECT_EQ(0, test.localeNumberingSystem[0]);
Narayan Kamath91447d82014-01-21 15:32:36 +0000203
Narayan Kamath91447d82014-01-21 15:32:36 +0000204 test.setBcp47Locale("en-Latn-419");
Narayan Kamath91447d82014-01-21 15:32:36 +0000205 EXPECT_EQ('e', test.language[0]);
206 EXPECT_EQ('n', test.language[1]);
Narayan Kamath91447d82014-01-21 15:32:36 +0000207 EXPECT_EQ(0, memcmp("Latn", test.localeScript, 4));
Roozbeh Pournader79608982016-03-03 15:06:46 -0800208 EXPECT_FALSE(test.localeScriptWasComputed);
Roozbeh Pournaderb927c552016-01-15 11:23:42 -0800209 memset(out, 1, 4);
Narayan Kamath91447d82014-01-21 15:32:36 +0000210 test.unpackRegion(out);
211 EXPECT_EQ('4', out[0]);
212 EXPECT_EQ('1', out[1]);
213 EXPECT_EQ('9', out[2]);
Igor Viarheichyke7bc60a2017-10-20 15:09:13 -0700214 EXPECT_EQ(0, test.localeNumberingSystem[0]);
Roozbeh Pournaderb927c552016-01-15 11:23:42 -0800215
216 test.setBcp47Locale("de-1901");
217 memset(out, 1, 4);
218 test.unpackLanguage(out);
219 EXPECT_EQ('d', out[0]);
220 EXPECT_EQ('e', out[1]);
221 EXPECT_EQ('\0', out[2]);
Roozbeh Pournader79608982016-03-03 15:06:46 -0800222 EXPECT_TRUE(test.localeScriptWasComputed);
Roozbeh Pournaderb927c552016-01-15 11:23:42 -0800223 EXPECT_EQ(0, memcmp("Latn", test.localeScript, 4));
224 memset(out, 1, 4);
225 test.unpackRegion(out);
226 EXPECT_EQ('\0', out[0]);
227 EXPECT_EQ(0, strcmp("1901", test.localeVariant));
Igor Viarheichyke7bc60a2017-10-20 15:09:13 -0700228 EXPECT_EQ(0, test.localeNumberingSystem[0]);
Roozbeh Pournaderb927c552016-01-15 11:23:42 -0800229
230 test.setBcp47Locale("de-Latn-1901");
231 memset(out, 1, 4);
232 test.unpackLanguage(out);
233 EXPECT_EQ('d', out[0]);
234 EXPECT_EQ('e', out[1]);
235 EXPECT_EQ('\0', out[2]);
Roozbeh Pournader79608982016-03-03 15:06:46 -0800236 EXPECT_FALSE(test.localeScriptWasComputed);
Roozbeh Pournaderb927c552016-01-15 11:23:42 -0800237 EXPECT_EQ(0, memcmp("Latn", test.localeScript, 4));
238 memset(out, 1, 4);
239 test.unpackRegion(out);
240 EXPECT_EQ('\0', out[0]);
241 EXPECT_EQ(0, strcmp("1901", test.localeVariant));
Igor Viarheichyke7bc60a2017-10-20 15:09:13 -0700242 EXPECT_EQ(0, test.localeNumberingSystem[0]);
243
244 test.setBcp47Locale("ar-EG-u-nu-latn");
245 EXPECT_EQ('a', test.language[0]);
246 EXPECT_EQ('r', test.language[1]);
247 EXPECT_EQ('E', test.country[0]);
248 EXPECT_EQ('G', test.country[1]);
249 EXPECT_TRUE(test.localeScriptWasComputed);
250 EXPECT_EQ(0, memcmp("Arab", test.localeScript, 4));
251 EXPECT_EQ(0, test.localeVariant[0]);
252 EXPECT_EQ(0, memcmp("latn", test.localeNumberingSystem, 4));
253
254 test.setBcp47Locale("ar-EG-u");
255 EXPECT_EQ(0, test.localeNumberingSystem[0]);
256
257 test.setBcp47Locale("ar-EG-u-nu");
258 EXPECT_EQ(0, test.localeNumberingSystem[0]);
259
260 test.setBcp47Locale("ar-EG-u-attr-nu-latn");
261 EXPECT_EQ(0, memcmp("latn", test.localeNumberingSystem, 4));
262
263 test.setBcp47Locale("ar-EG-u-ca-gregory-nu-latn");
264 EXPECT_EQ(0, memcmp("latn", test.localeNumberingSystem, 4));
265
266 test.setBcp47Locale("ar-EG-u-nu-latn-ca-gregory");
267 EXPECT_EQ(0, memcmp("latn", test.localeNumberingSystem, 4));
268
269 test.setBcp47Locale("ar-EG-u-nu-toolongnumsys");
270 EXPECT_EQ(0, test.localeNumberingSystem[0]);
271
272 test.setBcp47Locale("ar-EG-u-nu-latn-nu-arab");
273 EXPECT_EQ(0, memcmp("latn", test.localeNumberingSystem, 4));
274
275 test.setBcp47Locale("ar-EG-u-co-nu-latn");
276 EXPECT_EQ(0, test.localeNumberingSystem[0]);
277
278 test.setBcp47Locale("ar-u-co-abcd-attr-nu-latn");
279 EXPECT_EQ(0, test.localeNumberingSystem[0]);
Narayan Kamath91447d82014-01-21 15:32:36 +0000280}
Narayan Kamath378c6772014-01-20 13:57:11 +0000281
Roozbeh Pournaderb927c552016-01-15 11:23:42 -0800282TEST(ConfigLocaleTest, computeScript) {
283 ResTable_config config;
284
285 fillIn(NULL, NULL, NULL, NULL, &config);
286 EXPECT_EQ(0, memcmp("\0\0\0\0", config.localeScript, 4));
287
288 fillIn("zh", "TW", NULL, NULL, &config);
289 EXPECT_EQ(0, memcmp("Hant", config.localeScript, 4));
290
291 fillIn("zh", "CN", NULL, NULL, &config);
292 EXPECT_EQ(0, memcmp("Hans", config.localeScript, 4));
293
294 fillIn("az", NULL, NULL, NULL, &config);
295 EXPECT_EQ(0, memcmp("Latn", config.localeScript, 4));
296
297 fillIn("az", "AZ", NULL, NULL, &config);
298 EXPECT_EQ(0, memcmp("Latn", config.localeScript, 4));
299
300 fillIn("az", "IR", NULL, NULL, &config);
301 EXPECT_EQ(0, memcmp("Arab", config.localeScript, 4));
302
303 fillIn("peo", NULL, NULL, NULL, &config);
304 EXPECT_EQ(0, memcmp("Xpeo", config.localeScript, 4));
305
306 fillIn("qaa", NULL, NULL, NULL, &config);
307 EXPECT_EQ(0, memcmp("\0\0\0\0", config.localeScript, 4));
308}
309
310TEST(ConfigLocaleTest, getBcp47Locale_script) {
311 ResTable_config config;
312 fillIn("en", NULL, "Latn", NULL, &config);
313
314 char out[RESTABLE_MAX_LOCALE_LEN];
Roozbeh Pournader79608982016-03-03 15:06:46 -0800315 config.localeScriptWasComputed = false;
Roozbeh Pournaderb927c552016-01-15 11:23:42 -0800316 config.getBcp47Locale(out);
317 EXPECT_EQ(0, strcmp("en-Latn", out));
318
Roozbeh Pournader79608982016-03-03 15:06:46 -0800319 config.localeScriptWasComputed = true;
Roozbeh Pournaderb927c552016-01-15 11:23:42 -0800320 config.getBcp47Locale(out);
321 EXPECT_EQ(0, strcmp("en", out));
322}
323
Roozbeh Pournader7e5f96f2016-06-13 18:10:49 -0700324TEST(ConfigLocaleTest, getBcp47Locale_canonicalize) {
325 ResTable_config config;
326 char out[RESTABLE_MAX_LOCALE_LEN];
327
328 fillIn("tl", NULL, NULL, NULL, &config);
329 config.getBcp47Locale(out);
330 EXPECT_EQ(0, strcmp("tl", out));
331 config.getBcp47Locale(out, true /* canonicalize */);
332 EXPECT_EQ(0, strcmp("fil", out));
333
334 fillIn("tl", "PH", NULL, NULL, &config);
335 config.getBcp47Locale(out);
336 EXPECT_EQ(0, strcmp("tl-PH", out));
337 config.getBcp47Locale(out, true /* canonicalize */);
338 EXPECT_EQ(0, strcmp("fil-PH", out));
339}
340
Roozbeh Pournaderb927c552016-01-15 11:23:42 -0800341TEST(ConfigLocaleTest, match) {
342 ResTable_config supported, requested;
343
344 fillIn(NULL, NULL, NULL, NULL, &supported);
345 fillIn("fr", "CA", NULL, NULL, &requested);
346 // Empty locale matches everything (as a default).
347 EXPECT_TRUE(supported.match(requested));
348
349 fillIn("en", "CA", NULL, NULL, &supported);
350 fillIn("fr", "CA", NULL, NULL, &requested);
351 // Different languages don't match.
352 EXPECT_FALSE(supported.match(requested));
353
Roozbeh Pournader7e5f96f2016-06-13 18:10:49 -0700354 fillIn("tl", "PH", NULL, NULL, &supported);
355 fillIn("fil", "PH", NULL, NULL, &requested);
356 // Equivalent languages match.
357 EXPECT_TRUE(supported.match(requested));
358
Roozbeh Pournaderb927c552016-01-15 11:23:42 -0800359 fillIn("qaa", "FR", NULL, NULL, &supported);
360 fillIn("qaa", "CA", NULL, NULL, &requested);
361 // If we can't infer the scripts, different regions don't match.
362 EXPECT_FALSE(supported.match(requested));
363
364 fillIn("qaa", "FR", "Latn", NULL, &supported);
365 fillIn("qaa", "CA", NULL, NULL, &requested);
366 // If we can't infer any of the scripts, different regions don't match.
367 EXPECT_FALSE(supported.match(requested));
368
369 fillIn("qaa", "FR", NULL, NULL, &supported);
370 fillIn("qaa", "CA", "Latn", NULL, &requested);
371 // If we can't infer any of the scripts, different regions don't match.
372 EXPECT_FALSE(supported.match(requested));
373
374 fillIn("qaa", NULL, NULL, NULL, &supported);
375 fillIn("qaa", "CA", NULL, NULL, &requested);
376 // language-only resources still support language+region requests, even if we can't infer the
377 // script.
378 EXPECT_TRUE(supported.match(requested));
379
380 fillIn("qaa", "CA", NULL, NULL, &supported);
381 fillIn("qaa", "CA", NULL, NULL, &requested);
382 // Even if we can't infer the scripts, exactly equal locales match.
383 EXPECT_TRUE(supported.match(requested));
384
385 fillIn("az", NULL, NULL, NULL, &supported);
386 fillIn("az", NULL, "Latn", NULL, &requested);
387 // If the resolved scripts are the same, it doesn't matter if they were explicitly provided
388 // or not, and they match.
389 EXPECT_TRUE(supported.match(requested));
390
391 fillIn("az", NULL, NULL, NULL, &supported);
392 fillIn("az", NULL, "Cyrl", NULL, &requested);
393 // If the resolved scripts are different, they don't match.
394 EXPECT_FALSE(supported.match(requested));
395
396 fillIn("az", NULL, NULL, NULL, &supported);
397 fillIn("az", "IR", NULL, NULL, &requested);
398 // If the resolved scripts are different, they don't match.
399 EXPECT_FALSE(supported.match(requested));
400
401 fillIn("az", "IR", NULL, NULL, &supported);
402 fillIn("az", NULL, "Arab", NULL, &requested);
403 // If the resolved scripts are the same, it doesn't matter if they were explicitly provided
404 // or not, and they match.
405 EXPECT_TRUE(supported.match(requested));
406
407 fillIn("en", NULL, NULL, NULL, &supported);
408 fillIn("en", "XA", NULL, NULL, &requested);
409 // en-XA is a pseudo-locale, and English resources are not a match for it.
410 EXPECT_FALSE(supported.match(requested));
411
412 fillIn("en", "XA", NULL, NULL, &supported);
413 fillIn("en", NULL, NULL, NULL, &requested);
414 // en-XA is a pseudo-locale, and its resources don't support English locales.
415 EXPECT_FALSE(supported.match(requested));
416
417 fillIn("en", "XA", NULL, NULL, &supported);
418 fillIn("en", "XA", NULL, NULL, &requested);
419 // Even if they are pseudo-locales, exactly equal locales match.
420 EXPECT_TRUE(supported.match(requested));
421
422 fillIn("ar", NULL, NULL, NULL, &supported);
423 fillIn("ar", "XB", NULL, NULL, &requested);
424 // ar-XB is a pseudo-locale, and Arabic resources are not a match for it.
425 EXPECT_FALSE(supported.match(requested));
426
427 fillIn("ar", "XB", NULL, NULL, &supported);
428 fillIn("ar", NULL, NULL, NULL, &requested);
429 // ar-XB is a pseudo-locale, and its resources don't support Arabic locales.
430 EXPECT_FALSE(supported.match(requested));
431
432 fillIn("ar", "XB", NULL, NULL, &supported);
433 fillIn("ar", "XB", NULL, NULL, &requested);
434 // Even if they are pseudo-locales, exactly equal locales match.
435 EXPECT_TRUE(supported.match(requested));
436}
437
Roozbeh Pournader4de45962016-02-11 17:58:24 -0800438TEST(ConfigLocaleTest, match_emptyScript) {
439 ResTable_config supported, requested;
440
441 fillIn("fr", "FR", NULL, NULL, &supported);
442 fillIn("fr", "CA", NULL, NULL, &requested);
443
444 // emulate packages built with older AAPT
445 memset(supported.localeScript, '\0', 4);
Roozbeh Pournader79608982016-03-03 15:06:46 -0800446 supported.localeScriptWasComputed = false;
Roozbeh Pournader4de45962016-02-11 17:58:24 -0800447
448 EXPECT_TRUE(supported.match(requested));
449}
450
Roozbeh Pournaderb927c552016-01-15 11:23:42 -0800451TEST(ConfigLocaleTest, isLocaleBetterThan_basics) {
452 ResTable_config config1, config2, request;
453
454 fillIn(NULL, NULL, NULL, NULL, &request);
455 fillIn("fr", "FR", NULL, NULL, &config1);
456 fillIn("fr", "CA", NULL, NULL, &config2);
457 EXPECT_FALSE(config1.isLocaleBetterThan(config2, &request));
458 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
459
460 fillIn("fr", "CA", NULL, NULL, &request);
461 fillIn(NULL, NULL, NULL, NULL, &config1);
462 fillIn(NULL, NULL, NULL, NULL, &config2);
463 EXPECT_FALSE(config1.isLocaleBetterThan(config2, &request));
464 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
465
466 fillIn("fr", "CA", NULL, NULL, &request);
467 fillIn("fr", "FR", NULL, NULL, &config1);
468 fillIn(NULL, NULL, NULL, NULL, &config2);
469 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
470 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
471
472 fillIn("de", "DE", NULL, NULL, &request);
Roozbeh Pournader7e5f96f2016-06-13 18:10:49 -0700473 fillIn("de", "DE", NULL, NULL, &config1);
474 fillIn("de", "DE", NULL, "1901", &config2);
475 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
476 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
477
478 fillIn("de", "DE", NULL, NULL, &request);
Roozbeh Pournaderb927c552016-01-15 11:23:42 -0800479 fillIn("de", "DE", NULL, "1901", &config1);
480 fillIn("de", "DE", NULL, "1996", &config2);
481 EXPECT_FALSE(config1.isLocaleBetterThan(config2, &request));
482 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
483
484 fillIn("de", "DE", NULL, "1901", &request);
485 fillIn("de", "DE", NULL, "1901", &config1);
486 fillIn("de", "DE", NULL, NULL, &config2);
487 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
488 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
489
490 fillIn("de", "DE", NULL, "1901", &request);
491 fillIn("de", "DE", NULL, "1996", &config1);
492 fillIn("de", "DE", NULL, NULL, &config2);
493 EXPECT_FALSE(config1.isLocaleBetterThan(config2, &request));
494 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
Roozbeh Pournader7e5f96f2016-06-13 18:10:49 -0700495
496 fillIn("fil", "PH", NULL, NULL, &request);
497 fillIn("tl", "PH", NULL, NULL, &config1);
498 fillIn("fil", "US", NULL, NULL, &config2);
499 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
500 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
501
502 fillIn("fil", "PH", NULL, "fonipa", &request);
503 fillIn("tl", "PH", NULL, "fonipa", &config1);
504 fillIn("fil", "PH", NULL, NULL, &config2);
505 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
506 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
507
508 fillIn("fil", "PH", NULL, NULL, &request);
509 fillIn("fil", "PH", NULL, NULL, &config1);
510 fillIn("tl", "PH", NULL, NULL, &config2);
511 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
512 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
Roozbeh Pournaderb927c552016-01-15 11:23:42 -0800513}
514
515TEST(ConfigLocaleTest, isLocaleBetterThan_regionComparison) {
516 ResTable_config config1, config2, request;
517
518 fillIn("es", "AR", NULL, NULL, &request);
519 fillIn("es", "419", NULL, NULL, &config1);
520 fillIn("es", "419", NULL, NULL, &config2);
521 // Both supported locales are the same, so none is better than the other.
522 EXPECT_FALSE(config1.isLocaleBetterThan(config2, &request));
523 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
524
525 fillIn("es", "AR", NULL, NULL, &request);
526 fillIn("es", "AR", NULL, NULL, &config1);
527 fillIn("es", "419", NULL, NULL, &config2);
528 // An exact locale match is better than a parent.
529 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
530 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
531
532 fillIn("es", "AR", NULL, NULL, &request);
533 fillIn("es", "419", NULL, NULL, &config1);
534 fillIn("es", NULL, NULL, NULL, &config2);
535 // A closer parent is better.
536 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
537 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
538
539 fillIn("es", "AR", NULL, NULL, &request);
540 fillIn("es", "419", NULL, NULL, &config1);
541 fillIn("es", "ES", NULL, NULL, &config2);
542 // A parent is better than a non-parent representative locale.
543 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
544 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
545
546 fillIn("es", "AR", NULL, NULL, &request);
547 fillIn("es", NULL, NULL, NULL, &config1);
548 fillIn("es", "ES", NULL, NULL, &config2);
549 // A parent is better than a non-parent representative locale.
550 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
551 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
552
553 fillIn("es", "AR", NULL, NULL, &request);
554 fillIn("es", "PE", NULL, NULL, &config1);
555 fillIn("es", "ES", NULL, NULL, &config2);
556 // A closer locale is better.
557 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
558 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
559
560 fillIn("es", "AR", NULL, NULL, &request);
Roozbeh Pournadera192a8c2017-01-10 15:24:32 -0800561 fillIn("es", "US", NULL, NULL, &config1);
562 fillIn("es", NULL, NULL, NULL, &config2);
563 // Special case for Latin American Spanish: es-MX and es-US are
564 // pseudo-parents of all Latin Ameircan Spanish locales.
565 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
566 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
567
568 fillIn("es", "MX", NULL, NULL, &request);
569 fillIn("es", "US", NULL, NULL, &config1);
570 fillIn("es", NULL, NULL, NULL, &config2);
571 // Special case for Latin American Spanish: es-MX and es-US are
572 // pseudo-parents of all Latin Ameircan Spanish locales.
573 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
574 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
575
576 fillIn("es", "AR", NULL, NULL, &request);
577 fillIn("es", "MX", NULL, NULL, &config1);
578 fillIn("es", NULL, NULL, NULL, &config2);
579 // Special case for Latin American Spanish: es-MX and es-US are
580 // pseudo-parents of all Latin Ameircan Spanish locales.
581 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
582 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
583
584 fillIn("es", "US", NULL, NULL, &request);
585 fillIn("es", "MX", NULL, NULL, &config1);
586 fillIn("es", NULL, NULL, NULL, &config2);
587 // Special case for Latin American Spanish: es-MX and es-US are
588 // pseudo-parents of all Latin Ameircan Spanish locales.
589 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
590 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
591
592 fillIn("es", "AR", NULL, NULL, &request);
593 fillIn("es", "419", NULL, NULL, &config1);
594 fillIn("es", "MX", NULL, NULL, &config2);
595 // Even though es-MX and es-US are pseudo-parents of all Latin Ameircan
596 // Spanish locales, es-419 is a closer parent.
597 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
598 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
599
600 fillIn("es", "US", NULL, NULL, &request);
601 fillIn("es", "419", NULL, NULL, &config1);
602 fillIn("es", "MX", NULL, NULL, &config2);
603 // Even though es-MX and es-US are pseudo-parents of all Latin Ameircan
604 // Spanish locales, es-419 is a closer parent.
605 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
606 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
607
608 fillIn("es", "MX", NULL, NULL, &request);
609 fillIn("es", "419", NULL, NULL, &config1);
610 fillIn("es", "US", NULL, NULL, &config2);
611 // Even though es-MX and es-US are pseudo-parents of all Latin Ameircan
612 // Spanish locales, es-419 is a closer parent.
613 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
614 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
615
616 fillIn("es", "AR", NULL, NULL, &request);
Roozbeh Pournaderb927c552016-01-15 11:23:42 -0800617 fillIn("es", "MX", NULL, NULL, &config1);
618 fillIn("es", "BO", NULL, NULL, &config2);
Roozbeh Pournadera192a8c2017-01-10 15:24:32 -0800619 // Special case for Latin American Spanish: es-MX and es-US are
620 // pseudo-parents of all Latin Ameircan Spanish locales.
Roozbeh Pournaderb927c552016-01-15 11:23:42 -0800621 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
622 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
623
624 fillIn("es", "AR", NULL, NULL, &request);
625 fillIn("es", "US", NULL, NULL, &config1);
626 fillIn("es", "BO", NULL, NULL, &config2);
Roozbeh Pournadera192a8c2017-01-10 15:24:32 -0800627 // Special case for Latin American Spanish: es-MX and es-US are
628 // pseudo-parents of all Latin Ameircan Spanish locales.
629 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
630 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
631
632 fillIn("es", "IC", NULL, NULL, &request);
633 fillIn("es", "ES", NULL, NULL, &config1);
634 fillIn("es", "GQ", NULL, NULL, &config2);
Roozbeh Pournaderb927c552016-01-15 11:23:42 -0800635 // A representative locale is better if they are equidistant.
636 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
637 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
638
639 fillIn("es", "AR", NULL, NULL, &request);
640 fillIn("es", "MX", NULL, NULL, &config1);
641 fillIn("es", "US", NULL, NULL, &config2);
642 // If all is equal, the locale earlier in the dictionary is better.
643 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
644 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
645
646 fillIn("es", "GQ", NULL, NULL, &request);
647 fillIn("es", "IC", NULL, NULL, &config1);
648 fillIn("es", "419", NULL, NULL, &config2);
649 // If all is equal, the locale earlier in the dictionary is better and
650 // letters are better than numbers.
651 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
652 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
653
654 fillIn("en", "GB", NULL, NULL, &request);
655 fillIn("en", "001", NULL, NULL, &config1);
656 fillIn("en", NULL, NULL, NULL, &config2);
657 // A closer parent is better.
658 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
659 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
660
661 fillIn("en", "PR", NULL, NULL, &request);
662 fillIn("en", NULL, NULL, NULL, &config1);
663 fillIn("en", "001", NULL, NULL, &config2);
664 // A parent is better than a non-parent.
665 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
666 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
667
668 fillIn("en", "DE", NULL, NULL, &request);
669 fillIn("en", "150", NULL, NULL, &config1);
670 fillIn("en", "001", NULL, NULL, &config2);
671 // A closer parent is better.
672 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
673 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
674
675 fillIn("en", "IN", NULL, NULL, &request);
676 fillIn("en", "AU", NULL, NULL, &config1);
677 fillIn("en", "US", NULL, NULL, &config2);
678 // A closer locale is better.
679 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
680 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
681
682 fillIn("en", "PR", NULL, NULL, &request);
683 fillIn("en", "001", NULL, NULL, &config1);
684 fillIn("en", "GB", NULL, NULL, &config2);
685 // A closer locale is better.
686 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
687 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
688
689 fillIn("en", "IN", NULL, NULL, &request);
690 fillIn("en", "GB", NULL, NULL, &config1);
691 fillIn("en", "AU", NULL, NULL, &config2);
692 // A representative locale is better if they are equidistant.
693 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
694 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
695
696 fillIn("en", "IN", NULL, NULL, &request);
697 fillIn("en", "AU", NULL, NULL, &config1);
698 fillIn("en", "CA", NULL, NULL, &config2);
699 // If all is equal, the locale earlier in the dictionary is better.
700 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
701 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
702
703 fillIn("pt", "MZ", NULL, NULL, &request);
704 fillIn("pt", "PT", NULL, NULL, &config1);
705 fillIn("pt", NULL, NULL, NULL, &config2);
706 // A closer parent is better.
707 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
708 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
709
710 fillIn("pt", "MZ", NULL, NULL, &request);
711 fillIn("pt", "PT", NULL, NULL, &config1);
712 fillIn("pt", "BR", NULL, NULL, &config2);
713 // A parent is better than a non-parent.
714 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
715 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
716
717 fillIn("zh", "MO", "Hant", NULL, &request);
718 fillIn("zh", "HK", "Hant", NULL, &config1);
719 fillIn("zh", "TW", "Hant", NULL, &config2);
720 // A parent is better than a non-parent.
721 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
722 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
723
724 fillIn("zh", "US", "Hant", NULL, &request);
725 fillIn("zh", "TW", "Hant", NULL, &config1);
726 fillIn("zh", "HK", "Hant", NULL, &config2);
727 // A representative locale is better if they are equidistant.
728 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
729 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
730
731 fillIn("ar", "DZ", NULL, NULL, &request);
732 fillIn("ar", "015", NULL, NULL, &config1);
733 fillIn("ar", NULL, NULL, NULL, &config2);
734 // A closer parent is better.
735 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
736 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
737
738 fillIn("ar", "EG", NULL, NULL, &request);
739 fillIn("ar", NULL, NULL, NULL, &config1);
740 fillIn("ar", "015", NULL, NULL, &config2);
741 // A parent is better than a non-parent.
742 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
743 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
744
745 fillIn("ar", "QA", NULL, NULL, &request);
746 fillIn("ar", "EG", NULL, NULL, &config1);
747 fillIn("ar", "BH", NULL, NULL, &config2);
748 // A representative locale is better if they are equidistant.
749 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
750 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
751
752 fillIn("ar", "QA", NULL, NULL, &request);
753 fillIn("ar", "SA", NULL, NULL, &config1);
754 fillIn("ar", "015", NULL, NULL, &config2);
755 // If all is equal, the locale earlier in the dictionary is better and
756 // letters are better than numbers.
757 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
758 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
759}
760
Roozbeh Pournader27953c32016-02-01 13:49:52 -0800761// Default resources are considered better matches for US English
762// and US-like English locales than International English locales
763TEST(ConfigLocaleTest, isLocaleBetterThan_UsEnglishIsSpecial) {
764 ResTable_config config1, config2, request;
765
766 fillIn("en", "US", NULL, NULL, &request);
767 fillIn(NULL, NULL, NULL, NULL, &config1);
768 fillIn("en", "001", NULL, NULL, &config2);
769 // default is better than International English
770 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
771 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
772
773 fillIn("en", "US", NULL, NULL, &request);
774 fillIn(NULL, NULL, NULL, NULL, &config1);
775 fillIn("en", "GB", NULL, NULL, &config2);
776 // default is better than British English
777 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
778 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
779
780 fillIn("en", "PR", NULL, NULL, &request);
781 fillIn(NULL, NULL, NULL, NULL, &config1);
782 fillIn("en", "001", NULL, NULL, &config2);
783 // Even for Puerto Rico, default is better than International English
784 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
785 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
786
787 fillIn("en", "US", NULL, NULL, &request);
788 fillIn("en", NULL, NULL, NULL, &config1);
789 fillIn(NULL, NULL, NULL, NULL, &config2);
790 // "English" is better than default, since it's a parent of US English
791 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
792 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
793
794 fillIn("en", "PR", NULL, NULL, &request);
795 fillIn("en", NULL, NULL, NULL, &config1);
796 fillIn(NULL, NULL, NULL, NULL, &config2);
797 // "English" is better than default, since it's a parent of Puerto Rico English
798 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
799 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
800
801 fillIn("en", "US", NULL, NULL, &request);
802 fillIn(NULL, NULL, NULL, NULL, &config1);
803 fillIn("en", "PR", NULL, NULL, &config2);
804 // For US English itself, we prefer default to its siblings in the parent tree
805 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
806 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
807}
808
Roozbeh Pournaderb927c552016-01-15 11:23:42 -0800809} // namespace android