1 /* 2 * Copyright (C) 2015 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 package android.os.cts; 18 19 import android.icu.util.ULocale; 20 import android.os.LocaleList; 21 import android.os.Parcel; 22 import android.test.AndroidTestCase; 23 24 import java.util.ArrayList; 25 import java.util.List; 26 import java.util.Locale; 27 28 public class LocaleListTest extends AndroidTestCase { 29 public void testEmptyLocaleList() { 30 LocaleList ll = new LocaleList(); 31 assertNotNull(ll); 32 assertTrue(ll.isEmpty()); 33 assertEquals(0, ll.size()); 34 assertNull(ll.get(0)); 35 assertNull(ll.get(1)); 36 assertNull(ll.get(10)); 37 38 ll = new LocaleList(new Locale[0]); 39 assertNotNull(ll); 40 assertTrue(ll.isEmpty()); 41 assertEquals(0, ll.size()); 42 assertNull(ll.get(0)); 43 assertNull(ll.get(1)); 44 assertNull(ll.get(10)); 45 } 46 47 public void testOneMemberLocaleList() { 48 final LocaleList ll = new LocaleList(Locale.US); 49 assertNotNull(ll); 50 assertFalse(ll.isEmpty()); 51 assertEquals(1, ll.size()); 52 assertEquals(Locale.US, ll.get(0)); 53 assertNull(ll.get(10)); 54 } 55 56 public void testTwoMemberLocaleList() { 57 final Locale enPH = Locale.forLanguageTag("en-PH"); 58 final Locale[] la = {enPH, Locale.US}; 59 final LocaleList ll = new LocaleList(la); 60 assertNotNull(ll); 61 assertFalse(ll.isEmpty()); 62 assertEquals(2, ll.size()); 63 assertEquals(enPH, ll.get(0)); 64 assertEquals(Locale.US, ll.get(1)); 65 assertNull(ll.get(10)); 66 } 67 68 public void testNullArgument() { 69 try { 70 LocaleList ll = new LocaleList((Locale) null); 71 fail("Initializing a LocaleList with a null argument should throw."); 72 } catch (Throwable e) { 73 assertEquals(NullPointerException.class, e.getClass()); 74 } 75 try { 76 LocaleList ll = new LocaleList((Locale[]) null); 77 fail("Initializing a LocaleList with a null array should throw."); 78 } catch (Throwable e) { 79 assertEquals(NullPointerException.class, e.getClass()); 80 } 81 } 82 83 public void testNullArguments() { 84 final Locale[] la = {Locale.US, null}; 85 LocaleList ll = null; 86 try { 87 ll = new LocaleList(la); 88 fail("Initializing a LocaleList with an array containing null should throw."); 89 } catch (Throwable e) { 90 assertEquals(NullPointerException.class, e.getClass()); 91 } 92 } 93 94 public void testRepeatedArguments() { 95 final Locale[] la = {Locale.US, Locale.US}; 96 LocaleList ll = null; 97 try { 98 ll = new LocaleList(la); 99 fail("Initializing a LocaleList with an array containing duplicates should throw."); 100 } catch (Throwable e) { 101 assertEquals(IllegalArgumentException.class, e.getClass()); 102 } 103 } 104 105 public void testIndexOf() { 106 final LocaleList empty = new LocaleList(); 107 assertEquals(-1, empty.indexOf(Locale.US)); 108 109 final LocaleList oneMember = new LocaleList(Locale.US); 110 assertEquals(0, oneMember.indexOf(Locale.US)); 111 assertEquals(-1, oneMember.indexOf(Locale.ENGLISH)); 112 113 final LocaleList twoMember = LocaleList.forLanguageTags("en,fr"); 114 assertEquals(0, twoMember.indexOf(Locale.forLanguageTag("en"))); 115 assertEquals(1, twoMember.indexOf(Locale.forLanguageTag("fr"))); 116 assertEquals(-1, twoMember.indexOf(Locale.forLanguageTag("en-US"))); 117 } 118 119 public void testEquals() { 120 final LocaleList empty = new LocaleList(); 121 final LocaleList anotherEmpty = new LocaleList(); 122 LocaleList oneMember = new LocaleList(Locale.US); 123 LocaleList sameOneMember = new LocaleList(new Locale("en", "US")); 124 LocaleList differentOneMember = new LocaleList(Locale.FRENCH); 125 Locale[] la = {Locale.US, Locale.FRENCH}; 126 LocaleList twoMember = new LocaleList(la); 127 128 assertFalse(empty.equals(null)); 129 assertFalse(oneMember.equals(null)); 130 131 assertFalse(empty.equals(new Object())); 132 133 assertTrue(empty.equals(empty)); 134 assertTrue(oneMember.equals(oneMember)); 135 136 assertFalse(empty.equals(oneMember)); 137 assertFalse(oneMember.equals(twoMember)); 138 139 assertFalse(oneMember.equals(differentOneMember)); 140 141 assertTrue(empty.equals(anotherEmpty)); 142 assertTrue(oneMember.equals(sameOneMember)); 143 } 144 145 public void testHashCode() { 146 final LocaleList empty = new LocaleList(); 147 final LocaleList anotherEmpty = new LocaleList(); 148 Locale[] la1 = {Locale.US}; 149 LocaleList oneMember = new LocaleList(la1); 150 LocaleList sameOneMember = new LocaleList(la1); 151 152 assertEquals(empty.hashCode(), anotherEmpty.hashCode()); 153 assertEquals(oneMember.hashCode(), sameOneMember.hashCode()); 154 } 155 156 public void testToString() { 157 LocaleList ll = new LocaleList(); 158 assertEquals("[]", ll.toString()); 159 160 final Locale[] la1 = {Locale.US}; 161 ll = new LocaleList(la1); 162 assertEquals("["+Locale.US.toString()+"]", ll.toString()); 163 164 final Locale[] la2 = {Locale.US, Locale.FRENCH}; 165 ll = new LocaleList(la2); 166 assertEquals("["+Locale.US.toString()+","+Locale.FRENCH.toString()+"]", ll.toString()); 167 } 168 169 public void testToLanguageTags() { 170 LocaleList ll = new LocaleList(); 171 assertEquals("", ll.toLanguageTags()); 172 173 final Locale[] la1 = {Locale.US}; 174 ll = new LocaleList(la1); 175 assertEquals(Locale.US.toLanguageTag(), ll.toLanguageTags()); 176 177 final Locale[] la2 = {Locale.US, Locale.FRENCH}; 178 ll = new LocaleList(la2); 179 assertEquals(Locale.US.toLanguageTag()+","+Locale.FRENCH.toLanguageTag(), 180 ll.toLanguageTags()); 181 } 182 183 public void testGetEmptyLocaleList() { 184 LocaleList empty = LocaleList.getEmptyLocaleList(); 185 LocaleList anotherEmpty = LocaleList.getEmptyLocaleList(); 186 LocaleList constructedEmpty = new LocaleList(); 187 188 assertEquals(constructedEmpty, empty); 189 assertSame(empty, anotherEmpty); 190 } 191 192 public void testForLanguageTags() { 193 assertEquals(LocaleList.getEmptyLocaleList(), LocaleList.forLanguageTags(null)); 194 assertEquals(LocaleList.getEmptyLocaleList(), LocaleList.forLanguageTags("")); 195 196 assertEquals(new LocaleList(Locale.forLanguageTag("en-US")), 197 LocaleList.forLanguageTags("en-US")); 198 199 final Locale[] la = {Locale.forLanguageTag("en-PH"), Locale.forLanguageTag("en-US")}; 200 assertEquals(new LocaleList(la), LocaleList.forLanguageTags("en-PH,en-US")); 201 } 202 203 public void testGetDefault() { 204 final LocaleList ll = LocaleList.getDefault(); 205 assertNotNull(ll); 206 assertTrue(ll.size() >= 1); 207 208 final Locale defaultLocale = Locale.getDefault(); 209 assertTrue(ll.indexOf(defaultLocale) != -1); 210 } 211 212 public void testGetAdjustedDefault() { 213 final LocaleList ll = LocaleList.getDefault(); 214 assertNotNull(ll); 215 assertTrue(ll.size() >= 1); 216 217 final Locale defaultLocale = Locale.getDefault(); 218 assertTrue(ll.indexOf(defaultLocale) == 0); 219 } 220 221 public void testGetDefault_localeSetDefaultCalled() { 222 final Locale originalLocale = Locale.getDefault(); 223 final LocaleList originalLocaleList = LocaleList.getDefault(); 224 225 LocaleList.setDefault(LocaleList.forLanguageTags("ae,en,ja")); 226 227 try { 228 Locale.setDefault(Locale.forLanguageTag("fr")); 229 assertEquals("fr,ae,en,ja", LocaleList.getDefault().toLanguageTags()); 230 assertEquals("fr,ae,en,ja", LocaleList.getAdjustedDefault().toLanguageTags()); 231 232 Locale.setDefault(Locale.forLanguageTag("de")); 233 assertEquals("de,ae,en,ja", LocaleList.getDefault().toLanguageTags()); 234 assertEquals("de,ae,en,ja", LocaleList.getAdjustedDefault().toLanguageTags()); 235 236 Locale.setDefault(Locale.forLanguageTag("en")); 237 assertEquals("en,ae,ja", LocaleList.getDefault().toLanguageTags()); 238 assertEquals("en,ae,ja", LocaleList.getAdjustedDefault().toLanguageTags()); 239 240 Locale.setDefault(Locale.forLanguageTag("es")); 241 assertEquals("es,ae,en,ja", LocaleList.getDefault().toLanguageTags()); 242 assertEquals("es,ae,en,ja", LocaleList.getAdjustedDefault().toLanguageTags()); 243 244 Locale.setDefault(Locale.forLanguageTag("ja")); 245 assertEquals("ja,ae,en", LocaleList.getDefault().toLanguageTags()); 246 assertEquals("ja,ae,en", LocaleList.getAdjustedDefault().toLanguageTags()); 247 248 Locale.setDefault(Locale.forLanguageTag("ae")); 249 assertEquals("ae,en,ja", LocaleList.getDefault().toLanguageTags()); 250 assertEquals("ae,en,ja", LocaleList.getAdjustedDefault().toLanguageTags()); 251 } finally { 252 // restore the original values 253 resetDefaultLocaleList(originalLocale, originalLocaleList); 254 } 255 } 256 257 public void testSetDefault_null() { 258 try { 259 LocaleList.setDefault(null); 260 fail("Setting the default locale list to null should throw."); 261 } catch (Throwable e) { 262 assertEquals(NullPointerException.class, e.getClass()); 263 } 264 } 265 266 public void testSetDefault_empty() { 267 try { 268 LocaleList.setDefault(LocaleList.getEmptyLocaleList()); 269 fail("Setting the default locale list to an empty list should throw."); 270 } catch (Throwable e) { 271 assertEquals(IllegalArgumentException.class, e.getClass()); 272 } 273 } 274 275 public void testSetDefault_oneLocale() { 276 final Locale originalLocale = Locale.getDefault(); 277 final LocaleList originalLocaleList = LocaleList.getDefault(); 278 279 final LocaleList locales = LocaleList.forLanguageTags("ae"); 280 LocaleList.setDefault(locales); 281 try { 282 assertEquals("ae", Locale.getDefault().toLanguageTag()); 283 assertEquals(locales, LocaleList.getDefault()); 284 assertEquals(locales, LocaleList.getAdjustedDefault()); 285 } finally { 286 // restore the original values 287 resetDefaultLocaleList(originalLocale, originalLocaleList); 288 } 289 } 290 291 public void testSetDefault_twoLocales() { 292 final Locale originalLocale = Locale.getDefault(); 293 final LocaleList originalLocaleList = LocaleList.getDefault(); 294 295 final LocaleList locales = LocaleList.forLanguageTags("ae,en"); 296 LocaleList.setDefault(locales); 297 try { 298 assertEquals("ae", Locale.getDefault().toLanguageTag()); 299 assertEquals(locales, LocaleList.getDefault()); 300 assertEquals(locales, LocaleList.getAdjustedDefault()); 301 } finally { 302 // restore the original values 303 resetDefaultLocaleList(originalLocale, originalLocaleList); 304 } 305 } 306 307 public void testParcelable() { 308 // Make sure an empty LocaleList can be marshalled/unmarshalled via Parcel. 309 assertEquals(LocaleList.getEmptyLocaleList(), 310 cloneViaParcel(LocaleList.getEmptyLocaleList())); 311 312 // Make sure a non-empty LocaleList can be marshalled/unmarshalled via Parcel. 313 LocaleList original = LocaleList.forLanguageTags("en-PH,en-US"); 314 assertEquals(original, cloneViaParcel(original)); 315 } 316 317 public void testDescribeContents_doesNotThrowException() { 318 // Just check calling describeContents() should not cause any exceptions. 319 LocaleList.forLanguageTags("en").describeContents(); 320 LocaleList.forLanguageTags("").describeContents(); 321 LocaleList.forLanguageTags(null).describeContents(); 322 LocaleList.getEmptyLocaleList().describeContents(); 323 } 324 325 private static void resetDefaultLocaleList(Locale topLocale, LocaleList localeList) { 326 final List<Locale> newLocales = new ArrayList<>(); 327 328 if (topLocale != null) { 329 newLocales.add(topLocale); 330 } 331 332 if (localeList != null) { 333 for (int index = 0; index < localeList.size(); index++) { 334 final Locale locale = localeList.get(index); 335 if (topLocale != null && !topLocale.equals(locale)) { 336 newLocales.add(locale); 337 } 338 } 339 } 340 341 final LocaleList result = new LocaleList(newLocales.toArray(new Locale[newLocales.size()])); 342 LocaleList.setDefault(result); 343 } 344 345 private static LocaleList cloneViaParcel(final LocaleList original) { 346 Parcel parcel = null; 347 try { 348 parcel = Parcel.obtain(); 349 original.writeToParcel(parcel, 0); 350 parcel.setDataPosition(0); 351 return LocaleList.CREATOR.createFromParcel(parcel); 352 } finally { 353 if (parcel != null) { 354 parcel.recycle(); 355 } 356 } 357 } 358 359 public void testGetFirstMatch_noAssets() { 360 String[] noAssets = {}; 361 assertNull(LocaleList.getEmptyLocaleList().getFirstMatch(noAssets)); 362 assertEquals( 363 Locale.forLanguageTag("fr-BE"), 364 LocaleList.forLanguageTags("fr-BE").getFirstMatch(noAssets)); 365 assertEquals( 366 Locale.forLanguageTag("fr-BE"), 367 LocaleList.forLanguageTags("fr-BE,nl-BE").getFirstMatch(noAssets)); 368 } 369 370 public void testGetFirstMatch_oneAsset() { 371 String[] oneDutchAsset = {"nl"}; 372 assertNull(LocaleList.getEmptyLocaleList().getFirstMatch(oneDutchAsset)); 373 assertEquals( 374 Locale.forLanguageTag("fr-BE"), 375 LocaleList.forLanguageTags("fr-BE").getFirstMatch(oneDutchAsset)); 376 assertEquals( 377 Locale.forLanguageTag("nl-BE"), 378 LocaleList.forLanguageTags("nl-BE").getFirstMatch(oneDutchAsset)); 379 assertEquals( 380 Locale.forLanguageTag("nl-BE"), 381 LocaleList.forLanguageTags("fr-BE,nl-BE").getFirstMatch(oneDutchAsset)); 382 assertEquals( 383 Locale.forLanguageTag("nl-BE"), 384 LocaleList.forLanguageTags("nl-BE,fr-BE").getFirstMatch(oneDutchAsset)); 385 } 386 387 public void testGetFirstMatch_twoAssets() { 388 String[] FrenchAndDutchAssets = {"fr", "nl"}; 389 assertNull(LocaleList.getEmptyLocaleList().getFirstMatch(FrenchAndDutchAssets)); 390 assertEquals( 391 Locale.forLanguageTag("fr-BE"), 392 LocaleList.forLanguageTags("fr-BE").getFirstMatch(FrenchAndDutchAssets)); 393 assertEquals( 394 Locale.forLanguageTag("nl-BE"), 395 LocaleList.forLanguageTags("nl-BE").getFirstMatch(FrenchAndDutchAssets)); 396 assertEquals( 397 Locale.forLanguageTag("fr-BE"), 398 LocaleList.forLanguageTags("fr-BE,nl-BE").getFirstMatch(FrenchAndDutchAssets)); 399 assertEquals( 400 Locale.forLanguageTag("nl-BE"), 401 LocaleList.forLanguageTags("nl-BE,fr-BE").getFirstMatch(FrenchAndDutchAssets)); 402 } 403 404 public void testGetFirstMatch_oneChineseAsset() { 405 String[] oneChineseAsset = {"zh-CN"}; // Assumed to mean zh-Hans-CN 406 // The following Chinese examples would all match, so they will be chosen. 407 assertEquals( 408 Locale.forLanguageTag("zh"), 409 LocaleList.forLanguageTags("ko-KR,zh").getFirstMatch(oneChineseAsset)); 410 assertEquals( 411 Locale.forLanguageTag("zh-CN"), 412 LocaleList.forLanguageTags("ko-KR,zh-CN").getFirstMatch(oneChineseAsset)); 413 assertEquals( 414 Locale.forLanguageTag("zh-Hans"), 415 LocaleList.forLanguageTags("ko-KR,zh-Hans").getFirstMatch(oneChineseAsset)); 416 assertEquals( 417 Locale.forLanguageTag("zh-Hans-CN"), 418 LocaleList.forLanguageTags("ko-KR,zh-Hans-CN").getFirstMatch(oneChineseAsset)); 419 assertEquals( 420 Locale.forLanguageTag("zh-Hans-HK"), 421 LocaleList.forLanguageTags("ko-KR,zh-Hans-HK").getFirstMatch(oneChineseAsset)); 422 423 // The following Chinese examples wouldn't match, so the first locale will be chosen 424 // instead. 425 assertEquals( 426 Locale.forLanguageTag("ko-KR"), 427 LocaleList.forLanguageTags("ko-KR,zh-TW").getFirstMatch(oneChineseAsset)); 428 assertEquals( 429 Locale.forLanguageTag("ko-KR"), 430 LocaleList.forLanguageTags("ko-KR,zh-Hant").getFirstMatch(oneChineseAsset)); 431 assertEquals( 432 Locale.forLanguageTag("ko-KR"), 433 LocaleList.forLanguageTags("ko-KR,zh-Hant-TW").getFirstMatch(oneChineseAsset)); 434 } 435 436 public void testGetFirstMatch_serbianCyrillic() { 437 String[] oneSerbianAsset = {"sr"}; // Assumed to mean sr-Cyrl-RS 438 // The following Serbian examples would all match, so they will be chosen. 439 assertEquals( 440 Locale.forLanguageTag("sr"), 441 LocaleList.forLanguageTags("hr-HR,sr").getFirstMatch(oneSerbianAsset)); 442 assertEquals( 443 Locale.forLanguageTag("sr-RS"), 444 LocaleList.forLanguageTags("hr-HR,sr-RS").getFirstMatch(oneSerbianAsset)); 445 assertEquals( 446 Locale.forLanguageTag("sr-Cyrl"), 447 LocaleList.forLanguageTags("hr-HR,sr-Cyrl").getFirstMatch(oneSerbianAsset)); 448 assertEquals( 449 Locale.forLanguageTag("sr-Cyrl-RS"), 450 LocaleList.forLanguageTags("hr-HR,sr-Cyrl-RS").getFirstMatch(oneSerbianAsset)); 451 assertEquals( 452 Locale.forLanguageTag("sr-Cyrl-ME"), 453 LocaleList.forLanguageTags("hr-HR,sr-Cyrl-ME").getFirstMatch(oneSerbianAsset)); 454 455 // The following Serbian examples wouldn't match, so the first locale will be chosen 456 // instead. 457 assertEquals( 458 Locale.forLanguageTag("hr-HR"), 459 LocaleList.forLanguageTags("hr-HR,sr-ME").getFirstMatch(oneSerbianAsset)); 460 assertEquals( 461 Locale.forLanguageTag("hr-HR"), 462 LocaleList.forLanguageTags("hr-HR,sr-Latn").getFirstMatch(oneSerbianAsset)); 463 assertEquals( 464 Locale.forLanguageTag("hr-HR"), 465 LocaleList.forLanguageTags("hr-HR,sr-Latn-ME").getFirstMatch(oneSerbianAsset)); 466 } 467 468 public void testGetFirstMatch_LtrPseudoLocale() { 469 String[] onePseudoLocale = {"en-XA"}; 470 // "en-XA" matches itself 471 assertEquals( 472 Locale.forLanguageTag("en-XA"), 473 LocaleList.forLanguageTags("sr,en-XA").getFirstMatch(onePseudoLocale)); 474 475 // "en-XA" doesn't match "en" or "en-US" 476 assertEquals( 477 Locale.forLanguageTag("sr"), 478 LocaleList.forLanguageTags("sr,en").getFirstMatch(onePseudoLocale)); 479 assertEquals( 480 Locale.forLanguageTag("sr"), 481 LocaleList.forLanguageTags("sr,en-US").getFirstMatch(onePseudoLocale)); 482 } 483 484 public void testGetFirstMatch_RtlPseudoLocale() { 485 String[] onePseudoLocale = {"ar-XB"}; 486 // "ar-XB" matches itself 487 assertEquals( 488 Locale.forLanguageTag("ar-XB"), 489 LocaleList.forLanguageTags("sr,ar-XB").getFirstMatch(onePseudoLocale)); 490 491 // "ar-XB" doesn't match "ar" or "ar-EG" 492 assertEquals( 493 Locale.forLanguageTag("sr"), 494 LocaleList.forLanguageTags("sr,ar").getFirstMatch(onePseudoLocale)); 495 assertEquals( 496 Locale.forLanguageTag("sr"), 497 LocaleList.forLanguageTags("sr,ar-EG").getFirstMatch(onePseudoLocale)); 498 } 499 500 public void testGetFirstMatch_privateUseWithoutCountry() { 501 String[] onePrivateLocale = {"qaa"}; 502 // "qaa" supports itself and "qaa-CA" 503 assertEquals( 504 Locale.forLanguageTag("qaa"), 505 LocaleList.forLanguageTags("sr,qaa").getFirstMatch(onePrivateLocale)); 506 assertEquals( 507 Locale.forLanguageTag("qaa-CA"), 508 LocaleList.forLanguageTags("sr,qaa-CA").getFirstMatch(onePrivateLocale)); 509 } 510 511 public void testGetFirstMatch_privateUseWithCountry() { 512 String[] onePrivateLocale = {"qaa-US"}; 513 // "qaa-US" supports itself 514 assertEquals( 515 Locale.forLanguageTag("qaa-US"), 516 LocaleList.forLanguageTags("sr,qaa-US").getFirstMatch(onePrivateLocale)); 517 518 // "qaa-US" doesn't support "qaa" or "qaa-CA" 519 assertEquals( 520 Locale.forLanguageTag("sr"), 521 LocaleList.forLanguageTags("sr,qaa-CA").getFirstMatch(onePrivateLocale)); 522 assertEquals( 523 Locale.forLanguageTag("sr"), 524 LocaleList.forLanguageTags("sr,qaa").getFirstMatch(onePrivateLocale)); 525 } 526 527 public void testIsPseudoLocale() { 528 assertTrue(LocaleList.isPseudoLocale(ULocale.forLanguageTag("en-XA"))); 529 assertTrue(LocaleList.isPseudoLocale(ULocale.forLanguageTag("ar-XB"))); 530 assertFalse(LocaleList.isPseudoLocale(ULocale.forLanguageTag("en-US"))); 531 assertFalse(LocaleList.isPseudoLocale(ULocale.forLanguageTag("ar-AR"))); 532 assertFalse(LocaleList.isPseudoLocale(ULocale.forLanguageTag("fa-IR"))); 533 assertFalse(LocaleList.isPseudoLocale(ULocale.forLanguageTag("zh-CN"))); 534 assertFalse(LocaleList.isPseudoLocale(ULocale.forLanguageTag("fr-CA"))); 535 assertFalse(LocaleList.isPseudoLocale((ULocale) null)); 536 } 537 } 538