Path: blob/master/test/jdk/java/util/Locale/Bug7069824.java
41149 views
/*1* Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 7069824 8042360 8032842 8175539 8210443 824201026* @summary Verify implementation for Locale matching.27* @run testng/othervm Bug706982428*/2930import java.util.*;31import java.util.Locale.*;32import static java.util.Locale.FilteringMode.*;33import static java.util.Locale.LanguageRange.*;34import static org.testng.Assert.*;3536import org.testng.annotations.DataProvider;37import org.testng.annotations.Test;3839public class Bug7069824 {4041@DataProvider(name = "LRConstructorData")42Object[][] LRConstructorData() {43return new Object[][] {44// Range, Weight45{"elvish", MAX_WEIGHT},46{"de-DE", MAX_WEIGHT},47{"de-Latn-DE-1996", MAX_WEIGHT},48{"zh-Hant-CN-x-private1-private2", MAX_WEIGHT},49{"ar", 0.8},50{"en-US", 0.5},51{"sr-Latn-BA", 0},52{"ja", 1},53};54}5556@DataProvider(name = "LRConstructorNPEData")57Object[][] LRConstructorNPEData() {58return new Object[][] {59// Range, Weight60{null, MAX_WEIGHT},61{null, 0.8},62};63}6465@DataProvider(name = "LRConstructorIAEData")66Object[][] LRConstructorIAEData() {67return new Object[][] {68// Range, Weight69{"ja", -0.8},70{"Elvish", 3.0},71{"-ja", MAX_WEIGHT},72{"ja--JP", MAX_WEIGHT},73{"en-US-", MAX_WEIGHT},74{"a4r", MAX_WEIGHT},75{"ar*", MAX_WEIGHT},76{"ar-*EG", MAX_WEIGHT},77{"abcdefghijklmn", MAX_WEIGHT},78{"ja-J=", MAX_WEIGHT},79{"ja-opqrstuvwxyz", MAX_WEIGHT},80{"zh_CN", MAX_WEIGHT},81{"1996-de-Latn", MAX_WEIGHT},82// Testcase for 804236083{"en-Latn-1234567890", MAX_WEIGHT},84};85}8687@DataProvider(name = "LRParseData")88Object[][] LRParseData() {89return new Object[][] {90// Ranges, Expected result91{"Accept-Language: fr-FX, de-DE;q=0.5, fr-tp-x-FOO;q=0.1, "92+ "en-X-tp;q=0.6, en-FR;q=0.7, de-de;q=0.8, iw;q=0.4, "93+ "he;q=0.4, de-de;q=0.5, ja, in-tpp, in-tp;q=0.2",94List.of(new LanguageRange("fr-fx", 1.0),95new LanguageRange("fr-fr", 1.0),96new LanguageRange("ja", 1.0),97new LanguageRange("in-tpp", 1.0),98new LanguageRange("id-tpp", 1.0),99new LanguageRange("en-fr", 0.7),100new LanguageRange("en-fx", 0.7),101new LanguageRange("en-x-tp", 0.6),102new LanguageRange("de-de", 0.5),103new LanguageRange("de-dd", 0.5),104new LanguageRange("iw", 0.4),105new LanguageRange("he", 0.4),106new LanguageRange("in-tp", 0.2),107new LanguageRange("id-tl", 0.2),108new LanguageRange("id-tp", 0.2),109new LanguageRange("in-tl", 0.2),110new LanguageRange("fr-tp-x-foo", 0.1),111new LanguageRange("fr-tl-x-foo", 0.1))},112{"Accept-Language: hak-CN;q=0.8, no-bok-NO;q=0.9, no-nyn, cmn-CN;q=0.1",113List.of(new LanguageRange("no-nyn", 1.0),114new LanguageRange("nn", 1.0),115new LanguageRange("no-bok-no", 0.9),116new LanguageRange("nb-no", 0.9),117new LanguageRange("hak-CN", 0.8),118new LanguageRange("zh-hakka-CN", 0.8),119new LanguageRange("i-hak-CN", 0.8),120new LanguageRange("zh-hak-CN", 0.8),121new LanguageRange("cmn-CN", 0.1),122new LanguageRange("zh-guoyu-CN", 0.1),123new LanguageRange("zh-cmn-CN", 0.1))},124{"Accept-Language: rki;q=0.4, no-bok-NO;q=0.9, ccq;q=0.5",125List.of(new LanguageRange("no-bok-no", 0.9),126new LanguageRange("nb-no", 0.9),127new LanguageRange("rki", 0.4),128new LanguageRange("ybd", 0.4),129new LanguageRange("ccq", 0.4))},130};131}132133@DataProvider(name = "LRParseIAEData")134Object[][] LRParseIAEData() {135return new Object[][] {136// Ranges137{""},138{"ja;q=3"},139};140}141142@DataProvider(name = "LRMapEquivalentsData")143Object[][] LRMapEquivalentsData() {144return new Object[][] {145// Ranges, Map, Expected result146{LanguageRange.parse("zh, zh-TW;q=0.8, ar;q=0.9, EN, zh-HK, ja-JP;q=0.2, es;q=0.4"),147new HashMap<>(),148LanguageRange.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"),150null,151LanguageRange.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"),153new LinkedHashMap<String, List<String>>() {154{155put("ja", List.of("ja", "ja-Hira"));156put("zh", List.of("zh-Hans", "zh-Hans-CN", "zh-CN"));157put("zh-TW", List.of("zh-TW", "zh-Hant"));158put("es", null);159put("en", List.of());160put("zh-HK", List.of("de"));161}162},163List.of(new LanguageRange("zh-hans", 1.0),164new LanguageRange("zh-hans-cn", 1.0),165new LanguageRange("zh-cn", 1.0),166new LanguageRange("de", 1.0),167new LanguageRange("ar", 0.9),168new LanguageRange("zh-tw", 0.8),169new LanguageRange("zh-hant", 0.8),170new LanguageRange("ja-jp", 0.2),171new LanguageRange("ja-hira-jp", 0.2))},172};173}174175@DataProvider(name = "LFilterData")176Object[][] LFilterData() {177return new Object[][] {178// Range, LanguageTags, FilteringMode, Expected locales179{"ja-JP, fr-FR", "de-DE, en, ja-JP-hepburn, fr, he, ja-Latn-JP",180EXTENDED_FILTERING, "ja-JP-hepburn, ja-Latn-JP"},181{"ja-*-JP, fr-FR", "de-DE, en, ja-JP-hepburn, fr, he, ja-Latn-JP",182EXTENDED_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",184AUTOSELECT_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",186AUTOSELECT_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",188IGNORE_EXTENDED_RANGES, "en"},189{"en;q=0.2, ja-*-JP, fr-JP", "de-DE, en, ja-JP-hepburn, fr, he, ja-Latn-JP",190MAP_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",192REJECT_EXTENDED_RANGES, "ja-JP-hepburn, en"},193{"en;q=0.2, ja-*-JP, fr-JP", "", REJECT_EXTENDED_RANGES, ""},194};195}196197@DataProvider(name = "LFilterNPEData")198Object[][] LFilterNPEData() {199return new Object[][] {200// Range, LanguageTags, FilteringMode201{"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}205206@DataProvider(name = "LFilterTagsData")207Object[][] LFilterTagsData() {208return new Object[][] {209// Range, LanguageTags, FilteringMode, Expected language tags210{"en;q=0.2, *;q=0.6, ja", "de-DE, en, ja-JP-hepburn, fr-JP, he",211null, "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",213null, "ja-JP-hepburn, en"},214{"en;q=0.2, ja-JP, fr-JP, iw", "de-DE, he, en, ja-JP-hepburn, fr, he-IL",215null, "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",217null, "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",220MAP_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",223EXTENDED_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",228EXTENDED_FILTERING,229"de-DE, de-Latn-DE, de-Latf-DE, de-DE-x-goethe, "230+ "de-Latn-DE-1996, de-Deva-DE"},231};232}233234@DataProvider(name = "LLookupData")235Object[][] LLookupData() {236return new Object[][] {237// Range, LanguageTags, Expected locale238{"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}243244@DataProvider(name = "LLookupTagData")245Object[][] LLookupTagData() {246return new Object[][] {247// Range, LanguageTags, Expected language tag248{"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}256257@Test258public void testLRConstants() {259assertEquals(MIN_WEIGHT, 0.0, " MIN_WEIGHT should be 0.0 but got "260+ MIN_WEIGHT);261assertEquals(MAX_WEIGHT, 1.0, " MAX_WEIGHT should be 1.0 but got "262+ MAX_WEIGHT);263}264265@Test(dataProvider = "LRConstructorData")266public void testLRConstructors(String range, double weight) {267LanguageRange lr;268if (weight == MAX_WEIGHT) {269lr = new LanguageRange(range);270} else {271lr = new LanguageRange(range, weight);272}273assertEquals(lr.getRange(), range.toLowerCase(Locale.ROOT),274" LR.getRange() returned unexpected value. Expected: "275+ range.toLowerCase(Locale.ROOT) + ", got: " + lr.getRange());276assertEquals(lr.getWeight(), weight,277" LR.getWeight() returned unexpected value. Expected: "278+ weight + ", got: " + lr.getWeight());279}280281@Test(dataProvider = "LRConstructorNPEData", expectedExceptions = NullPointerException.class)282public void testLRConstructorNPE(String range, double weight) {283if (weight == MAX_WEIGHT) {284new LanguageRange(range);285} else {286new LanguageRange(range, weight);287}288}289290@Test(dataProvider = "LRConstructorIAEData", expectedExceptions = IllegalArgumentException.class)291public void testLRConstructorIAE(String range, double weight) {292if (weight == MAX_WEIGHT) {293new LanguageRange(range);294} else {295new LanguageRange(range, weight);296}297}298299@Test300public void testLREquals() {301LanguageRange lr1 = new LanguageRange("ja", 1.0);302LanguageRange lr2 = new LanguageRange("ja");303LanguageRange lr3 = new LanguageRange("ja", 0.1);304LanguageRange lr4 = new LanguageRange("en", 1.0);305306assertEquals(lr1, lr2, " LR(ja, 1.0).equals(LR(ja)) should return true.");307assertNotEquals(lr1, lr3, " LR(ja, 1.0).equals(LR(ja, 0.1)) should return false.");308assertNotEquals(lr1, lr4, " LR(ja, 1.0).equals(LR(en, 1.0)) should return false.");309assertNotNull(lr1, " LR(ja, 1.0).equals(null) should return false.");310assertNotEquals(lr1, "", " LR(ja, 1.0).equals(\"\") should return false.");311}312313@Test(dataProvider = "LRParseData")314public void testLRParse(String ranges, List<LanguageRange> expected) {315assertEquals(LanguageRange.parse(ranges), expected,316" LR.parse(" + ranges + ") test failed.");317}318319@Test(expectedExceptions = NullPointerException.class)320public void testLRParseNPE() {321LanguageRange.parse(null);322}323324@Test(dataProvider = "LRParseIAEData", expectedExceptions = IllegalArgumentException.class)325public void testLRParseIAE(String ranges) {326LanguageRange.parse(ranges);327}328329@Test(dataProvider = "LRMapEquivalentsData")330public void testLRMapEquivalents(List<Locale.LanguageRange> priorityList,331Map<String,List<String>> map, List<LanguageRange> expected) {332assertEquals(LanguageRange.mapEquivalents(priorityList, map), expected,333" LR.mapEquivalents() test failed.");334}335336@Test(expectedExceptions = NullPointerException.class)337public void testLRMapEquivalentsNPE() {338LanguageRange.mapEquivalents(null, Map.of("ja", List.of("ja", "ja-Hira")));339}340341@Test(dataProvider = "LFilterData")342public void testLFilter(String ranges, String tags, FilteringMode mode, String expectedLocales) {343List<LanguageRange> priorityList = LanguageRange.parse(ranges);344List<Locale> tagList = generateLocales(tags);345String actualLocales =346showLocales(Locale.filter(priorityList, tagList, mode));347assertEquals(actualLocales, expectedLocales, showErrorMessage(" L.Filter(" + mode + ")",348ranges, tags, expectedLocales, actualLocales));349}350351@Test(dataProvider = "LFilterNPEData", expectedExceptions = NullPointerException.class)352public void testLFilterNPE(String ranges, String tags, FilteringMode mode) {353List<LanguageRange> priorityList = LanguageRange.parse(ranges);354List<Locale> tagList = generateLocales(tags);355showLocales(Locale.filter(priorityList, tagList, mode));356}357358@Test(expectedExceptions = IllegalArgumentException.class)359public void testLFilterIAE() {360String ranges = "en;q=0.2, ja-*-JP, fr-JP";361String tags = "de-DE, en, ja-JP-hepburn, fr, he, ja-Latn-JP";362List<LanguageRange> priorityList = LanguageRange.parse(ranges);363List<Locale> tagList = generateLocales(tags);364showLocales(Locale.filter(priorityList, tagList, REJECT_EXTENDED_RANGES));365}366367@Test(dataProvider = "LFilterTagsData")368public void testLFilterTags(String ranges, String tags, FilteringMode mode, String expectedTags) {369List<LanguageRange> priorityList = LanguageRange.parse(ranges);370List<String> tagList = generateLanguageTags(tags);371String actualTags;372if (mode == null) {373actualTags = showLanguageTags(Locale.filterTags(priorityList, tagList));374} else {375actualTags = showLanguageTags(Locale.filterTags(priorityList, tagList, mode));376}377assertEquals(actualTags, expectedTags,378showErrorMessage(" L.FilterTags(" + (mode != null ? mode : "") + ")",379ranges, tags, expectedTags, actualTags));380}381382@Test(dataProvider = "LLookupData")383public void testLLookup(String ranges, String tags, String expectedLocale) {384List<LanguageRange> priorityList = LanguageRange.parse(ranges);385List<Locale> localeList = generateLocales(tags);386String actualLocale =387Locale.lookup(priorityList, localeList).toLanguageTag();388assertEquals(actualLocale, expectedLocale, showErrorMessage(" L.Lookup()",389ranges, tags, expectedLocale, actualLocale));390}391392@Test(dataProvider = "LLookupTagData")393public void testLLookupTag(String ranges, String tags, String expectedTag) {394List<LanguageRange> priorityList = LanguageRange.parse(ranges);395List<String> tagList = generateLanguageTags(tags);396String actualTag = Locale.lookupTag(priorityList, tagList);397assertEquals(actualTag, expectedTag, showErrorMessage(" L.LookupTag()",398ranges, tags, expectedTag, actualTag));399}400401private static List<Locale> generateLocales(String tags) {402if (tags == null) {403return null;404}405406List<Locale> localeList = new ArrayList<>();407if (tags.equals("")) {408return localeList;409}410String[] t = tags.split(", ");411for (String tag : t) {412localeList.add(Locale.forLanguageTag(tag));413}414return localeList;415}416417private static List<String> generateLanguageTags(String tags) {418List<String> tagList = new ArrayList<>();419String[] t = tags.split(", ");420for (String tag : t) {421tagList.add(tag);422}423return tagList;424}425426private static String showLanguageTags(List<String> tags) {427StringBuilder sb = new StringBuilder();428429Iterator<String> itr = tags.iterator();430if (itr.hasNext()) {431sb.append(itr.next());432}433while (itr.hasNext()) {434sb.append(", ");435sb.append(itr.next());436}437438return sb.toString().trim();439}440441private static String showLocales(List<Locale> locales) {442StringBuilder sb = new StringBuilder();443444Iterator<Locale> itr = locales.iterator();445if (itr.hasNext()) {446sb.append(itr.next().toLanguageTag());447}448while (itr.hasNext()) {449sb.append(", ");450sb.append(itr.next().toLanguageTag());451}452453return sb.toString().trim();454}455456private static String showErrorMessage(String methodName,457String priorityList,458String tags,459String expectedTags,460String actualTags) {461return "Incorrect " + methodName + " result."462+ " Priority list : " + priorityList463+ " Language tags : " + tags464+ " Expected value : " + expectedTags465+ " Actual value : " + actualTags;466}467}468469470