1 /* 2 * Copyright (C) 2016 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 com.android.internal.inputmethod; 18 19 import android.os.LocaleList; 20 import android.test.InstrumentationTestCase; 21 import android.test.suitebuilder.annotation.SmallTest; 22 23 import java.util.ArrayList; 24 import java.util.Locale; 25 26 public class LocaleUtilsTest extends InstrumentationTestCase { 27 28 private static final LocaleUtils.LocaleExtractor<Locale> sIdentityMapper = 29 new LocaleUtils.LocaleExtractor<Locale>() { 30 @Override 31 public Locale get(Locale source) { 32 return source; 33 } 34 }; 35 36 @SmallTest testFilterByLanguageEmptyLanguageList()37 public void testFilterByLanguageEmptyLanguageList() throws Exception { 38 final ArrayList<Locale> availableLocales = new ArrayList<>(); 39 availableLocales.add(Locale.forLanguageTag("en-US")); 40 availableLocales.add(Locale.forLanguageTag("fr-CA")); 41 availableLocales.add(Locale.forLanguageTag("in")); 42 availableLocales.add(Locale.forLanguageTag("ja")); 43 availableLocales.add(Locale.forLanguageTag("fil")); 44 45 final LocaleList preferredLocales = LocaleList.getEmptyLocaleList(); 46 47 final ArrayList<Locale> dest = new ArrayList<>(); 48 LocaleUtils.filterByLanguage(availableLocales, sIdentityMapper, preferredLocales, dest); 49 assertEquals(0, dest.size()); 50 } 51 52 @SmallTest testFilterDoesNotMatchAnything()53 public void testFilterDoesNotMatchAnything() throws Exception { 54 final ArrayList<Locale> availableLocales = new ArrayList<>(); 55 availableLocales.add(Locale.forLanguageTag("en-US")); 56 availableLocales.add(Locale.forLanguageTag("fr-CA")); 57 availableLocales.add(Locale.forLanguageTag("in")); 58 availableLocales.add(Locale.forLanguageTag("ja")); 59 availableLocales.add(Locale.forLanguageTag("fil")); 60 61 final LocaleList preferredLocales = LocaleList.forLanguageTags("zh-Hans-TW"); 62 63 final ArrayList<Locale> dest = new ArrayList<>(); 64 LocaleUtils.filterByLanguage(availableLocales, sIdentityMapper, preferredLocales, dest); 65 assertEquals(0, dest.size()); 66 } 67 68 @SmallTest testFilterByLanguageEmptySource()69 public void testFilterByLanguageEmptySource() throws Exception { 70 final ArrayList<Locale> availableLocales = new ArrayList<>(); 71 72 final LocaleList preferredLocales = LocaleList.forLanguageTags("fr,en-US,ja-JP"); 73 74 final ArrayList<Locale> dest = new ArrayList<>(); 75 LocaleUtils.filterByLanguage(availableLocales, sIdentityMapper, preferredLocales, dest); 76 assertEquals(0, dest.size()); 77 } 78 79 @SmallTest testFilterByLanguageNullAvailableLocales()80 public void testFilterByLanguageNullAvailableLocales() throws Exception { 81 { 82 final LocaleList preferredLocales = 83 LocaleList.forLanguageTags("en-AU,en-GB,en-US,en,en-IN"); 84 final ArrayList<Locale> availableLocales = new ArrayList<>(); 85 availableLocales.add(null); 86 final ArrayList<Locale> dest = new ArrayList<>(); 87 LocaleUtils.filterByLanguage(availableLocales, sIdentityMapper, preferredLocales, dest); 88 assertEquals(0, dest.size()); 89 } 90 { 91 final LocaleList preferredLocales = 92 LocaleList.forLanguageTags("en-AU,en-GB,en-US,en,en-IN"); 93 final ArrayList<Locale> availableLocales = new ArrayList<>(); 94 availableLocales.add(null); 95 availableLocales.add(null); 96 availableLocales.add(null); 97 final ArrayList<Locale> dest = new ArrayList<>(); 98 LocaleUtils.filterByLanguage(availableLocales, sIdentityMapper, preferredLocales, dest); 99 assertEquals(0, dest.size()); 100 } 101 { 102 final LocaleList preferredLocales = 103 LocaleList.forLanguageTags("en-AU,en-GB,en-US,en,en-IN"); 104 final ArrayList<Locale> availableLocales = new ArrayList<>(); 105 availableLocales.add(null); 106 availableLocales.add(Locale.forLanguageTag("en-US")); 107 availableLocales.add(null); 108 availableLocales.add(null); 109 final ArrayList<Locale> dest = new ArrayList<>(); 110 LocaleUtils.filterByLanguage(availableLocales, sIdentityMapper, preferredLocales, dest); 111 assertEquals(1, dest.size()); 112 assertEquals(availableLocales.get(1), dest.get(0)); // "en-US" 113 } 114 { 115 final LocaleList preferredLocales = 116 LocaleList.forLanguageTags("en-AU,en-GB,en-US,en,en-IN"); 117 final ArrayList<Locale> availableLocales = new ArrayList<>(); 118 availableLocales.add(null); 119 availableLocales.add(Locale.forLanguageTag("en")); 120 availableLocales.add(null); 121 availableLocales.add(null); 122 final ArrayList<Locale> dest = new ArrayList<>(); 123 LocaleUtils.filterByLanguage(availableLocales, sIdentityMapper, preferredLocales, dest); 124 assertEquals(1, dest.size()); 125 assertEquals(availableLocales.get(1), dest.get(0)); // "en" 126 } 127 { 128 final LocaleList preferredLocales = 129 LocaleList.forLanguageTags("en-AU,en-GB,en-US,en,en-IN"); 130 final ArrayList<Locale> availableLocales = new ArrayList<>(); 131 availableLocales.add(null); 132 availableLocales.add(Locale.forLanguageTag("ja-JP")); 133 availableLocales.add(null); 134 availableLocales.add(null); 135 final ArrayList<Locale> dest = new ArrayList<>(); 136 LocaleUtils.filterByLanguage(availableLocales, sIdentityMapper, preferredLocales, dest); 137 assertEquals(0, dest.size()); 138 } 139 } 140 141 @SmallTest testFilterByLanguage()142 public void testFilterByLanguage() throws Exception { 143 { 144 final ArrayList<Locale> availableLocales = new ArrayList<>(); 145 availableLocales.add(Locale.forLanguageTag("en-US")); 146 availableLocales.add(Locale.forLanguageTag("fr-CA")); 147 availableLocales.add(Locale.forLanguageTag("in")); 148 availableLocales.add(Locale.forLanguageTag("ja")); 149 availableLocales.add(Locale.forLanguageTag("fil")); 150 151 final LocaleList preferredLocales = LocaleList.forLanguageTags("fr,en-US,ja-JP"); 152 153 final ArrayList<Locale> dest = new ArrayList<>(); 154 LocaleUtils.filterByLanguage(availableLocales, sIdentityMapper, preferredLocales, dest); 155 assertEquals(3, dest.size()); 156 assertEquals(availableLocales.get(1), dest.get(0)); // "fr-CA" 157 assertEquals(availableLocales.get(0), dest.get(1)); // "en-US" 158 assertEquals(availableLocales.get(3), dest.get(2)); // "ja" 159 } 160 { 161 final ArrayList<Locale> availableLocales = new ArrayList<>(); 162 availableLocales.add(Locale.forLanguageTag("en-US")); 163 availableLocales.add(Locale.forLanguageTag("en-GB")); 164 availableLocales.add(Locale.forLanguageTag("en-IN")); 165 166 final LocaleList preferredLocales = LocaleList.forLanguageTags("en-US"); 167 168 final ArrayList<Locale> dest = new ArrayList<>(); 169 LocaleUtils.filterByLanguage(availableLocales, sIdentityMapper, preferredLocales, dest); 170 assertEquals(1, dest.size()); 171 assertEquals(availableLocales.get(0), dest.get(0)); // "en-US" 172 } 173 } 174 175 @SmallTest testFilterByLanguageTheSameLanguage()176 public void testFilterByLanguageTheSameLanguage() throws Exception { 177 { 178 final LocaleList preferredLocales = 179 LocaleList.forLanguageTags("en-AU,en-GB,en-US,en,en-IN"); 180 final ArrayList<Locale> availableLocales = new ArrayList<>(); 181 availableLocales.add(Locale.forLanguageTag("fr-CA")); 182 availableLocales.add(Locale.forLanguageTag("en-US")); 183 final ArrayList<Locale> dest = new ArrayList<>(); 184 LocaleUtils.filterByLanguage(availableLocales, sIdentityMapper, preferredLocales, dest); 185 assertEquals(1, dest.size()); 186 assertEquals(availableLocales.get(1), dest.get(0)); // "en-US" 187 } 188 { 189 final LocaleList preferredLocales = 190 LocaleList.forLanguageTags("en-AU,en-GB,en-US,en,en-IN"); 191 final ArrayList<Locale> availableLocales = new ArrayList<>(); 192 availableLocales.add(Locale.forLanguageTag("fr-CA")); 193 availableLocales.add(Locale.forLanguageTag("en")); 194 final ArrayList<Locale> dest = new ArrayList<>(); 195 LocaleUtils.filterByLanguage(availableLocales, sIdentityMapper, preferredLocales, dest); 196 assertEquals(1, dest.size()); 197 assertEquals(availableLocales.get(1), dest.get(0)); // "en" 198 } 199 { 200 final LocaleList preferredLocales = 201 LocaleList.forLanguageTags("en-AU,en-GB,en-US,en,en-IN"); 202 final ArrayList<Locale> availableLocales = new ArrayList<>(); 203 availableLocales.add(Locale.forLanguageTag("fr-CA")); 204 availableLocales.add(Locale.forLanguageTag("en-CA")); 205 availableLocales.add(Locale.forLanguageTag("en-IN")); 206 final ArrayList<Locale> dest = new ArrayList<>(); 207 LocaleUtils.filterByLanguage(availableLocales, sIdentityMapper, preferredLocales, dest); 208 assertEquals(1, dest.size()); 209 assertEquals(availableLocales.get(2), dest.get(0)); // "en-IN" 210 } 211 { 212 final LocaleList preferredLocales = 213 LocaleList.forLanguageTags("en-AU,en-GB,en-US,en-IN"); 214 final ArrayList<Locale> availableLocales = new ArrayList<>(); 215 availableLocales.add(Locale.forLanguageTag("fr-CA")); 216 availableLocales.add(Locale.forLanguageTag("en-CA")); 217 availableLocales.add(Locale.forLanguageTag("en-NZ")); 218 availableLocales.add(Locale.forLanguageTag("en-BZ")); 219 final ArrayList<Locale> dest = new ArrayList<>(); 220 LocaleUtils.filterByLanguage(availableLocales, sIdentityMapper, preferredLocales, dest); 221 assertEquals(1, dest.size()); 222 assertEquals(availableLocales.get(1), dest.get(0)); // "en-CA" 223 } 224 } 225 226 @SmallTest testFilterByLanguageFallbackRules()227 public void testFilterByLanguageFallbackRules() throws Exception { 228 { 229 final LocaleList preferredLocales = LocaleList.forLanguageTags("sr-Latn-RS"); 230 final ArrayList<Locale> availableLocales = new ArrayList<>(); 231 availableLocales.add(Locale.forLanguageTag("sr-Cyrl-BA")); 232 availableLocales.add(Locale.forLanguageTag("sr-Cyrl-CS")); 233 availableLocales.add(Locale.forLanguageTag("sr-Cyrl-ME")); 234 availableLocales.add(Locale.forLanguageTag("sr-Cyrl-RS")); 235 availableLocales.add(Locale.forLanguageTag("sr-Latn-BA")); 236 availableLocales.add(Locale.forLanguageTag("sr-Latn-CS")); 237 availableLocales.add(Locale.forLanguageTag("sr-Latn-ME")); 238 availableLocales.add(Locale.forLanguageTag("sr-Latn-RS")); 239 final ArrayList<Locale> dest = new ArrayList<>(); 240 LocaleUtils.filterByLanguage(availableLocales, sIdentityMapper, preferredLocales, dest); 241 assertEquals(1, dest.size()); 242 assertEquals(availableLocales.get(7), dest.get(0)); // "sr-Latn-RS" 243 } 244 { 245 final LocaleList preferredLocales = LocaleList.forLanguageTags("sr-Latn-RS-x-android"); 246 final ArrayList<Locale> availableLocales = new ArrayList<>(); 247 availableLocales.add(Locale.forLanguageTag("sr-Cyrl-BA")); 248 availableLocales.add(Locale.forLanguageTag("sr-Cyrl-CS")); 249 availableLocales.add(Locale.forLanguageTag("sr-Cyrl-ME")); 250 availableLocales.add(Locale.forLanguageTag("sr-Cyrl-RS")); 251 availableLocales.add(Locale.forLanguageTag("sr-Latn-BA")); 252 availableLocales.add(Locale.forLanguageTag("sr-Latn-CS")); 253 availableLocales.add(Locale.forLanguageTag("sr-Latn-ME")); 254 availableLocales.add(Locale.forLanguageTag("sr-Latn-RS")); 255 final ArrayList<Locale> dest = new ArrayList<>(); 256 LocaleUtils.filterByLanguage(availableLocales, sIdentityMapper, preferredLocales, dest); 257 assertEquals(1, dest.size()); 258 assertEquals(availableLocales.get(7), dest.get(0)); // "sr-Latn-RS" 259 } 260 { 261 final LocaleList preferredLocales = LocaleList.forLanguageTags("sr-Latn-RS"); 262 final ArrayList<Locale> availableLocales = new ArrayList<>(); 263 availableLocales.add(Locale.forLanguageTag("sr-Cyrl-BA-x-android")); 264 availableLocales.add(Locale.forLanguageTag("sr-Cyrl-CS-x-android")); 265 availableLocales.add(Locale.forLanguageTag("sr-Cyrl-ME-x-android")); 266 availableLocales.add(Locale.forLanguageTag("sr-Cyrl-RS-x-android")); 267 availableLocales.add(Locale.forLanguageTag("sr-Latn-BA-x-android")); 268 availableLocales.add(Locale.forLanguageTag("sr-Latn-CS-x-android")); 269 availableLocales.add(Locale.forLanguageTag("sr-Latn-ME-x-android")); 270 availableLocales.add(Locale.forLanguageTag("sr-Latn-RS-x-android")); 271 final ArrayList<Locale> dest = new ArrayList<>(); 272 LocaleUtils.filterByLanguage(availableLocales, sIdentityMapper, preferredLocales, dest); 273 assertEquals(1, dest.size()); 274 assertEquals(availableLocales.get(7), dest.get(0)); // "sr-Latn-RS-x-android" 275 } 276 277 { 278 final LocaleList preferredLocales = LocaleList.forLanguageTags("sr-Latn-RS"); 279 final ArrayList<Locale> availableLocales = new ArrayList<>(); 280 availableLocales.add(Locale.forLanguageTag("sr")); 281 availableLocales.add(Locale.forLanguageTag("sr-Cyrl")); 282 availableLocales.add(Locale.forLanguageTag("sr-Latn")); 283 final ArrayList<Locale> dest = new ArrayList<>(); 284 LocaleUtils.filterByLanguage(availableLocales, sIdentityMapper, preferredLocales, dest); 285 assertEquals(1, dest.size()); 286 assertEquals(availableLocales.get(2), dest.get(0)); // "sr-Latn" 287 } 288 289 { 290 final LocaleList preferredLocales = LocaleList.forLanguageTags("sr-RS"); 291 final ArrayList<Locale> availableLocales = new ArrayList<>(); 292 availableLocales.add(Locale.forLanguageTag("sr")); 293 availableLocales.add(Locale.forLanguageTag("sr-RS")); 294 availableLocales.add(Locale.forLanguageTag("sr-Latn")); 295 final ArrayList<Locale> dest = new ArrayList<>(); 296 LocaleUtils.filterByLanguage(availableLocales, sIdentityMapper, preferredLocales, dest); 297 assertEquals(1, dest.size()); 298 assertEquals(availableLocales.get(0), dest.get(0)); // "sr" 299 } 300 301 { 302 final LocaleList preferredLocales = LocaleList.forLanguageTags("sr-Latn"); 303 final ArrayList<Locale> availableLocales = new ArrayList<>(); 304 availableLocales.add(Locale.forLanguageTag("sr")); 305 availableLocales.add(Locale.forLanguageTag("sr-RS")); 306 availableLocales.add(Locale.forLanguageTag("sr-Latn")); 307 final ArrayList<Locale> dest = new ArrayList<>(); 308 LocaleUtils.filterByLanguage(availableLocales, sIdentityMapper, preferredLocales, dest); 309 assertEquals(1, dest.size()); 310 assertEquals(availableLocales.get(2), dest.get(0)); // "sr-Latn" 311 } 312 313 { 314 final LocaleList preferredLocales = LocaleList.forLanguageTags("sr"); 315 final ArrayList<Locale> availableLocales = new ArrayList<>(); 316 availableLocales.add(Locale.forLanguageTag("sr")); 317 availableLocales.add(Locale.forLanguageTag("sr-RS")); 318 availableLocales.add(Locale.forLanguageTag("sr-Latn")); 319 final ArrayList<Locale> dest = new ArrayList<>(); 320 LocaleUtils.filterByLanguage(availableLocales, sIdentityMapper, preferredLocales, dest); 321 assertEquals(1, dest.size()); 322 assertEquals(availableLocales.get(0), dest.get(0)); // "sr" 323 } 324 { 325 final LocaleList preferredLocales = LocaleList.forLanguageTags("sr"); 326 final ArrayList<Locale> availableLocales = new ArrayList<>(); 327 availableLocales.add(Locale.forLanguageTag("sr-Latn")); 328 availableLocales.add(Locale.forLanguageTag("sr-RS")); 329 availableLocales.add(Locale.forLanguageTag("sr")); 330 final ArrayList<Locale> dest = new ArrayList<>(); 331 LocaleUtils.filterByLanguage(availableLocales, sIdentityMapper, preferredLocales, dest); 332 assertEquals(1, dest.size()); 333 assertEquals(availableLocales.get(1), dest.get(0)); // "sr-RS" 334 } 335 336 { 337 final LocaleList preferredLocales = LocaleList.forLanguageTags("sr"); 338 final ArrayList<Locale> availableLocales = new ArrayList<>(); 339 availableLocales.add(Locale.forLanguageTag("sr-Cyrl-RS")); 340 availableLocales.add(Locale.forLanguageTag("sr-Latn-RS")); 341 final ArrayList<Locale> dest = new ArrayList<>(); 342 LocaleUtils.filterByLanguage(availableLocales, sIdentityMapper, preferredLocales, dest); 343 assertEquals(1, dest.size()); 344 assertEquals(availableLocales.get(0), dest.get(0)); // "sr-Cyrl-RS" 345 } 346 { 347 final LocaleList preferredLocales = LocaleList.forLanguageTags("sr-Latn"); 348 final ArrayList<Locale> availableLocales = new ArrayList<>(); 349 availableLocales.add(Locale.forLanguageTag("sr-Latn-RS")); 350 availableLocales.add(Locale.forLanguageTag("sr-Cyrl-RS")); 351 final ArrayList<Locale> dest = new ArrayList<>(); 352 LocaleUtils.filterByLanguage(availableLocales, sIdentityMapper, preferredLocales, dest); 353 assertEquals(1, dest.size()); 354 assertEquals(availableLocales.get(0), dest.get(0)); // "sr-Latn-RS" 355 } 356 } 357 testFilterKnownLimitation()358 public void testFilterKnownLimitation() throws Exception { 359 // Following test cases are not for intentional behavior but checks for preventing the 360 // behavior from becoming worse. 361 { 362 final LocaleList preferredLocales = LocaleList.forLanguageTags("ja-Hrkt"); 363 final ArrayList<Locale> availableLocales = new ArrayList<>(); 364 availableLocales.add(Locale.forLanguageTag("ja-Jpan")); 365 availableLocales.add(Locale.forLanguageTag("ja-Hrkt")); 366 final ArrayList<Locale> dest = new ArrayList<>(); 367 LocaleUtils.filterByLanguage(availableLocales, sIdentityMapper, preferredLocales, dest); 368 assertEquals(1, dest.size()); 369 // Should be ja-Jpan since it supports ja-Hrkt and listed before ja-Hrkt. 370 assertEquals(availableLocales.get(1), dest.get(0)); 371 } 372 { 373 final LocaleList preferredLocales = LocaleList.forLanguageTags("zh-Hani"); 374 final ArrayList<Locale> availableLocales = new ArrayList<>(); 375 availableLocales.add(Locale.forLanguageTag("zh-Hans")); 376 availableLocales.add(Locale.forLanguageTag("zh-Hant")); 377 availableLocales.add(Locale.forLanguageTag("zh-Hanb")); 378 availableLocales.add(Locale.forLanguageTag("zh-Hani")); 379 final ArrayList<Locale> dest = new ArrayList<>(); 380 LocaleUtils.filterByLanguage(availableLocales, sIdentityMapper, preferredLocales, dest); 381 assertEquals(1, dest.size()); 382 // Should be zh-Hans since it supports zh-Hani. Also zh-Hant, zh-Hanb supports zh-Hani. 383 assertEquals(availableLocales.get(3), dest.get(0)); 384 } 385 } 386 } 387