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, getBcp47Locale_canonicalize) { 283 ResTable_config config; 284 char out[RESTABLE_MAX_LOCALE_LEN]; 285 286 fillIn("tl", NULL, NULL, NULL, &config); 287 config.getBcp47Locale(out); 288 EXPECT_EQ(0, strcmp("tl", out)); 289 config.getBcp47Locale(out, true /* canonicalize */); 290 EXPECT_EQ(0, strcmp("fil", out)); 291 292 fillIn("tl", "PH", NULL, NULL, &config); 293 config.getBcp47Locale(out); 294 EXPECT_EQ(0, strcmp("tl-PH", out)); 295 config.getBcp47Locale(out, true /* canonicalize */); 296 EXPECT_EQ(0, strcmp("fil-PH", out)); 297} 298 299TEST(ConfigLocaleTest, match) { 300 ResTable_config supported, requested; 301 302 fillIn(NULL, NULL, NULL, NULL, &supported); 303 fillIn("fr", "CA", NULL, NULL, &requested); 304 // Empty locale matches everything (as a default). 305 EXPECT_TRUE(supported.match(requested)); 306 307 fillIn("en", "CA", NULL, NULL, &supported); 308 fillIn("fr", "CA", NULL, NULL, &requested); 309 // Different languages don't match. 310 EXPECT_FALSE(supported.match(requested)); 311 312 fillIn("tl", "PH", NULL, NULL, &supported); 313 fillIn("fil", "PH", NULL, NULL, &requested); 314 // Equivalent languages match. 315 EXPECT_TRUE(supported.match(requested)); 316 317 fillIn("qaa", "FR", NULL, NULL, &supported); 318 fillIn("qaa", "CA", NULL, NULL, &requested); 319 // If we can't infer the scripts, different regions don't match. 320 EXPECT_FALSE(supported.match(requested)); 321 322 fillIn("qaa", "FR", "Latn", NULL, &supported); 323 fillIn("qaa", "CA", NULL, NULL, &requested); 324 // If we can't infer any of the scripts, different regions don't match. 325 EXPECT_FALSE(supported.match(requested)); 326 327 fillIn("qaa", "FR", NULL, NULL, &supported); 328 fillIn("qaa", "CA", "Latn", NULL, &requested); 329 // If we can't infer any of the scripts, different regions don't match. 330 EXPECT_FALSE(supported.match(requested)); 331 332 fillIn("qaa", NULL, NULL, NULL, &supported); 333 fillIn("qaa", "CA", NULL, NULL, &requested); 334 // language-only resources still support language+region requests, even if we can't infer the 335 // script. 336 EXPECT_TRUE(supported.match(requested)); 337 338 fillIn("qaa", "CA", NULL, NULL, &supported); 339 fillIn("qaa", "CA", NULL, NULL, &requested); 340 // Even if we can't infer the scripts, exactly equal locales match. 341 EXPECT_TRUE(supported.match(requested)); 342 343 fillIn("az", NULL, NULL, NULL, &supported); 344 fillIn("az", NULL, "Latn", NULL, &requested); 345 // If the resolved scripts are the same, it doesn't matter if they were explicitly provided 346 // or not, and they match. 347 EXPECT_TRUE(supported.match(requested)); 348 349 fillIn("az", NULL, NULL, NULL, &supported); 350 fillIn("az", NULL, "Cyrl", NULL, &requested); 351 // If the resolved scripts are different, they don't match. 352 EXPECT_FALSE(supported.match(requested)); 353 354 fillIn("az", NULL, NULL, NULL, &supported); 355 fillIn("az", "IR", NULL, NULL, &requested); 356 // If the resolved scripts are different, they don't match. 357 EXPECT_FALSE(supported.match(requested)); 358 359 fillIn("az", "IR", NULL, NULL, &supported); 360 fillIn("az", NULL, "Arab", NULL, &requested); 361 // If the resolved scripts are the same, it doesn't matter if they were explicitly provided 362 // or not, and they match. 363 EXPECT_TRUE(supported.match(requested)); 364 365 fillIn("en", NULL, NULL, NULL, &supported); 366 fillIn("en", "XA", NULL, NULL, &requested); 367 // en-XA is a pseudo-locale, and English resources are not a match for it. 368 EXPECT_FALSE(supported.match(requested)); 369 370 fillIn("en", "XA", NULL, NULL, &supported); 371 fillIn("en", NULL, NULL, NULL, &requested); 372 // en-XA is a pseudo-locale, and its resources don't support English locales. 373 EXPECT_FALSE(supported.match(requested)); 374 375 fillIn("en", "XA", NULL, NULL, &supported); 376 fillIn("en", "XA", NULL, NULL, &requested); 377 // Even if they are pseudo-locales, exactly equal locales match. 378 EXPECT_TRUE(supported.match(requested)); 379 380 fillIn("ar", NULL, NULL, NULL, &supported); 381 fillIn("ar", "XB", NULL, NULL, &requested); 382 // ar-XB is a pseudo-locale, and Arabic resources are not a match for it. 383 EXPECT_FALSE(supported.match(requested)); 384 385 fillIn("ar", "XB", NULL, NULL, &supported); 386 fillIn("ar", NULL, NULL, NULL, &requested); 387 // ar-XB is a pseudo-locale, and its resources don't support Arabic locales. 388 EXPECT_FALSE(supported.match(requested)); 389 390 fillIn("ar", "XB", NULL, NULL, &supported); 391 fillIn("ar", "XB", NULL, NULL, &requested); 392 // Even if they are pseudo-locales, exactly equal locales match. 393 EXPECT_TRUE(supported.match(requested)); 394} 395 396TEST(ConfigLocaleTest, match_emptyScript) { 397 ResTable_config supported, requested; 398 399 fillIn("fr", "FR", NULL, NULL, &supported); 400 fillIn("fr", "CA", NULL, NULL, &requested); 401 402 // emulate packages built with older AAPT 403 memset(supported.localeScript, '\0', 4); 404 supported.localeScriptWasComputed = false; 405 406 EXPECT_TRUE(supported.match(requested)); 407} 408 409TEST(ConfigLocaleTest, isLocaleBetterThan_basics) { 410 ResTable_config config1, config2, request; 411 412 fillIn(NULL, NULL, NULL, NULL, &request); 413 fillIn("fr", "FR", NULL, NULL, &config1); 414 fillIn("fr", "CA", NULL, NULL, &config2); 415 EXPECT_FALSE(config1.isLocaleBetterThan(config2, &request)); 416 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 417 418 fillIn("fr", "CA", NULL, NULL, &request); 419 fillIn(NULL, NULL, NULL, NULL, &config1); 420 fillIn(NULL, NULL, NULL, NULL, &config2); 421 EXPECT_FALSE(config1.isLocaleBetterThan(config2, &request)); 422 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 423 424 fillIn("fr", "CA", NULL, NULL, &request); 425 fillIn("fr", "FR", NULL, NULL, &config1); 426 fillIn(NULL, NULL, NULL, NULL, &config2); 427 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 428 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 429 430 fillIn("de", "DE", NULL, NULL, &request); 431 fillIn("de", "DE", NULL, NULL, &config1); 432 fillIn("de", "DE", NULL, "1901", &config2); 433 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 434 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 435 436 fillIn("de", "DE", NULL, NULL, &request); 437 fillIn("de", "DE", NULL, "1901", &config1); 438 fillIn("de", "DE", NULL, "1996", &config2); 439 EXPECT_FALSE(config1.isLocaleBetterThan(config2, &request)); 440 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 441 442 fillIn("de", "DE", NULL, "1901", &request); 443 fillIn("de", "DE", NULL, "1901", &config1); 444 fillIn("de", "DE", NULL, NULL, &config2); 445 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 446 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 447 448 fillIn("de", "DE", NULL, "1901", &request); 449 fillIn("de", "DE", NULL, "1996", &config1); 450 fillIn("de", "DE", NULL, NULL, &config2); 451 EXPECT_FALSE(config1.isLocaleBetterThan(config2, &request)); 452 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 453 454 fillIn("fil", "PH", NULL, NULL, &request); 455 fillIn("tl", "PH", NULL, NULL, &config1); 456 fillIn("fil", "US", NULL, NULL, &config2); 457 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 458 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 459 460 fillIn("fil", "PH", NULL, "fonipa", &request); 461 fillIn("tl", "PH", NULL, "fonipa", &config1); 462 fillIn("fil", "PH", NULL, NULL, &config2); 463 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 464 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 465 466 fillIn("fil", "PH", NULL, NULL, &request); 467 fillIn("fil", "PH", NULL, NULL, &config1); 468 fillIn("tl", "PH", NULL, NULL, &config2); 469 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 470 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 471} 472 473TEST(ConfigLocaleTest, isLocaleBetterThan_regionComparison) { 474 ResTable_config config1, config2, request; 475 476 fillIn("es", "AR", NULL, NULL, &request); 477 fillIn("es", "419", NULL, NULL, &config1); 478 fillIn("es", "419", NULL, NULL, &config2); 479 // Both supported locales are the same, so none is better than the other. 480 EXPECT_FALSE(config1.isLocaleBetterThan(config2, &request)); 481 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 482 483 fillIn("es", "AR", NULL, NULL, &request); 484 fillIn("es", "AR", NULL, NULL, &config1); 485 fillIn("es", "419", NULL, NULL, &config2); 486 // An exact locale match is better than a parent. 487 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 488 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 489 490 fillIn("es", "AR", NULL, NULL, &request); 491 fillIn("es", "419", NULL, NULL, &config1); 492 fillIn("es", NULL, NULL, NULL, &config2); 493 // A closer parent is better. 494 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 495 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 496 497 fillIn("es", "AR", NULL, NULL, &request); 498 fillIn("es", "419", NULL, NULL, &config1); 499 fillIn("es", "ES", NULL, NULL, &config2); 500 // A parent is better than a non-parent representative locale. 501 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 502 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 503 504 fillIn("es", "AR", NULL, NULL, &request); 505 fillIn("es", NULL, NULL, NULL, &config1); 506 fillIn("es", "ES", NULL, NULL, &config2); 507 // A parent is better than a non-parent representative locale. 508 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 509 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 510 511 fillIn("es", "AR", NULL, NULL, &request); 512 fillIn("es", "PE", NULL, NULL, &config1); 513 fillIn("es", "ES", NULL, NULL, &config2); 514 // A closer locale is better. 515 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 516 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 517 518 fillIn("es", "AR", NULL, NULL, &request); 519 fillIn("es", "US", NULL, NULL, &config1); 520 fillIn("es", NULL, NULL, NULL, &config2); 521 // Special case for Latin American Spanish: es-MX and es-US are 522 // pseudo-parents of all Latin Ameircan Spanish locales. 523 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 524 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 525 526 fillIn("es", "MX", NULL, NULL, &request); 527 fillIn("es", "US", NULL, NULL, &config1); 528 fillIn("es", NULL, NULL, NULL, &config2); 529 // Special case for Latin American Spanish: es-MX and es-US are 530 // pseudo-parents of all Latin Ameircan Spanish locales. 531 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 532 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 533 534 fillIn("es", "AR", NULL, NULL, &request); 535 fillIn("es", "MX", NULL, NULL, &config1); 536 fillIn("es", NULL, NULL, NULL, &config2); 537 // Special case for Latin American Spanish: es-MX and es-US are 538 // pseudo-parents of all Latin Ameircan Spanish locales. 539 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 540 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 541 542 fillIn("es", "US", NULL, NULL, &request); 543 fillIn("es", "MX", NULL, NULL, &config1); 544 fillIn("es", NULL, NULL, NULL, &config2); 545 // Special case for Latin American Spanish: es-MX and es-US are 546 // pseudo-parents of all Latin Ameircan Spanish locales. 547 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 548 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 549 550 fillIn("es", "AR", NULL, NULL, &request); 551 fillIn("es", "419", NULL, NULL, &config1); 552 fillIn("es", "MX", NULL, NULL, &config2); 553 // Even though es-MX and es-US are pseudo-parents of all Latin Ameircan 554 // Spanish locales, es-419 is a closer parent. 555 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 556 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 557 558 fillIn("es", "US", NULL, NULL, &request); 559 fillIn("es", "419", NULL, NULL, &config1); 560 fillIn("es", "MX", NULL, NULL, &config2); 561 // Even though es-MX and es-US are pseudo-parents of all Latin Ameircan 562 // Spanish locales, es-419 is a closer parent. 563 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 564 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 565 566 fillIn("es", "MX", NULL, NULL, &request); 567 fillIn("es", "419", NULL, NULL, &config1); 568 fillIn("es", "US", NULL, NULL, &config2); 569 // Even though es-MX and es-US are pseudo-parents of all Latin Ameircan 570 // Spanish locales, es-419 is a closer parent. 571 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 572 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 573 574 fillIn("es", "AR", NULL, NULL, &request); 575 fillIn("es", "MX", NULL, NULL, &config1); 576 fillIn("es", "BO", NULL, NULL, &config2); 577 // Special case for Latin American Spanish: es-MX and es-US are 578 // pseudo-parents of all Latin Ameircan Spanish locales. 579 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 580 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 581 582 fillIn("es", "AR", NULL, NULL, &request); 583 fillIn("es", "US", NULL, NULL, &config1); 584 fillIn("es", "BO", NULL, NULL, &config2); 585 // Special case for Latin American Spanish: es-MX and es-US are 586 // pseudo-parents of all Latin Ameircan Spanish locales. 587 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 588 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 589 590 fillIn("es", "IC", NULL, NULL, &request); 591 fillIn("es", "ES", NULL, NULL, &config1); 592 fillIn("es", "GQ", NULL, NULL, &config2); 593 // A representative locale is better if they are equidistant. 594 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 595 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 596 597 fillIn("es", "AR", NULL, NULL, &request); 598 fillIn("es", "MX", NULL, NULL, &config1); 599 fillIn("es", "US", NULL, NULL, &config2); 600 // If all is equal, the locale earlier in the dictionary is better. 601 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 602 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 603 604 fillIn("es", "GQ", NULL, NULL, &request); 605 fillIn("es", "IC", NULL, NULL, &config1); 606 fillIn("es", "419", NULL, NULL, &config2); 607 // If all is equal, the locale earlier in the dictionary is better and 608 // letters are better than numbers. 609 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 610 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 611 612 fillIn("en", "GB", NULL, NULL, &request); 613 fillIn("en", "001", NULL, NULL, &config1); 614 fillIn("en", NULL, NULL, NULL, &config2); 615 // A closer parent is better. 616 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 617 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 618 619 fillIn("en", "PR", NULL, NULL, &request); 620 fillIn("en", NULL, NULL, NULL, &config1); 621 fillIn("en", "001", NULL, NULL, &config2); 622 // A parent is better than a non-parent. 623 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 624 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 625 626 fillIn("en", "DE", NULL, NULL, &request); 627 fillIn("en", "150", NULL, NULL, &config1); 628 fillIn("en", "001", NULL, NULL, &config2); 629 // A closer parent is better. 630 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 631 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 632 633 fillIn("en", "IN", NULL, NULL, &request); 634 fillIn("en", "AU", NULL, NULL, &config1); 635 fillIn("en", "US", NULL, NULL, &config2); 636 // A closer locale is better. 637 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 638 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 639 640 fillIn("en", "PR", NULL, NULL, &request); 641 fillIn("en", "001", NULL, NULL, &config1); 642 fillIn("en", "GB", NULL, NULL, &config2); 643 // A closer locale is better. 644 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 645 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 646 647 fillIn("en", "IN", NULL, NULL, &request); 648 fillIn("en", "GB", NULL, NULL, &config1); 649 fillIn("en", "AU", NULL, NULL, &config2); 650 // A representative locale is better if they are equidistant. 651 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 652 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 653 654 fillIn("en", "IN", NULL, NULL, &request); 655 fillIn("en", "AU", NULL, NULL, &config1); 656 fillIn("en", "CA", NULL, NULL, &config2); 657 // If all is equal, the locale earlier in the dictionary is better. 658 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 659 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 660 661 fillIn("pt", "MZ", NULL, NULL, &request); 662 fillIn("pt", "PT", NULL, NULL, &config1); 663 fillIn("pt", NULL, NULL, NULL, &config2); 664 // A closer parent is better. 665 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 666 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 667 668 fillIn("pt", "MZ", NULL, NULL, &request); 669 fillIn("pt", "PT", NULL, NULL, &config1); 670 fillIn("pt", "BR", NULL, NULL, &config2); 671 // A parent is better than a non-parent. 672 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 673 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 674 675 fillIn("zh", "MO", "Hant", NULL, &request); 676 fillIn("zh", "HK", "Hant", NULL, &config1); 677 fillIn("zh", "TW", "Hant", NULL, &config2); 678 // A parent is better than a non-parent. 679 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 680 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 681 682 fillIn("zh", "US", "Hant", NULL, &request); 683 fillIn("zh", "TW", "Hant", NULL, &config1); 684 fillIn("zh", "HK", "Hant", NULL, &config2); 685 // A representative locale is better if they are equidistant. 686 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 687 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 688 689 fillIn("ar", "DZ", NULL, NULL, &request); 690 fillIn("ar", "015", NULL, NULL, &config1); 691 fillIn("ar", NULL, NULL, NULL, &config2); 692 // A closer parent is better. 693 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 694 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 695 696 fillIn("ar", "EG", NULL, NULL, &request); 697 fillIn("ar", NULL, NULL, NULL, &config1); 698 fillIn("ar", "015", NULL, NULL, &config2); 699 // A parent is better than a non-parent. 700 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 701 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 702 703 fillIn("ar", "QA", NULL, NULL, &request); 704 fillIn("ar", "EG", NULL, NULL, &config1); 705 fillIn("ar", "BH", NULL, NULL, &config2); 706 // A representative locale is better if they are equidistant. 707 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 708 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 709 710 fillIn("ar", "QA", NULL, NULL, &request); 711 fillIn("ar", "SA", NULL, NULL, &config1); 712 fillIn("ar", "015", NULL, NULL, &config2); 713 // If all is equal, the locale earlier in the dictionary is better and 714 // letters are better than numbers. 715 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 716 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 717} 718 719// Default resources are considered better matches for US English 720// and US-like English locales than International English locales 721TEST(ConfigLocaleTest, isLocaleBetterThan_UsEnglishIsSpecial) { 722 ResTable_config config1, config2, request; 723 724 fillIn("en", "US", NULL, NULL, &request); 725 fillIn(NULL, NULL, NULL, NULL, &config1); 726 fillIn("en", "001", NULL, NULL, &config2); 727 // default is better than International English 728 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 729 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 730 731 fillIn("en", "US", NULL, NULL, &request); 732 fillIn(NULL, NULL, NULL, NULL, &config1); 733 fillIn("en", "GB", NULL, NULL, &config2); 734 // default is better than British English 735 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 736 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 737 738 fillIn("en", "PR", NULL, NULL, &request); 739 fillIn(NULL, NULL, NULL, NULL, &config1); 740 fillIn("en", "001", NULL, NULL, &config2); 741 // Even for Puerto Rico, default is better than International English 742 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 743 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 744 745 fillIn("en", "US", NULL, NULL, &request); 746 fillIn("en", NULL, NULL, NULL, &config1); 747 fillIn(NULL, NULL, NULL, NULL, &config2); 748 // "English" is better than default, since it's a parent of US English 749 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 750 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 751 752 fillIn("en", "PR", NULL, NULL, &request); 753 fillIn("en", NULL, NULL, NULL, &config1); 754 fillIn(NULL, NULL, NULL, NULL, &config2); 755 // "English" is better than default, since it's a parent of Puerto Rico English 756 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 757 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 758 759 fillIn("en", "US", NULL, NULL, &request); 760 fillIn(NULL, NULL, NULL, NULL, &config1); 761 fillIn("en", "PR", NULL, NULL, &config2); 762 // For US English itself, we prefer default to its siblings in the parent tree 763 EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request)); 764 EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request)); 765} 766 767} // namespace android 768