1/* 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 17#include <androidfw/LocaleData.h> 18#include <androidfw/ResourceTypes.h> 19#include <utils/Log.h> 20#include <utils/String8.h> 21 22#include <gtest/gtest.h> 23namespace android { 24 25TEST(ConfigLocaleTest, packAndUnpack2LetterLanguage) { 26 ResTable_config config; 27 config.packLanguage("en"); 28 29 EXPECT_EQ('e', config.language[0]); 30 EXPECT_EQ('n', config.language[1]); 31 32 char out[4] = {1, 1, 1, 1}; 33 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 48TEST(ConfigLocaleTest, packAndUnpack2LetterRegion) { 49 ResTable_config config; 50 config.packRegion("US"); 51 52 EXPECT_EQ('U', config.country[0]); 53 EXPECT_EQ('S', config.country[1]); 54 55 char out[4] = {1, 1, 1, 1}; 56 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 63TEST(ConfigLocaleTest, packAndUnpack3LetterLanguage) { 64 ResTable_config config; 65 config.packLanguage("eng"); 66 67 // 1-00110-01 101-00100 68 EXPECT_EQ('\x99', config.language[0]); 69 EXPECT_EQ('\xA4', config.language[1]); 70 71 char out[4] = {1, 1, 1, 1}; 72 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 79TEST(ConfigLocaleTest, packAndUnpack3LetterLanguageAtOffset16) { 80 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 92 EXPECT_EQ(char(0xbc), config.language[0]); 93 EXPECT_EQ(char(0xd3), config.language[1]); 94 95 char out[4] = {1, 1, 1, 1}; 96 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 103TEST(ConfigLocaleTest, packAndUnpack3LetterRegion) { 104 ResTable_config config; 105 config.packRegion("419"); 106 107 char out[4] = {1, 1, 1, 1}; 108 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); 128 out->localeScriptWasComputed = false; 129 } else { 130 out->computeScript(); 131 out->localeScriptWasComputed = true; 132 } 133 134 if (variant != NULL) { 135 memcpy(out->localeVariant, variant, strlen(variant)); 136 } 137} 138 139TEST(ConfigLocaleTest, IsMoreSpecificThan) { 140 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 178TEST(ConfigLocaleTest, setLocale) { 179 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]); 185 EXPECT_TRUE(test.localeScriptWasComputed); 186 EXPECT_EQ(0, memcmp("Latn", test.localeScript, 4)); 187 EXPECT_EQ(0, test.localeVariant[0]); 188 189 test.setBcp47Locale("eng-419"); 190 char out[4] = {1, 1, 1, 1}; 191 test.unpackLanguage(out); 192 EXPECT_EQ('e', out[0]); 193 EXPECT_EQ('n', out[1]); 194 EXPECT_EQ('g', out[2]); 195 EXPECT_EQ(0, out[3]); 196 memset(out, 1, 4); 197 test.unpackRegion(out); 198 EXPECT_EQ('4', out[0]); 199 EXPECT_EQ('1', out[1]); 200 EXPECT_EQ('9', out[2]); 201 202 test.setBcp47Locale("en-Latn-419"); 203 EXPECT_EQ('e', test.language[0]); 204 EXPECT_EQ('n', test.language[1]); 205 EXPECT_EQ(0, memcmp("Latn", test.localeScript, 4)); 206 EXPECT_FALSE(test.localeScriptWasComputed); 207 memset(out, 1, 4); 208 test.unpackRegion(out); 209 EXPECT_EQ('4', out[0]); 210 EXPECT_EQ('1', out[1]); 211 EXPECT_EQ('9', out[2]); 212 213 test.setBcp47Locale("de-1901"); 214 memset(out, 1, 4); 215 test.unpackLanguage(out); 216 EXPECT_EQ('d', out[0]); 217 EXPECT_EQ('e', out[1]); 218 EXPECT_EQ('\0', out[2]); 219 EXPECT_TRUE(test.localeScriptWasComputed); 220 EXPECT_EQ(0, memcmp("Latn", test.localeScript, 4)); 221 memset(out, 1, 4); 222 test.unpackRegion(out); 223 EXPECT_EQ('\0', out[0]); 224 EXPECT_EQ(0, strcmp("1901", test.localeVariant)); 225 226 test.setBcp47Locale("de-Latn-1901"); 227 memset(out, 1, 4); 228 test.unpackLanguage(out); 229 EXPECT_EQ('d', out[0]); 230 EXPECT_EQ('e', out[1]); 231 EXPECT_EQ('\0', out[2]); 232 EXPECT_FALSE(test.localeScriptWasComputed); 233 EXPECT_EQ(0, memcmp("Latn", test.localeScript, 4)); 234 memset(out, 1, 4); 235 test.unpackRegion(out); 236 EXPECT_EQ('\0', out[0]); 237 EXPECT_EQ(0, strcmp("1901", test.localeVariant)); 238} 239 240TEST(ConfigLocaleTest, computeScript) { 241 ResTable_config config; 242 243 fillIn(NULL, NULL, NULL, NULL, &config); 244 EXPECT_EQ(0, memcmp("\0\0\0\0", config.localeScript, 4)); 245 246 fillIn("zh", "TW", NULL, NULL, &config); 247 EXPECT_EQ(0, memcmp("Hant", config.localeScript, 4)); 248 249 fillIn("zh", "CN", NULL, NULL, &config); 250 EXPECT_EQ(0, memcmp("Hans", config.localeScript, 4)); 251 252 fillIn("az", NULL, NULL, NULL, &config); 253 EXPECT_EQ(0, memcmp("Latn", config.localeScript, 4)); 254 255 fillIn("az", "AZ", NULL, NULL, &config); 256 EXPECT_EQ(0, memcmp("Latn", config.localeScript, 4)); 257 258 fillIn("az", "IR", NULL, NULL, &config); 259 EXPECT_EQ(0, memcmp("Arab", config.localeScript, 4)); 260 261 fillIn("peo", NULL, NULL, NULL, &config); 262 EXPECT_EQ(0, memcmp("Xpeo", config.localeScript, 4)); 263 264 fillIn("qaa", NULL, NULL, NULL, &config); 265 EXPECT_EQ(0, memcmp("\0\0\0\0", config.localeScript, 4)); 266} 267 268TEST(ConfigLocaleTest, getBcp47Locale_script) { 269 ResTable_config config; 270 fillIn("en", NULL, "Latn", NULL, &config); 271 272 char out[RESTABLE_MAX_LOCALE_LEN]; 273 config.localeScriptWasComputed = false; 274 config.getBcp47Locale(out); 275 EXPECT_EQ(0, strcmp("en-Latn", out)); 276 277 config.localeScriptWasComputed = true; 278 config.getBcp47Locale(out); 279 EXPECT_EQ(0, strcmp("en", out)); 280} 281 282TEST(ConfigLocaleTest, match) { 283 ResTable_config supported, requested; 284 285 fillIn(NULL, NULL, NULL, NULL, &supported); 286 fillIn("fr", "CA", NULL, NULL, &requested); 287 // Empty locale matches everything (as a default). 288 EXPECT_TRUE(supported.match(requested)); 289 290 fillIn("en", "CA", NULL, NULL, &supported); 291 fillIn("fr", "CA", NULL, NULL, &requested); 292 // Different languages don't match. 293 EXPECT_FALSE(supported.match(requested)); 294 295 fillIn("qaa", "FR", NULL, NULL, &supported); 296 fillIn("qaa", "CA", NULL, NULL, &requested); 297 // If we can't infer the scripts, different regions don't match. 298 EXPECT_FALSE(supported.match(requested)); 299 300 fillIn("qaa", "FR", "Latn", NULL, &supported); 301 fillIn("qaa", "CA", NULL, NULL, &requested); 302 // If we can't infer any of the scripts, different regions don't match. 303 EXPECT_FALSE(supported.match(requested)); 304 305 fillIn("qaa", "FR", NULL, NULL, &supported); 306 fillIn("qaa", "CA", "Latn", NULL, &requested); 307 // If we can't infer any of the scripts, different regions don't match. 308 EXPECT_FALSE(supported.match(requested)); 309 310 fillIn("qaa", NULL, NULL, NULL, &supported); 311 fillIn("qaa", "CA", NULL, NULL, &requested); 312 // language-only resources still support language+region requests, even if we can't infer the 313 // script. 314 EXPECT_TRUE(supported.match(requested)); 315 316 fillIn("qaa", "CA", NULL, NULL, &supported); 317 fillIn("qaa", "CA", NULL, NULL, &requested); 318 // Even if we can't infer the scripts, exactly equal locales match. 319 EXPECT_TRUE(supported.match(requested)); 320 321 fillIn("az", NULL, NULL, NULL, &supported); 322 fillIn("az", NULL, "Latn", NULL, &requested); 323 // If the resolved scripts are the same, it doesn't matter if they were explicitly provided 324 // or not, and they match. 325 EXPECT_TRUE(supported.match(requested)); 326 327 fillIn("az", NULL, NULL, NULL, &supported); 328 fillIn("az", NULL, "Cyrl", NULL, &requested); 329 // If the resolved scripts are different, they don't match. 330 EXPECT_FALSE(supported.match(requested)); 331 332 fillIn("az", NULL, NULL, NULL, &supported); 333 fillIn("az", "IR", NULL, NULL, &requested); 334 // If the resolved scripts are different, they don't match. 335 EXPECT_FALSE(supported.match(requested)); 336 337 fillIn("az", "IR", NULL, NULL, &supported); 338 fillIn("az", NULL, "Arab", NULL, &requested); 339 // If the resolved scripts are the same, it doesn't matter if they were explicitly provided 340 // or not, and they match. 341 EXPECT_TRUE(supported.match(requested)); 342 343 fillIn("en", NULL, NULL, NULL, &supported); 344 fillIn("en", "XA", NULL, NULL, &requested); 345 // en-XA is a pseudo-locale, and English resources are not a match for it. 346 EXPECT_FALSE(supported.match(requested)); 347 348 fillIn("en", "XA", NULL, NULL, &supported); 349 fillIn("en", NULL, NULL, NULL, &requested); 350 // en-XA is a pseudo-locale, and its resources don't support English locales. 351 EXPECT_FALSE(supported.match(requested)); 352 353 fillIn("en", "XA", NULL, NULL, &supported); 354 fillIn("en", "XA", NULL, NULL, &requested); 355 // Even if they are pseudo-locales, exactly equal locales match. 356 EXPECT_TRUE(supported.match(requested)); 357 358 fillIn("ar", NULL, NULL, NULL, &supported); 359 fillIn("ar", "XB", NULL, NULL, &requested); 360 // ar-XB is a pseudo-locale, and Arabic resources are not a match for it. 361 EXPECT_FALSE(supported.match(requested)); 362 363 fillIn("ar", "XB", NULL, NULL, &supported); 364 fillIn("ar", NULL, NULL, NULL, &requested); 365 // ar-XB is a pseudo-locale, and its resources don't support Arabic locales. 366 EXPECT_FALSE(supported.match(requested)); 367 368 fillIn("ar", "XB", NULL, NULL, &supported); 369 fillIn("ar", "XB", NULL, NULL, &requested); 370 // Even if they are pseudo-locales, exactly equal locales match. 371 EXPECT_TRUE(supported.match(requested)); 372} 373 374TEST(ConfigLocaleTest, match_emptyScript) { 375 ResTable_config supported, requested; 376 377 fillIn("fr", "FR", NULL, NULL, &supported); 378 fillIn("fr", "CA", NULL, NULL, &requested); 379 380 // emulate packages built with older AAPT 381 memset(supported.localeScript, '\0', 4); 382 supported.localeScriptWasComputed = false; 383 384 EXPECT_TRUE(supported.match(requested)); 385} 386 387TEST(ConfigLocaleTest, isLocaleBetterThan_basics) { 388 ResTable_config config1, config2, request; 389 390 fillIn(NULL, NULL, NULL, NULL, &request); 391 fillIn("fr", "FR", NULL, NULL, &config1); 392 fillIn("fr", "CA", NULL, NULL, &config2); 393 EXPECT_FALSE(config1.isLocaleBetterThan(config2, &request)); 394 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 395 396 fillIn("fr", "CA", NULL, NULL, &request); 397 fillIn(NULL, NULL, NULL, NULL, &config1); 398 fillIn(NULL, NULL, NULL, NULL, &config2); 399 EXPECT_FALSE(config1.isLocaleBetterThan(config2, &request)); 400 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 401 402 fillIn("fr", "CA", NULL, NULL, &request); 403 fillIn("fr", "FR", NULL, NULL, &config1); 404 fillIn(NULL, NULL, NULL, NULL, &config2); 405 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 406 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 407 408 fillIn("de", "DE", NULL, NULL, &request); 409 fillIn("de", "DE", NULL, "1901", &config1); 410 fillIn("de", "DE", NULL, "1996", &config2); 411 EXPECT_FALSE(config1.isLocaleBetterThan(config2, &request)); 412 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 413 414 fillIn("de", "DE", NULL, "1901", &request); 415 fillIn("de", "DE", NULL, "1901", &config1); 416 fillIn("de", "DE", NULL, NULL, &config2); 417 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 418 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 419 420 fillIn("de", "DE", NULL, "1901", &request); 421 fillIn("de", "DE", NULL, "1996", &config1); 422 fillIn("de", "DE", NULL, NULL, &config2); 423 EXPECT_FALSE(config1.isLocaleBetterThan(config2, &request)); 424 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 425} 426 427TEST(ConfigLocaleTest, isLocaleBetterThan_regionComparison) { 428 ResTable_config config1, config2, request; 429 430 fillIn("es", "AR", NULL, NULL, &request); 431 fillIn("es", "419", NULL, NULL, &config1); 432 fillIn("es", "419", NULL, NULL, &config2); 433 // Both supported locales are the same, so none is better than the other. 434 EXPECT_FALSE(config1.isLocaleBetterThan(config2, &request)); 435 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 436 437 fillIn("es", "AR", NULL, NULL, &request); 438 fillIn("es", "AR", NULL, NULL, &config1); 439 fillIn("es", "419", NULL, NULL, &config2); 440 // An exact locale match is better than a parent. 441 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 442 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 443 444 fillIn("es", "AR", NULL, NULL, &request); 445 fillIn("es", "419", NULL, NULL, &config1); 446 fillIn("es", NULL, NULL, NULL, &config2); 447 // A closer parent is better. 448 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 449 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 450 451 fillIn("es", "AR", NULL, NULL, &request); 452 fillIn("es", "419", NULL, NULL, &config1); 453 fillIn("es", "ES", NULL, NULL, &config2); 454 // A parent is better than a non-parent representative locale. 455 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 456 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 457 458 fillIn("es", "AR", NULL, NULL, &request); 459 fillIn("es", NULL, NULL, NULL, &config1); 460 fillIn("es", "ES", NULL, NULL, &config2); 461 // A parent is better than a non-parent representative locale. 462 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 463 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 464 465 fillIn("es", "AR", NULL, NULL, &request); 466 fillIn("es", "PE", NULL, NULL, &config1); 467 fillIn("es", "ES", NULL, NULL, &config2); 468 // A closer locale is better. 469 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 470 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 471 472 fillIn("es", "AR", NULL, NULL, &request); 473 fillIn("es", "MX", NULL, NULL, &config1); 474 fillIn("es", "BO", NULL, NULL, &config2); 475 // A representative locale is better if they are equidistant. 476 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 477 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 478 479 fillIn("es", "AR", NULL, NULL, &request); 480 fillIn("es", "US", NULL, NULL, &config1); 481 fillIn("es", "BO", NULL, NULL, &config2); 482 // A representative locale is better if they are equidistant. 483 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 484 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 485 486 fillIn("es", "AR", NULL, NULL, &request); 487 fillIn("es", "MX", NULL, NULL, &config1); 488 fillIn("es", "US", NULL, NULL, &config2); 489 // If all is equal, the locale earlier in the dictionary is better. 490 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 491 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 492 493 fillIn("es", "GQ", NULL, NULL, &request); 494 fillIn("es", "IC", NULL, NULL, &config1); 495 fillIn("es", "419", NULL, NULL, &config2); 496 // If all is equal, the locale earlier in the dictionary is better and 497 // letters are better than numbers. 498 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 499 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 500 501 fillIn("en", "GB", NULL, NULL, &request); 502 fillIn("en", "001", NULL, NULL, &config1); 503 fillIn("en", NULL, NULL, NULL, &config2); 504 // A closer parent is better. 505 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 506 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 507 508 fillIn("en", "PR", NULL, NULL, &request); 509 fillIn("en", NULL, NULL, NULL, &config1); 510 fillIn("en", "001", NULL, NULL, &config2); 511 // A parent is better than a non-parent. 512 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 513 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 514 515 fillIn("en", "DE", NULL, NULL, &request); 516 fillIn("en", "150", NULL, NULL, &config1); 517 fillIn("en", "001", NULL, NULL, &config2); 518 // A closer parent is better. 519 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 520 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 521 522 fillIn("en", "IN", NULL, NULL, &request); 523 fillIn("en", "AU", NULL, NULL, &config1); 524 fillIn("en", "US", NULL, NULL, &config2); 525 // A closer locale is better. 526 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 527 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 528 529 fillIn("en", "PR", NULL, NULL, &request); 530 fillIn("en", "001", NULL, NULL, &config1); 531 fillIn("en", "GB", NULL, NULL, &config2); 532 // A closer locale is better. 533 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 534 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 535 536 fillIn("en", "IN", NULL, NULL, &request); 537 fillIn("en", "GB", NULL, NULL, &config1); 538 fillIn("en", "AU", NULL, NULL, &config2); 539 // A representative locale is better if they are equidistant. 540 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 541 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 542 543 fillIn("en", "IN", NULL, NULL, &request); 544 fillIn("en", "AU", NULL, NULL, &config1); 545 fillIn("en", "CA", NULL, NULL, &config2); 546 // If all is equal, the locale earlier in the dictionary is better. 547 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 548 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 549 550 fillIn("pt", "MZ", NULL, NULL, &request); 551 fillIn("pt", "PT", NULL, NULL, &config1); 552 fillIn("pt", NULL, NULL, NULL, &config2); 553 // A closer parent is better. 554 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 555 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 556 557 fillIn("pt", "MZ", NULL, NULL, &request); 558 fillIn("pt", "PT", NULL, NULL, &config1); 559 fillIn("pt", "BR", NULL, NULL, &config2); 560 // A parent is better than a non-parent. 561 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 562 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 563 564 fillIn("zh", "MO", "Hant", NULL, &request); 565 fillIn("zh", "HK", "Hant", NULL, &config1); 566 fillIn("zh", "TW", "Hant", NULL, &config2); 567 // A parent is better than a non-parent. 568 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 569 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 570 571 fillIn("zh", "US", "Hant", NULL, &request); 572 fillIn("zh", "TW", "Hant", NULL, &config1); 573 fillIn("zh", "HK", "Hant", NULL, &config2); 574 // A representative locale is better if they are equidistant. 575 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 576 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 577 578 fillIn("ar", "DZ", NULL, NULL, &request); 579 fillIn("ar", "015", NULL, NULL, &config1); 580 fillIn("ar", NULL, NULL, NULL, &config2); 581 // A closer parent is better. 582 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 583 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 584 585 fillIn("ar", "EG", NULL, NULL, &request); 586 fillIn("ar", NULL, NULL, NULL, &config1); 587 fillIn("ar", "015", NULL, NULL, &config2); 588 // A parent is better than a non-parent. 589 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 590 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 591 592 fillIn("ar", "QA", NULL, NULL, &request); 593 fillIn("ar", "EG", NULL, NULL, &config1); 594 fillIn("ar", "BH", NULL, NULL, &config2); 595 // A representative locale is better if they are equidistant. 596 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 597 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 598 599 fillIn("ar", "QA", NULL, NULL, &request); 600 fillIn("ar", "SA", NULL, NULL, &config1); 601 fillIn("ar", "015", NULL, NULL, &config2); 602 // If all is equal, the locale earlier in the dictionary is better and 603 // letters are better than numbers. 604 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 605 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 606} 607 608// Default resources are considered better matches for US English 609// and US-like English locales than International English locales 610TEST(ConfigLocaleTest, isLocaleBetterThan_UsEnglishIsSpecial) { 611 ResTable_config config1, config2, request; 612 613 fillIn("en", "US", NULL, NULL, &request); 614 fillIn(NULL, NULL, NULL, NULL, &config1); 615 fillIn("en", "001", NULL, NULL, &config2); 616 // default is better than International English 617 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 618 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 619 620 fillIn("en", "US", NULL, NULL, &request); 621 fillIn(NULL, NULL, NULL, NULL, &config1); 622 fillIn("en", "GB", NULL, NULL, &config2); 623 // default is better than British English 624 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 625 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 626 627 fillIn("en", "PR", NULL, NULL, &request); 628 fillIn(NULL, NULL, NULL, NULL, &config1); 629 fillIn("en", "001", NULL, NULL, &config2); 630 // Even for Puerto Rico, default is better than International English 631 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 632 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 633 634 fillIn("en", "US", NULL, NULL, &request); 635 fillIn("en", NULL, NULL, NULL, &config1); 636 fillIn(NULL, NULL, NULL, NULL, &config2); 637 // "English" is better than default, since it's a parent of US English 638 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 639 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 640 641 fillIn("en", "PR", NULL, NULL, &request); 642 fillIn("en", NULL, NULL, NULL, &config1); 643 fillIn(NULL, NULL, NULL, NULL, &config2); 644 // "English" is better than default, since it's a parent of Puerto Rico English 645 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 646 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 647 648 fillIn("en", "US", NULL, NULL, &request); 649 fillIn(NULL, NULL, NULL, NULL, &config1); 650 fillIn("en", "PR", NULL, NULL, &config2); 651 // For US English itself, we prefer default to its siblings in the parent tree 652 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 653 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 654} 655 656} // namespace android 657