1 /* 2 * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @bug 7069824 8042360 8032842 8175539 27 * @summary Verify implementation for Locale matching. 28 * @run main Bug7069824 29 */ 30 31 import java.util.*; 32 import java.util.Locale.*; 33 import static java.util.Locale.FilteringMode.*; 34 import static java.util.Locale.LanguageRange.*; 35 36 public class Bug7069824 { 37 38 static boolean err = false; 39 40 public static void main(String[] args) { 41 testLanguageRange(); 42 testLocale(); 43 44 if (err) { 45 throw new RuntimeException("Failed."); 46 } 47 } 48 49 private static void testLanguageRange() { 50 System.out.println("Test LanguageRange class..."); 51 testConstants(); 52 testConstructors(); 53 testMethods(); 54 } 55 56 private static void testLocale() { 57 System.out.println("Test Locale class..."); 58 test_filter(); 59 test_filterTags(); 60 test_lookup(); 61 test_lookupTag(); 62 } 63 64 private static void testConstants() { 65 boolean error = false; 66 67 if (MIN_WEIGHT != 0.0) { 68 error = true; 69 System.err.println(" MIN_WEIGHT should be 0.0 but got " 70 + MIN_WEIGHT); 71 } 72 73 if (MAX_WEIGHT != 1.0) { 74 error = true; 75 System.err.println(" MAX_WEIGHT should be 1.0 but got " 76 + MAX_WEIGHT); 77 } 78 79 if (error) { 80 err = true; 81 System.err.println(" testConstants() failed."); 82 } else { 83 System.out.println(" testConstants() passed."); 84 } 85 } 86 87 private static void testConstructors() { 88 boolean error = false; 89 90 LanguageRange lr; 91 String range; 92 double weight; 93 94 // Testcase for 8042360 95 range = "en-Latn-1234567890"; 96 try { 97 lr = new LanguageRange(range); 98 error = true; 99 System.err.println(" IAE should be thrown for LanguageRange(" 100 + range + ")."); 101 } 102 catch (IllegalArgumentException ex) { 103 } 104 105 range = null; 106 try { 107 lr = new LanguageRange(range); 108 error = true; 109 System.err.println(" NPE should be thrown for LanguageRange(" 110 + range + ")."); 111 } 112 catch (NullPointerException ex) { 113 } 114 115 range = null; 116 weight = 0.8; 117 try { 118 lr = new LanguageRange(range, weight); 119 error = true; 120 System.err.println(" NPE should be thrown for LanguageRange(" 121 + range + ", " + weight + ")."); 122 } 123 catch (NullPointerException ex) { 124 } 125 126 range = "elvish"; 127 try { 128 lr = new LanguageRange(range); 129 } 130 catch (Exception ex) { 131 error = true; 132 System.err.println(" " + ex 133 + " should not be thrown for LanguageRange(" + range + ")."); 134 } 135 136 range = "de-DE"; 137 try { 138 lr = new LanguageRange(range); 139 } 140 catch (Exception ex) { 141 error = true; 142 System.err.println(" " + ex 143 + " should not be thrown for LanguageRange(" + range + ")."); 144 } 145 146 range = "ar"; 147 weight = 0.8; 148 try { 149 lr = new LanguageRange(range, weight); 150 } 151 catch (Exception ex) { 152 error = true; 153 System.err.println(" " + ex 154 + " should not be thrown for LanguageRange(" + range + ", " 155 + weight + ")."); 156 } 157 158 range = "ja"; 159 weight = -0.8; 160 try { 161 lr = new LanguageRange(range, weight); 162 error = true; 163 System.err.println(" IAE should be thrown for LanguageRange(" 164 + range + ", " + weight + ")."); 165 } 166 catch (IllegalArgumentException ex) { 167 } 168 169 range = "Elvish"; 170 weight = 3.0; 171 try { 172 lr = new LanguageRange(range, weight); 173 error = true; 174 System.err.println(" IAE should be thrown for LanguageRange(" 175 + range + ", " + weight + ")."); 176 } 177 catch (IllegalArgumentException ex) { 178 } 179 180 String[] illformedRanges = {"-ja", "ja--JP", "en-US-", "a4r", "ar*", 181 "ar-*EG", "", "abcdefghijklmn", "ja-J=", "ja-opqrstuvwxyz"}; 182 for (String r : illformedRanges) { 183 try { 184 lr = new LanguageRange(r); 185 error = true; 186 System.err.println(" IAE should be thrown for LanguageRange(" 187 + r + ")."); 188 } 189 catch (IllegalArgumentException ex) { 190 } 191 } 192 193 194 if (error) { 195 err = true; 196 System.err.println(" testConstructors() failed."); 197 } else { 198 System.out.println(" testConstructors() passed."); 199 } 200 } 201 202 private static void testMethods() { 203 test_getRange(); 204 test_getWeight(); 205 test_equals(); 206 test_parse(); 207 test_mapEquivalents(); 208 } 209 210 private static void test_getRange() { 211 boolean error = false; 212 213 String range = "ja"; 214 double weight = 0.5; 215 LanguageRange lr = new LanguageRange(range, weight); 216 if (!lr.getRange().equals(range)) { 217 error = true; 218 System.err.println(" LanguageRange.getRange() returned unexpected value. Expected: " 219 + range + ", got: " + lr.getRange()); 220 } 221 222 range = "en-US"; 223 weight = 0.5; 224 lr = new LanguageRange(range, weight); 225 if (!lr.getRange().equals(range.toLowerCase())) { 226 error = true; 227 System.err.println(" LanguageRange.getRange() returned unexpected value. Expected: " 228 + range + ", got: " + lr.getRange()); 229 } 230 231 if (error) { 232 err = true; 233 System.err.println(" test_getRange() failed."); 234 } else { 235 System.out.println(" test_getRange() passed."); 236 } 237 } 238 239 private static void test_getWeight() { 240 boolean error = false; 241 242 String range = "ja"; 243 double weight = 0.5; 244 LanguageRange lr = new LanguageRange(range, weight); 245 if (lr.getWeight() != weight) { 246 error = true; 247 System.err.println(" LanguageRange.getWeight() returned unexpected value. Expected: " 248 + weight + ", got: " + lr.getWeight()); 249 } 250 251 range = "ja"; 252 weight = MAX_WEIGHT; // default 253 lr = new LanguageRange(range); 254 if (!lr.getRange().equals(range) || lr.getWeight() != MAX_WEIGHT) { 255 error = true; 256 System.err.println(" LanguageRange.getWeight() returned unexpected value. Expected: " 257 + weight + ", got: " + lr.getWeight()); 258 } 259 260 if (error) { 261 err = true; 262 System.err.println(" test_getWeight() failed."); 263 } else { 264 System.out.println(" test_getWeight() passed."); 265 } 266 } 267 268 private static void test_equals() { 269 boolean error = false; 270 271 LanguageRange lr1 = new LanguageRange("ja", 1.0); 272 LanguageRange lr2 = new LanguageRange("ja"); 273 LanguageRange lr3 = new LanguageRange("ja", 0.1); 274 LanguageRange lr4 = new LanguageRange("en", 1.0); 275 276 if (!lr1.equals(lr2)) { 277 error = true; 278 System.err.println(" LanguageRange(LR(ja, 1.0)).equals(LR(ja)) should return true."); 279 } 280 281 if (lr1.equals(lr3)) { 282 error = true; 283 System.err.println(" LanguageRange(LR(ja, 1.0)).equals(LR(ja, 0.1)) should return false."); 284 } 285 286 if (lr1.equals(lr4)) { 287 error = true; 288 System.err.println(" LanguageRange(LR(ja, 1.0)).equals(LR(en, 1.0)) should return false."); 289 } 290 291 if (lr1.equals(null)) { 292 error = true; 293 System.err.println(" LanguageRange(LR(ja, 1.0)).equals(null) should return false."); 294 } 295 296 if (lr1.equals("")) { 297 error = true; 298 System.err.println(" LanguageRange(LR(ja, 1.0)).equals(\"\") should return false."); 299 300 } 301 302 if (error) { 303 err = true; 304 System.err.println(" test_equals() failed."); 305 } else { 306 System.out.println(" test_equals() passed."); 307 } 308 } 309 310 private static void test_parse() { 311 boolean error = false; 312 313 List<LanguageRange> list; 314 String str = null; 315 try { 316 list = LanguageRange.parse(str); 317 error = true; 318 System.err.println(" NPE should be thrown for parse(" 319 + str + ")."); 320 } 321 catch (NullPointerException ex) { 322 } 323 324 str = ""; 325 try { 326 list = LanguageRange.parse(""); 327 error = true; 328 System.err.println(" IAE should be thrown for parse(" 329 + str + ")."); 330 } 331 catch (IllegalArgumentException ex) { 332 } 333 334 str = "ja;q=3"; 335 try { 336 list = LanguageRange.parse(str); 337 error = true; 338 System.err.println("IAE should be thrown for parse(" 339 + str + ")."); 340 } 341 catch (IllegalArgumentException ex) { 342 } 343 344 str = "Accept-Language: fr-FX,de-DE;q=0.5, fr-tp-x-FOO;q=0.1," 345 + "en-X-tp;q=0.6,en-FR;q=.7,de-de;q=0.8, iw;q=0.4, " 346 + "he;q=0.4, de-de;q=0.5,ja, in-tpp, in-tp;q=0.2"; 347 ArrayList<LanguageRange> expected = new ArrayList<>(); 348 expected.add(new LanguageRange("fr-fx", 1.0)); 349 expected.add(new LanguageRange("fr-fr", 1.0)); 350 expected.add(new LanguageRange("ja", 1.0)); 351 expected.add(new LanguageRange("in-tpp", 1.0)); 352 expected.add(new LanguageRange("id-tpp", 1.0)); 353 expected.add(new LanguageRange("en-fr", 0.7)); 354 expected.add(new LanguageRange("en-fx", 0.7)); 355 expected.add(new LanguageRange("en-x-tp", 0.6)); 356 expected.add(new LanguageRange("de-de", 0.5)); 357 expected.add(new LanguageRange("de-dd", 0.5)); 358 expected.add(new LanguageRange("iw", 0.4)); 359 expected.add(new LanguageRange("he", 0.4)); 360 expected.add(new LanguageRange("in-tp", 0.2)); 361 expected.add(new LanguageRange("id-tl", 0.2)); 362 expected.add(new LanguageRange("id-tp", 0.2)); 363 expected.add(new LanguageRange("in-tl", 0.2)); 364 expected.add(new LanguageRange("fr-tp-x-foo", 0.1)); 365 expected.add(new LanguageRange("fr-tl-x-foo", 0.1)); 366 List<LanguageRange> got = LanguageRange.parse(str); 367 if (!areEqual(expected, got)) { 368 error = true; 369 System.err.println(" #1 parse() test failed."); 370 } 371 372 str = "Accept-Language: hak-CN;q=0.8, no-bok-NO;q=0.9, no-nyn, cmn-CN;q=0.1"; 373 expected = new ArrayList<>(); 374 expected.add(new LanguageRange("no-nyn", 1.0)); 375 expected.add(new LanguageRange("nn", 1.0)); 376 expected.add(new LanguageRange("no-bok-no", 0.9)); 377 expected.add(new LanguageRange("nb-no", 0.9)); 378 expected.add(new LanguageRange("hak-CN", 0.8)); 379 expected.add(new LanguageRange("zh-hakka-CN", 0.8)); 380 expected.add(new LanguageRange("i-hak-CN", 0.8)); 381 expected.add(new LanguageRange("cmn-CN", 0.1)); 382 expected.add(new LanguageRange("zh-cmn-CN", 0.1)); 383 expected.add(new LanguageRange("zh-guoyu-CN", 0.1)); 384 got = LanguageRange.parse(str); 385 if (!areEqual(expected, got)) { 386 error = true; 387 System.err.println(" #2 parse() test failed."); 388 } 389 390 str = "Accept-Language: rki;q=0.4, no-bok-NO;q=0.9, ccq;q=0.5"; 391 expected = new ArrayList<>(); 392 expected.add(new LanguageRange("no-bok-no", 0.9)); 393 expected.add(new LanguageRange("nb-no", 0.9)); 394 expected.add(new LanguageRange("rki", 0.4)); 395 expected.add(new LanguageRange("ybd", 0.4)); 396 expected.add(new LanguageRange("ccq", 0.4)); 397 got = LanguageRange.parse(str); 398 if (!areEqual(expected, got)) { 399 error = true; 400 System.err.println(" #3 parse() test failed."); 401 } 402 403 if (error) { 404 err = true; 405 System.err.println(" test_parse() failed."); 406 } else { 407 System.out.println(" test_parse() passed."); 408 } 409 } 410 411 private static boolean areEqual(List<LanguageRange> expected, 412 List<LanguageRange> got) { 413 boolean error = false; 414 415 int expectedSize = expected.size(); 416 int actualSize = got.size(); 417 418 if (expectedSize != actualSize) { 419 error = true; 420 421 System.err.println(" Expected size=" + expectedSize); 422 for (LanguageRange lr : expected) { 423 System.err.println(" range=" + lr.getRange() 424 + ", weight=" + lr.getWeight()); 425 } 426 427 System.out.println(" Actual size=" + actualSize); 428 for (LanguageRange lr : got) { 429 System.err.println(" range=" + lr.getRange() 430 + ", weight=" + lr.getWeight()); 431 } 432 } else { 433 for (int i = 0; i < expectedSize; i++) { 434 LanguageRange lr1 = expected.get(i); 435 LanguageRange lr2 = got.get(i); 436 437 if (!lr1.getRange().equals(lr2.getRange()) 438 || lr1.getWeight() != lr2.getWeight()) { 439 error = true; 440 System.err.println(" " + i + ": Expected: range=" + lr1.getRange() 441 + ", weight=" + lr1.getWeight()); 442 System.err.println(" " + i + ": Actual: range=" + lr2.getRange() 443 + ", weight=" + lr2.getWeight()); 444 } 445 } 446 } 447 448 return !error; 449 } 450 451 private static void test_mapEquivalents() { 452 boolean error = false; 453 454 String ranges = "zh, zh-TW;q=0.8, ar;q=0.9, EN, zh-HK, ja-JP;q=0.2, es;q=0.4"; 455 List<LanguageRange> priorityList = LanguageRange.parse(ranges); 456 HashMap<String, List<String>> map = null; 457 458 try { 459 List<LanguageRange> list = 460 LanguageRange.mapEquivalents(priorityList, null); 461 } 462 catch (Exception ex) { 463 error = true; 464 System.err.println(ex 465 + " should not be thrown for mapEquivalents(priorityList, null)."); 466 } 467 468 map = new HashMap<>(); 469 try { 470 List<LanguageRange> list = 471 LanguageRange.mapEquivalents(priorityList, map); 472 } 473 catch (Exception ex) { 474 error = true; 475 System.err.println(ex 476 + " should not be thrown for mapEquivalents(priorityList, empty map)."); 477 } 478 479 ArrayList<String> equivalentList = new ArrayList<>(); 480 equivalentList.add("ja"); 481 equivalentList.add("ja-Hira"); 482 map.put("ja", equivalentList); 483 try { 484 List<LanguageRange> list = LanguageRange.mapEquivalents(null, map); 485 error = true; 486 System.err.println("NPE should be thrown for mapEquivalents(null, map)."); 487 } 488 catch (NullPointerException ex) { 489 } 490 491 map = new LinkedHashMap<>(); 492 ArrayList<String> equivalentList1 = new ArrayList<>(); 493 equivalentList1.add("ja"); 494 equivalentList1.add("ja-Hira"); 495 map.put("ja", equivalentList1); 496 ArrayList<String> equivalentList2 = new ArrayList<>(); 497 equivalentList2.add("zh-Hans"); 498 equivalentList2.add("zh-Hans-CN"); 499 equivalentList2.add("zh-CN"); 500 map.put("zh", equivalentList2); 501 ArrayList<String> equivalentList3 = new ArrayList<>(); 502 equivalentList3.add("zh-TW"); 503 equivalentList3.add("zh-Hant"); 504 map.put("zh-TW", equivalentList3); 505 map.put("es", null); 506 ArrayList<String> equivalentList4 = new ArrayList<>(); 507 map.put("en", equivalentList4); 508 ArrayList<String> equivalentList5 = new ArrayList<>(); 509 equivalentList5.add("de"); 510 map.put("zh-HK", equivalentList5); 511 512 ArrayList<LanguageRange> expected = new ArrayList<>(); 513 expected.add(new LanguageRange("zh-hans", 1.0)); 514 expected.add(new LanguageRange("zh-hans-cn", 1.0)); 515 expected.add(new LanguageRange("zh-cn", 1.0)); 516 expected.add(new LanguageRange("de", 1.0)); 517 expected.add(new LanguageRange("ar", 0.9)); 518 expected.add(new LanguageRange("zh-tw", 0.8)); 519 expected.add(new LanguageRange("zh-hant", 0.8)); 520 expected.add(new LanguageRange("ja-jp", 0.2)); 521 expected.add(new LanguageRange("ja-hira-jp", 0.2)); 522 List<LanguageRange> got = 523 LanguageRange.mapEquivalents(priorityList, map); 524 525 if (!areEqual(expected, got)) { 526 error = true; 527 } 528 529 if (error) { 530 err = true; 531 System.err.println(" test_mapEquivalents() failed."); 532 } else { 533 System.out.println(" test_mapEquivalents() passed."); 534 } 535 } 536 537 private static void test_filter() { 538 boolean error = false; 539 540 String ranges = "ja-JP, fr-FR"; 541 String tags = "de-DE, en, ja-JP-hepburn, fr, he, ja-Latn-JP"; 542 FilteringMode mode = EXTENDED_FILTERING; 543 544 List<LanguageRange> priorityList = LanguageRange.parse(ranges); 545 List<Locale> tagList = generateLocales(tags); 546 String actualLocales = 547 showLocales(Locale.filter(priorityList, tagList, mode)); 548 String expectedLocales = "ja-JP-hepburn, ja-Latn-JP"; 549 550 if (!expectedLocales.equals(actualLocales)) { 551 error = true; 552 showErrorMessage("#1 filter(" + mode + ")", 553 ranges, tags, expectedLocales, actualLocales); 554 } 555 556 557 ranges = "ja-*-JP, fr-FR"; 558 tags = "de-DE, en, ja-JP-hepburn, fr, he, ja-Latn-JP"; 559 mode = EXTENDED_FILTERING; 560 561 priorityList = LanguageRange.parse(ranges); 562 tagList = generateLocales(tags); 563 actualLocales = showLocales(Locale.filter(priorityList, tagList, mode)); 564 expectedLocales = "ja-JP-hepburn, ja-Latn-JP"; 565 566 if (!expectedLocales.equals(actualLocales)) { 567 error = true; 568 showErrorMessage("#2 filter(" + mode + ")", 569 ranges, tags, expectedLocales, actualLocales); 570 } 571 572 573 ranges = "ja-*-JP, fr-FR, de-de;q=0.2"; 574 tags = "de-DE, en, ja-JP-hepburn, de-de, fr, he, ja-Latn-JP"; 575 mode = AUTOSELECT_FILTERING; 576 577 priorityList = LanguageRange.parse(ranges); 578 tagList = generateLocales(tags); 579 actualLocales = showLocales(Locale.filter(priorityList, tagList, mode)); 580 expectedLocales = "ja-JP-hepburn, ja-Latn-JP, de-DE"; 581 582 if (!expectedLocales.equals(actualLocales)) { 583 error = true; 584 showErrorMessage("#3 filter(" + mode + ")", 585 ranges, tags,expectedLocales, actualLocales); 586 } 587 588 ranges = "ja-JP, fr-FR, de-de;q=0.2"; 589 tags = "de-DE, en, ja-JP-hepburn, de-de, fr, he, ja-Latn-JP"; 590 mode = AUTOSELECT_FILTERING; 591 592 priorityList = LanguageRange.parse(ranges); 593 tagList = generateLocales(tags); 594 actualLocales = showLocales(Locale.filter(priorityList, tagList, mode)); 595 expectedLocales = "ja-JP-hepburn, de-DE"; 596 597 if (!expectedLocales.equals(actualLocales)) { 598 error = true; 599 showErrorMessage("#4 filter(" + mode + ")", 600 ranges, tags, expectedLocales, actualLocales); 601 } 602 603 604 ranges = "en;q=0.2, ja-*-JP, fr-JP"; 605 tags = "de-DE, en, ja-JP-hepburn, fr, he, ja-Latn-JP"; 606 mode = IGNORE_EXTENDED_RANGES; 607 608 priorityList = LanguageRange.parse(ranges); 609 tagList = generateLocales(tags); 610 actualLocales = showLocales(Locale.filter(priorityList, tagList, mode)); 611 expectedLocales = "en"; 612 613 if (!expectedLocales.equals(actualLocales)) { 614 error = true; 615 showErrorMessage("#5 filter(" + mode + ")", 616 ranges, tags, expectedLocales, actualLocales); 617 } 618 619 620 ranges = "en;q=0.2, ja-*-JP, fr-JP"; 621 tags = "de-DE, en, ja-JP-hepburn, fr, he, ja-Latn-JP"; 622 mode = MAP_EXTENDED_RANGES; 623 624 priorityList = LanguageRange.parse(ranges); 625 tagList = generateLocales(tags); 626 actualLocales = showLocales(Locale.filter(priorityList, tagList, mode)); 627 expectedLocales = "ja-JP-hepburn, en"; 628 629 if (!expectedLocales.equals(actualLocales)) { 630 error = true; 631 showErrorMessage("#6 filter(" + mode + ")", 632 ranges, tags, expectedLocales, actualLocales); 633 } 634 635 636 ranges = "en;q=0.2, ja-JP, fr-JP"; 637 tags = "de-DE, en, ja-JP-hepburn, fr, he, ja-Latn-JP"; 638 mode = REJECT_EXTENDED_RANGES; 639 640 priorityList = LanguageRange.parse(ranges); 641 tagList = generateLocales(tags); 642 actualLocales = showLocales(Locale.filter(priorityList, tagList, mode)); 643 expectedLocales = "ja-JP-hepburn, en"; 644 645 if (!expectedLocales.equals(actualLocales)) { 646 error = true; 647 showErrorMessage("#7 filter(" + mode + ")", 648 ranges, tags, expectedLocales, actualLocales); 649 } 650 651 652 ranges = "en;q=0.2, ja-*-JP, fr-JP"; 653 tags = "de-DE, en, ja-JP-hepburn, fr, he, ja-Latn-JP"; 654 mode = REJECT_EXTENDED_RANGES; 655 656 priorityList = LanguageRange.parse(ranges); 657 tagList = generateLocales(tags); 658 try { 659 actualLocales = 660 showLocales(Locale.filter(priorityList, tagList, mode)); 661 error = true; 662 System.out.println("IAE should be thrown for filter(" 663 + mode + ")."); 664 } 665 catch (IllegalArgumentException ex) { 666 } 667 668 669 ranges = "en;q=0.2, ja-*-JP, fr-JP"; 670 tags = null; 671 mode = REJECT_EXTENDED_RANGES; 672 673 priorityList = LanguageRange.parse(ranges); 674 tagList = generateLocales(tags); 675 try { 676 actualLocales = 677 showLocales(Locale.filter(priorityList, tagList, mode)); 678 error = true; 679 System.out.println("NPE should be thrown for filter(tags=null)."); 680 } 681 catch (NullPointerException ex) { 682 } 683 684 685 ranges = null; 686 tags = "de-DE, en, ja-JP-hepburn, fr, he, ja-Latn-JP"; 687 mode = REJECT_EXTENDED_RANGES; 688 689 try { 690 priorityList = LanguageRange.parse(ranges); 691 tagList = generateLocales(tags); 692 actualLocales = 693 showLocales(Locale.filter(priorityList, tagList, mode)); 694 error = true; 695 System.out.println("NPE should be thrown for filter(ranges=null)."); 696 } 697 catch (NullPointerException ex) { 698 } 699 700 701 ranges = "en;q=0.2, ja-*-JP, fr-JP"; 702 tags = ""; 703 mode = REJECT_EXTENDED_RANGES; 704 705 priorityList = LanguageRange.parse(ranges); 706 tagList = generateLocales(tags); 707 try { 708 actualLocales = 709 showLocales(Locale.filter(priorityList, tagList, mode)); 710 } 711 catch (Exception ex) { 712 error = true; 713 System.out.println(ex 714 + " should not be thrown for filter(" + ranges + ", \"\")."); 715 } 716 717 718 if (error) { 719 err = true; 720 System.out.println(" test_filter() failed."); 721 } else { 722 System.out.println(" test_filter() passed."); 723 } 724 } 725 726 private static void test_filterTags() { 727 boolean error = false; 728 729 String ranges = "en;q=0.2, *;q=0.6, ja"; 730 String tags = "de-DE, en, ja-JP-hepburn, fr-JP, he"; 731 732 List<LanguageRange> priorityList = LanguageRange.parse(ranges); 733 List<String> tagList = generateLanguageTags(tags); 734 String actualTags = 735 showLanguageTags(Locale.filterTags(priorityList, tagList)); 736 String expectedTags = tags; 737 738 if (!expectedTags.equals(actualTags)) { 739 error = true; 740 showErrorMessage("#1 filterTags()", 741 ranges, tags, expectedTags, actualTags); 742 } 743 744 745 ranges = "en;q=0.2, ja-JP, fr-JP"; 746 tags = "de-DE, en, ja-JP-hepburn, fr, he"; 747 priorityList = LanguageRange.parse(ranges); 748 tagList = generateLanguageTags(tags); 749 actualTags = showLanguageTags(Locale.filterTags(priorityList, tagList)); 750 expectedTags = "ja-JP-hepburn, en"; 751 752 if (!expectedTags.equals(actualTags)) { 753 error = true; 754 showErrorMessage("#2 filterTags()", 755 ranges, tags, expectedTags, actualTags); 756 } 757 758 759 ranges = "de-DE"; 760 tags = "de-DE, de-de, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, " 761 + "de-Latn-DE-1996, de-Deva-DE, de, de-x-DE, de-Deva"; 762 FilteringMode mode = MAP_EXTENDED_RANGES; 763 priorityList = LanguageRange.parse(ranges); 764 tagList = generateLanguageTags(tags); 765 actualTags = showLanguageTags(Locale.filterTags(priorityList, tagList, mode)); 766 expectedTags = "de-DE, de-DE-x-goethe"; 767 768 if (!expectedTags.equals(actualTags)) { 769 error = true; 770 showErrorMessage("#3 filterTags(" + mode + ")", 771 ranges, tags, expectedTags, actualTags); 772 } 773 774 775 ranges = "de-DE"; 776 tags = "de-DE, de-de, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, " 777 + "de-Latn-DE-1996, de-Deva-DE, de, de-x-DE, de-Deva"; 778 mode = EXTENDED_FILTERING; 779 priorityList = LanguageRange.parse(ranges); 780 tagList = generateLanguageTags(tags); 781 actualTags = showLanguageTags(Locale.filterTags(priorityList, tagList, mode)); 782 expectedTags = "de-DE, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, " 783 + "de-Latn-DE-1996, de-Deva-DE"; 784 785 if (!expectedTags.equals(actualTags)) { 786 error = true; 787 showErrorMessage("#4 filterTags(" + mode + ")", 788 ranges, tags, expectedTags, actualTags); 789 } 790 791 792 ranges = "de-*-DE"; 793 tags = "de-DE, de-de, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, " 794 + "de-Latn-DE-1996, de-Deva-DE, de, de-x-DE, de-Deva"; 795 mode = EXTENDED_FILTERING; 796 priorityList = LanguageRange.parse(ranges); 797 tagList = generateLanguageTags(tags); 798 actualTags = showLanguageTags(Locale.filterTags(priorityList, tagList, mode)); 799 expectedTags = "de-DE, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, " 800 + "de-Latn-DE-1996, de-Deva-DE"; 801 802 if (!expectedTags.equals(actualTags)) { 803 error = true; 804 showErrorMessage("#5 filterTags(" + mode + ")", 805 ranges, tags, expectedTags, actualTags); 806 } 807 808 if (error) { 809 err = true; 810 System.out.println(" test_filterTags() failed."); 811 } else { 812 System.out.println(" test_filterTags() passed."); 813 } 814 } 815 816 private static void test_lookup() { 817 boolean error = false; 818 819 String ranges = "en;q=0.2, *-JP;q=0.6, iw"; 820 String tags = "de-DE, en, ja-JP-hepburn, fr-JP, he"; 821 List<LanguageRange> priorityList = LanguageRange.parse(ranges); 822 List<Locale> localeList = generateLocales(tags); 823 String actualLocale = 824 Locale.lookup(priorityList, localeList).toLanguageTag(); 825 String expectedLocale ="he"; 826 827 if (!expectedLocale.equals(actualLocale)) { 828 error = true; 829 showErrorMessage("#1 lookup()", ranges, tags, expectedLocale, actualLocale); 830 } 831 832 833 ranges = "en;q=0.2, *-JP;q=0.6, iw"; 834 tags = "de-DE, he-IL, en, iw"; 835 priorityList = LanguageRange.parse(ranges); 836 localeList = generateLocales(tags); 837 actualLocale = Locale.lookup(priorityList, localeList).toLanguageTag(); 838 expectedLocale = "he"; 839 840 if (!expectedLocale.equals(actualLocale)) { 841 error = true; 842 showErrorMessage("#2 lookup()", ranges, tags, expectedLocale, actualLocale); 843 } 844 845 846 ranges = "en;q=0.2, ja-*-JP-x-foo;q=0.6, iw"; 847 tags = "de-DE, fr, en, ja-Latn-JP"; 848 priorityList = LanguageRange.parse(ranges); 849 localeList = generateLocales(tags); 850 actualLocale = Locale.lookup(priorityList, localeList).toLanguageTag(); 851 expectedLocale = "ja-Latn-JP"; 852 853 if (!expectedLocale.equals(actualLocale)) { 854 error = true; 855 showErrorMessage("#3 lookup()", ranges, tags, expectedLocale, actualLocale); 856 } 857 858 if (error) { 859 err = true; 860 System.out.println(" test_lookup() failed."); 861 } else { 862 System.out.println(" test_lookup() passed."); 863 } 864 } 865 866 private static void test_lookupTag() { 867 boolean error = false; 868 869 String ranges = "en, *"; 870 String tags = "es, de, ja-JP"; 871 List<LanguageRange> priorityList = LanguageRange.parse(ranges); 872 List<String> tagList = generateLanguageTags(tags); 873 String actualTag = Locale.lookupTag(priorityList, tagList); 874 String expectedTag = null; 875 876 if (actualTag != null) { 877 error = true; 878 showErrorMessage("#1 lookupTag()", ranges, tags, expectedTag, actualTag); 879 } 880 881 882 ranges= "en;q=0.2, *-JP"; 883 tags = "de-DE, en, ja-JP-hepburn, fr-JP, en-JP"; 884 priorityList = LanguageRange.parse(ranges); 885 tagList = generateLanguageTags(tags); 886 actualTag = Locale.lookupTag(priorityList, tagList); 887 expectedTag = "fr-JP"; 888 889 if (!expectedTag.equals(actualTag)) { 890 error = true; 891 showErrorMessage("#2 lookupTag()", ranges, tags, expectedTag, actualTag); 892 } 893 894 895 ranges = "en;q=0.2, ar-MO, iw"; 896 tags = "de-DE, he, fr-JP"; 897 priorityList = LanguageRange.parse(ranges); 898 tagList = generateLanguageTags(tags); 899 actualTag = Locale.lookupTag(priorityList, tagList); 900 expectedTag = "he"; 901 902 if (!expectedTag.equals(actualTag)) { 903 error = true; 904 showErrorMessage("#3 lookupTag()", ranges, tags, expectedTag, actualTag); 905 } 906 907 908 ranges = "en;q=0.2, ar-MO, he"; 909 tags = "de-DE, iw, fr-JP"; 910 priorityList = LanguageRange.parse(ranges); 911 tagList = generateLanguageTags(tags); 912 actualTag = Locale.lookupTag(priorityList, tagList); 913 expectedTag = "iw"; 914 915 if (!expectedTag.equals(actualTag)) { 916 error = true; 917 showErrorMessage("#4 lookupTag()", ranges, tags, expectedTag, actualTag); 918 } 919 920 if (error) { 921 err = true; 922 System.out.println(" test_lookupTag() failed."); 923 } else { 924 System.out.println(" test_lookupTag() passed."); 925 } 926 } 927 928 private static List<Locale> generateLocales(String tags) { 929 if (tags == null) { 930 return null; 931 } 932 933 List<Locale> localeList = new ArrayList<>(); 934 if (tags.equals("")) { 935 return localeList; 936 } 937 String[] t = tags.split(", "); 938 for (String tag : t) { 939 localeList.add(Locale.forLanguageTag(tag)); 940 } 941 return localeList; 942 } 943 944 private static List<String> generateLanguageTags(String tags) { 945 List<String> tagList = new ArrayList<>(); 946 String[] t = tags.split(", "); 947 for (String tag : t) { 948 tagList.add(tag); 949 } 950 return tagList; 951 } 952 953 private static String showPriorityList(List<LanguageRange> priorityList) { 954 StringBuilder sb = new StringBuilder(); 955 956 Iterator<LanguageRange> itr = priorityList.iterator(); 957 LanguageRange lr; 958 if (itr.hasNext()) { 959 lr = itr.next(); 960 sb.append(lr.getRange()); 961 sb.append(";q="); 962 sb.append(lr.getWeight()); 963 } 964 while (itr.hasNext()) { 965 sb.append(", "); 966 lr = itr.next(); 967 sb.append(lr.getRange()); 968 sb.append(";q="); 969 sb.append(lr.getWeight()); 970 } 971 972 return sb.toString(); 973 } 974 975 private static String showLanguageTags(List<String> tags) { 976 StringBuilder sb = new StringBuilder(); 977 978 Iterator<String> itr = tags.iterator(); 979 if (itr.hasNext()) { 980 sb.append(itr.next()); 981 } 982 while (itr.hasNext()) { 983 sb.append(", "); 984 sb.append(itr.next()); 985 } 986 987 return sb.toString().trim(); 988 } 989 990 private static String showLocales(List<Locale> locales) { 991 StringBuilder sb = new StringBuilder(); 992 993 Iterator<Locale> itr = locales.iterator(); 994 if (itr.hasNext()) { 995 sb.append(itr.next().toLanguageTag()); 996 } 997 while (itr.hasNext()) { 998 sb.append(", "); 999 sb.append(itr.next().toLanguageTag()); 1000 } 1001 1002 return sb.toString().trim(); 1003 } 1004 1005 private static void showErrorMessage(String methodName, 1006 String priorityList, 1007 String tags, 1008 String expectedTags, 1009 String actualTags) { 1010 System.out.println("\nIncorrect " + methodName + " result."); 1011 System.out.println(" Priority list : " + priorityList); 1012 System.out.println(" Language tags : " + tags); 1013 System.out.println(" Expected value : " + expectedTags); 1014 System.out.println(" Actual value : " + actualTags); 1015 } 1016 1017 } | 1 /* 2 * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @bug 7069824 8042360 8032842 8175539 8210443 27 * @summary Verify implementation for Locale matching. 28 * @run testng/othervm Bug7069824 29 */ 30 31 import java.util.*; 32 import java.util.Locale.*; 33 import static java.util.Locale.FilteringMode.*; 34 import static java.util.Locale.LanguageRange.*; 35 import static org.testng.Assert.*; 36 37 import org.testng.annotations.DataProvider; 38 import org.testng.annotations.Test; 39 40 public class Bug7069824 { 41 42 @DataProvider(name = "LRConstructorData") 43 Object[][] LRConstructorData() { 44 return new Object[][] { 45 // Range, Weight 46 {"elvish", MAX_WEIGHT}, 47 {"de-DE", MAX_WEIGHT}, 48 {"de-Latn-DE-1996", MAX_WEIGHT}, 49 {"zh-Hant-CN-x-private1-private2", MAX_WEIGHT}, 50 {"ar", 0.8}, 51 {"en-US", 0.5}, 52 {"sr-Latn-BA", 0}, 53 {"ja", 1}, 54 }; 55 } 56 57 @DataProvider(name = "LRConstructorNPEData") 58 Object[][] LRConstructorNPEData() { 59 return new Object[][] { 60 // Range, Weight 61 {null, MAX_WEIGHT}, 62 {null, 0.8}, 63 }; 64 } 65 66 @DataProvider(name = "LRConstructorIAEData") 67 Object[][] LRConstructorIAEData() { 68 return new Object[][] { 69 // Range, Weight 70 {"ja", -0.8}, 71 {"Elvish", 3.0}, 72 {"-ja", MAX_WEIGHT}, 73 {"ja--JP", MAX_WEIGHT}, 74 {"en-US-", MAX_WEIGHT}, 75 {"a4r", MAX_WEIGHT}, 76 {"ar*", MAX_WEIGHT}, 77 {"ar-*EG", MAX_WEIGHT}, 78 {"abcdefghijklmn", MAX_WEIGHT}, 79 {"ja-J=", MAX_WEIGHT}, 80 {"ja-opqrstuvwxyz", MAX_WEIGHT}, 81 {"zh_CN", MAX_WEIGHT}, 82 {"1996-de-Latn", MAX_WEIGHT}, 83 // Testcase for 8042360 84 {"en-Latn-1234567890", MAX_WEIGHT}, 85 }; 86 } 87 88 @DataProvider(name = "LRParseData") 89 Object[][] LRParseData() { 90 return new Object[][] { 91 // Ranges, Expected result 92 {"Accept-Language: fr-FX, de-DE;q=0.5, fr-tp-x-FOO;q=0.1, " 93 + "en-X-tp;q=0.6, en-FR;q=0.7, de-de;q=0.8, iw;q=0.4, " 94 + "he;q=0.4, de-de;q=0.5, ja, in-tpp, in-tp;q=0.2", 95 List.of(new LanguageRange("fr-fx", 1.0), 96 new LanguageRange("fr-fr", 1.0), 97 new LanguageRange("ja", 1.0), 98 new LanguageRange("in-tpp", 1.0), 99 new LanguageRange("id-tpp", 1.0), 100 new LanguageRange("en-fr", 0.7), 101 new LanguageRange("en-fx", 0.7), 102 new LanguageRange("en-x-tp", 0.6), 103 new LanguageRange("de-de", 0.5), 104 new LanguageRange("de-dd", 0.5), 105 new LanguageRange("iw", 0.4), 106 new LanguageRange("he", 0.4), 107 new LanguageRange("in-tp", 0.2), 108 new LanguageRange("id-tl", 0.2), 109 new LanguageRange("id-tp", 0.2), 110 new LanguageRange("in-tl", 0.2), 111 new LanguageRange("fr-tp-x-foo", 0.1), 112 new LanguageRange("fr-tl-x-foo", 0.1))}, 113 {"Accept-Language: hak-CN;q=0.8, no-bok-NO;q=0.9, no-nyn, cmn-CN;q=0.1", 114 List.of(new LanguageRange("no-nyn", 1.0), 115 new LanguageRange("nn", 1.0), 116 new LanguageRange("no-bok-no", 0.9), 117 new LanguageRange("nb-no", 0.9), 118 new LanguageRange("hak-CN", 0.8), 119 new LanguageRange("zh-hakka-CN", 0.8), 120 new LanguageRange("i-hak-CN", 0.8), 121 new LanguageRange("cmn-CN", 0.1), 122 new LanguageRange("zh-cmn-CN", 0.1), 123 new LanguageRange("zh-guoyu-CN", 0.1))}, 124 {"Accept-Language: rki;q=0.4, no-bok-NO;q=0.9, ccq;q=0.5", 125 List.of(new LanguageRange("no-bok-no", 0.9), 126 new LanguageRange("nb-no", 0.9), 127 new LanguageRange("rki", 0.4), 128 new LanguageRange("ybd", 0.4), 129 new LanguageRange("ccq", 0.4))}, 130 }; 131 } 132 133 @DataProvider(name = "LRParseIAEData") 134 Object[][] LRParseIAEData() { 135 return new Object[][] { 136 // Ranges 137 {""}, 138 {"ja;q=3"}, 139 }; 140 } 141 142 @DataProvider(name = "LRMapEquivalentsData") 143 Object[][] LRMapEquivalentsData() { 144 return new Object[][] { 145 // Ranges, Map, Expected result 146 {LanguageRange.parse("zh, zh-TW;q=0.8, ar;q=0.9, EN, zh-HK, ja-JP;q=0.2, es;q=0.4"), 147 new HashMap<>(), 148 LanguageRange.parse("zh, zh-TW;q=0.8, ar;q=0.9, EN, zh-HK, ja-JP;q=0.2, es;q=0.4")}, 149 {LanguageRange.parse("zh, zh-TW;q=0.8, ar;q=0.9, EN, zh-HK, ja-JP;q=0.2, es;q=0.4"), 150 null, 151 LanguageRange.parse("zh, zh-TW;q=0.8, ar;q=0.9, EN, zh-HK, ja-JP;q=0.2, es;q=0.4")}, 152 {LanguageRange.parse("zh, zh-TW;q=0.8, ar;q=0.9, EN, zh-HK, ja-JP;q=0.2, es;q=0.4"), 153 new LinkedHashMap<String, List<String>>() { 154 { 155 put("ja", List.of("ja", "ja-Hira")); 156 put("zh", List.of("zh-Hans", "zh-Hans-CN", "zh-CN")); 157 put("zh-TW", List.of("zh-TW", "zh-Hant")); 158 put("es", null); 159 put("en", List.of()); 160 put("zh-HK", List.of("de")); 161 } 162 }, 163 List.of(new LanguageRange("zh-hans", 1.0), 164 new LanguageRange("zh-hans-cn", 1.0), 165 new LanguageRange("zh-cn", 1.0), 166 new LanguageRange("de", 1.0), 167 new LanguageRange("ar", 0.9), 168 new LanguageRange("zh-tw", 0.8), 169 new LanguageRange("zh-hant", 0.8), 170 new LanguageRange("ja-jp", 0.2), 171 new LanguageRange("ja-hira-jp", 0.2))}, 172 }; 173 } 174 175 @DataProvider(name = "LFilterData") 176 Object[][] LFilterData() { 177 return new Object[][] { 178 // Range, LanguageTags, FilteringMode, Expected locales 179 {"ja-JP, fr-FR", "de-DE, en, ja-JP-hepburn, fr, he, ja-Latn-JP", 180 EXTENDED_FILTERING, "ja-JP-hepburn, ja-Latn-JP"}, 181 {"ja-*-JP, fr-FR", "de-DE, en, ja-JP-hepburn, fr, he, ja-Latn-JP", 182 EXTENDED_FILTERING, "ja-JP-hepburn, ja-Latn-JP"}, 183 {"ja-*-JP, fr-FR, de-de;q=0.2", "de-DE, en, ja-JP-hepburn, de-de, fr, he, ja-Latn-JP", 184 AUTOSELECT_FILTERING, "ja-JP-hepburn, ja-Latn-JP, de-DE"}, 185 {"ja-JP, fr-FR, de-de;q=0.2", "de-DE, en, ja-JP-hepburn, de-de, fr, he, ja-Latn-JP", 186 AUTOSELECT_FILTERING, "ja-JP-hepburn, de-DE"}, 187 {"en;q=0.2, ja-*-JP, fr-JP", "de-DE, en, ja-JP-hepburn, fr, he, ja-Latn-JP", 188 IGNORE_EXTENDED_RANGES, "en"}, 189 {"en;q=0.2, ja-*-JP, fr-JP", "de-DE, en, ja-JP-hepburn, fr, he, ja-Latn-JP", 190 MAP_EXTENDED_RANGES, "ja-JP-hepburn, en"}, 191 {"en;q=0.2, ja-JP, fr-JP", "de-DE, en, ja-JP-hepburn, fr, he, ja-Latn-JP", 192 REJECT_EXTENDED_RANGES, "ja-JP-hepburn, en"}, 193 {"en;q=0.2, ja-*-JP, fr-JP", "", REJECT_EXTENDED_RANGES, ""}, 194 }; 195 } 196 197 @DataProvider(name = "LFilterNPEData") 198 Object[][] LFilterNPEData() { 199 return new Object[][] { 200 // Range, LanguageTags, FilteringMode 201 {"en;q=0.2, ja-*-JP, fr-JP", null, REJECT_EXTENDED_RANGES}, 202 {null, "de-DE, en, ja-JP-hepburn, fr, he, ja-Latn-JP", REJECT_EXTENDED_RANGES}, 203 }; 204 } 205 206 @DataProvider(name = "LFilterTagsData") 207 Object[][] LFilterTagsData() { 208 return new Object[][] { 209 // Range, LanguageTags, FilteringMode, Expected language tags 210 {"en;q=0.2, *;q=0.6, ja", "de-DE, en, ja-JP-hepburn, fr-JP, he", 211 null, "de-DE, en, ja-JP-hepburn, fr-JP, he"}, 212 {"en;q=0.2, ja-JP, fr-JP", "de-DE, en, ja-JP-hepburn, fr, he", 213 null, "ja-JP-hepburn, en"}, 214 {"en;q=0.2, ja-JP, fr-JP, iw", "de-DE, he, en, ja-JP-hepburn, fr, he-IL", 215 null, "ja-JP-hepburn, he, he-IL, en"}, 216 {"en;q=0.2, ja-JP, fr-JP, he", "de-DE, en, ja-JP-hepburn, fr, iw-IL", 217 null, "ja-JP-hepburn, iw-IL, en"}, 218 {"de-DE", "de-DE, de-de, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, " 219 + "de-Latn-DE-1996, de-Deva-DE, de, de-x-DE, de-Deva", 220 MAP_EXTENDED_RANGES, "de-DE, de-DE-x-goethe"}, 221 {"de-DE", "de-DE, de-de, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, " 222 + "de-Latn-DE-1996, de-Deva-DE, de, de-x-DE, de-Deva", 223 EXTENDED_FILTERING, 224 "de-DE, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, " 225 + "de-Latn-DE-1996, de-Deva-DE"}, 226 {"de-*-DE", "de-DE, de-de, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, " 227 + "de-Latn-DE-1996, de-Deva-DE, de, de-x-DE, de-Deva", 228 EXTENDED_FILTERING, 229 "de-DE, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, " 230 + "de-Latn-DE-1996, de-Deva-DE"}, 231 }; 232 } 233 234 @DataProvider(name = "LLookupData") 235 Object[][] LLookupData() { 236 return new Object[][] { 237 // Range, LanguageTags, Expected locale 238 {"en;q=0.2, *-JP;q=0.6, iw", "de-DE, en, ja-JP-hepburn, fr-JP, he", "he"}, 239 {"en;q=0.2, *-JP;q=0.6, iw", "de-DE, he-IL, en, iw", "he"}, 240 {"en;q=0.2, ja-*-JP-x-foo;q=0.6, iw", "de-DE, fr, en, ja-Latn-JP", "ja-Latn-JP"}, 241 }; 242 } 243 244 @DataProvider(name = "LLookupTagData") 245 Object[][] LLookupTagData() { 246 return new Object[][] { 247 // Range, LanguageTags, Expected language tag 248 {"en, *", "es, de, ja-JP", null}, 249 {"en;q=0.2, *-JP", "de-DE, en, ja-JP-hepburn, fr-JP, en-JP", "fr-JP"}, 250 {"en;q=0.2, ar-MO, iw", "de-DE, he, fr-JP", "he"}, 251 {"en;q=0.2, ar-MO, he", "de-DE, iw, fr-JP", "iw"}, 252 {"de-DE-1996;q=0.8, en;q=0.2, iw;q=0.9, zh-Hans-CN;q=0.7", "de-DE, zh-CN, he, iw, fr-JP", "iw"}, 253 {"de-DE-1996;q=0.8, en;q=0.2, he;q=0.9, zh-Hans-CN;q=0.7", "de-DE, zh-CN, he, iw, fr-JP", "he"}, 254 }; 255 } 256 257 @Test 258 public void testLRConstants() { 259 assertEquals(MIN_WEIGHT, 0.0, " MIN_WEIGHT should be 0.0 but got " 260 + MIN_WEIGHT); 261 assertEquals(MAX_WEIGHT, 1.0, " MAX_WEIGHT should be 1.0 but got " 262 + MAX_WEIGHT); 263 } 264 265 @Test(dataProvider = "LRConstructorData") 266 public void testLRConstructors(String range, double weight) { 267 LanguageRange lr; 268 if (weight == MAX_WEIGHT) { 269 lr = new LanguageRange(range); 270 } else { 271 lr = new LanguageRange(range, weight); 272 } 273 assertEquals(lr.getRange(), range.toLowerCase(Locale.ROOT), 274 " LR.getRange() returned unexpected value. Expected: " 275 + range.toLowerCase(Locale.ROOT) + ", got: " + lr.getRange()); 276 assertEquals(lr.getWeight(), weight, 277 " LR.getWeight() returned unexpected value. Expected: " 278 + weight + ", got: " + lr.getWeight()); 279 } 280 281 @Test(dataProvider = "LRConstructorNPEData", expectedExceptions = NullPointerException.class) 282 public void testLRConstructorNPE(String range, double weight) { 283 if (weight == MAX_WEIGHT) { 284 new LanguageRange(range); 285 } else { 286 new LanguageRange(range, weight); 287 } 288 } 289 290 @Test(dataProvider = "LRConstructorIAEData", expectedExceptions = IllegalArgumentException.class) 291 public void testLRConstructorIAE(String range, double weight) { 292 if (weight == MAX_WEIGHT) { 293 new LanguageRange(range); 294 } else { 295 new LanguageRange(range, weight); 296 } 297 } 298 299 @Test 300 public void testLREquals() { 301 LanguageRange lr1 = new LanguageRange("ja", 1.0); 302 LanguageRange lr2 = new LanguageRange("ja"); 303 LanguageRange lr3 = new LanguageRange("ja", 0.1); 304 LanguageRange lr4 = new LanguageRange("en", 1.0); 305 306 assertEquals(lr1, lr2, " LR(ja, 1.0).equals(LR(ja)) should return true."); 307 assertNotEquals(lr1, lr3, " LR(ja, 1.0).equals(LR(ja, 0.1)) should return false."); 308 assertNotEquals(lr1, lr4, " LR(ja, 1.0).equals(LR(en, 1.0)) should return false."); 309 assertNotNull(lr1, " LR(ja, 1.0).equals(null) should return false."); 310 assertNotEquals(lr1, "", " LR(ja, 1.0).equals(\"\") should return false."); 311 } 312 313 @Test(dataProvider = "LRParseData") 314 public void testLRParse(String ranges, List<LanguageRange> expected) { 315 assertEquals(LanguageRange.parse(ranges), expected, 316 " LR.parse(" + ranges + ") test failed."); 317 } 318 319 @Test(expectedExceptions = NullPointerException.class) 320 public void testLRParseNPE() { 321 LanguageRange.parse(null); 322 } 323 324 @Test(dataProvider = "LRParseIAEData", expectedExceptions = IllegalArgumentException.class) 325 public void testLRParseIAE(String ranges) { 326 LanguageRange.parse(ranges); 327 } 328 329 @Test(dataProvider = "LRMapEquivalentsData") 330 public void testLRMapEquivalents(List<Locale.LanguageRange> priorityList, 331 Map<String,List<String>> map, List<LanguageRange> expected) { 332 assertEquals(LanguageRange.mapEquivalents(priorityList, map), expected, 333 " LR.mapEquivalents() test failed."); 334 } 335 336 @Test(expectedExceptions = NullPointerException.class) 337 public void testLRMapEquivalentsNPE() { 338 LanguageRange.mapEquivalents(null, Map.of("ja", List.of("ja", "ja-Hira"))); 339 } 340 341 @Test(dataProvider = "LFilterData") 342 public void testLFilter(String ranges, String tags, FilteringMode mode, String expectedLocales) { 343 List<LanguageRange> priorityList = LanguageRange.parse(ranges); 344 List<Locale> tagList = generateLocales(tags); 345 String actualLocales = 346 showLocales(Locale.filter(priorityList, tagList, mode)); 347 assertEquals(actualLocales, expectedLocales, showErrorMessage(" L.Filter(" + mode + ")", 348 ranges, tags, expectedLocales, actualLocales)); 349 } 350 351 @Test(dataProvider = "LFilterNPEData", expectedExceptions = NullPointerException.class) 352 public void testLFilterNPE(String ranges, String tags, FilteringMode mode) { 353 List<LanguageRange> priorityList = LanguageRange.parse(ranges); 354 List<Locale> tagList = generateLocales(tags); 355 showLocales(Locale.filter(priorityList, tagList, mode)); 356 } 357 358 @Test(expectedExceptions = IllegalArgumentException.class) 359 public void testLFilterIAE() { 360 String ranges = "en;q=0.2, ja-*-JP, fr-JP"; 361 String tags = "de-DE, en, ja-JP-hepburn, fr, he, ja-Latn-JP"; 362 List<LanguageRange> priorityList = LanguageRange.parse(ranges); 363 List<Locale> tagList = generateLocales(tags); 364 showLocales(Locale.filter(priorityList, tagList, REJECT_EXTENDED_RANGES)); 365 } 366 367 @Test(dataProvider = "LFilterTagsData") 368 public void testLFilterTags(String ranges, String tags, FilteringMode mode, String expectedTags) { 369 List<LanguageRange> priorityList = LanguageRange.parse(ranges); 370 List<String> tagList = generateLanguageTags(tags); 371 String actualTags; 372 if (mode == null) { 373 actualTags = showLanguageTags(Locale.filterTags(priorityList, tagList)); 374 } else { 375 actualTags = showLanguageTags(Locale.filterTags(priorityList, tagList, mode)); 376 } 377 assertEquals(actualTags, expectedTags, 378 showErrorMessage(" L.FilterTags(" + (mode != null ? mode : "") + ")", 379 ranges, tags, expectedTags, actualTags)); 380 } 381 382 @Test(dataProvider = "LLookupData") 383 public void testLLookup(String ranges, String tags, String expectedLocale) { 384 List<LanguageRange> priorityList = LanguageRange.parse(ranges); 385 List<Locale> localeList = generateLocales(tags); 386 String actualLocale = 387 Locale.lookup(priorityList, localeList).toLanguageTag(); 388 assertEquals(actualLocale, expectedLocale, showErrorMessage(" L.Lookup()", 389 ranges, tags, expectedLocale, actualLocale)); 390 } 391 392 @Test(dataProvider = "LLookupTagData") 393 public void testLLookupTag(String ranges, String tags, String expectedTag) { 394 List<LanguageRange> priorityList = LanguageRange.parse(ranges); 395 List<String> tagList = generateLanguageTags(tags); 396 String actualTag = Locale.lookupTag(priorityList, tagList); 397 assertEquals(actualTag, expectedTag, showErrorMessage(" L.LookupTag()", 398 ranges, tags, expectedTag, actualTag)); 399 } 400 401 private static List<Locale> generateLocales(String tags) { 402 if (tags == null) { 403 return null; 404 } 405 406 List<Locale> localeList = new ArrayList<>(); 407 if (tags.equals("")) { 408 return localeList; 409 } 410 String[] t = tags.split(", "); 411 for (String tag : t) { 412 localeList.add(Locale.forLanguageTag(tag)); 413 } 414 return localeList; 415 } 416 417 private static List<String> generateLanguageTags(String tags) { 418 List<String> tagList = new ArrayList<>(); 419 String[] t = tags.split(", "); 420 for (String tag : t) { 421 tagList.add(tag); 422 } 423 return tagList; 424 } 425 426 private static String showLanguageTags(List<String> tags) { 427 StringBuilder sb = new StringBuilder(); 428 429 Iterator<String> itr = tags.iterator(); 430 if (itr.hasNext()) { 431 sb.append(itr.next()); 432 } 433 while (itr.hasNext()) { 434 sb.append(", "); 435 sb.append(itr.next()); 436 } 437 438 return sb.toString().trim(); 439 } 440 441 private static String showLocales(List<Locale> locales) { 442 StringBuilder sb = new StringBuilder(); 443 444 Iterator<Locale> itr = locales.iterator(); 445 if (itr.hasNext()) { 446 sb.append(itr.next().toLanguageTag()); 447 } 448 while (itr.hasNext()) { 449 sb.append(", "); 450 sb.append(itr.next().toLanguageTag()); 451 } 452 453 return sb.toString().trim(); 454 } 455 456 private static String showErrorMessage(String methodName, 457 String priorityList, 458 String tags, 459 String expectedTags, 460 String actualTags) { 461 return "Incorrect " + methodName + " result." 462 + " Priority list : " + priorityList 463 + " Language tags : " + tags 464 + " Expected value : " + expectedTags 465 + " Actual value : " + actualTags; 466 } 467 } |