17935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 27935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ****************************************************************************************** 36775e829ec5126cec90e6dff9751cf16739a2b09ccornelius * Copyright (C) 2009-2015, Google, Inc.; International Business Machines Corporation and * 47935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * others. All Rights Reserved. * 57935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ****************************************************************************************** 67935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 77935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 87935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertpackage com.ibm.icu.dev.test.util; 97935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.Set; 117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.TreeSet; 127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.dev.test.TestFmwk; 147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.LocaleMatcher; 157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.LocaleMatcher.LanguageMatcherData; 167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.LocalePriorityList; 177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.ULocale; 187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/** 20bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * Test the LocaleMatcher. 217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @author markdavis 237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 24bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert@SuppressWarnings("deprecation") 257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertpublic class LocaleMatcherTest extends TestFmwk { 267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 27bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 28bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private static final ULocale ZH_MO = new ULocale("zh_MO"); 29bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private static final ULocale ZH_HK = new ULocale("zh_HK"); 30bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert static LanguageMatcherData LANGUAGE_MATCHER_DATA = LocaleMatcherShim.load(); 31bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 32bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private LocaleMatcher newLocaleMatcher(LocalePriorityList build) { 33bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert return new LocaleMatcher(build, LANGUAGE_MATCHER_DATA); 34bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 35bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 36bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private LocaleMatcher newLocaleMatcher(LocalePriorityList build, LanguageMatcherData data) { 37bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert return new LocaleMatcher(build, data == null ? LANGUAGE_MATCHER_DATA : data); 38bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 39bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 40bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private LocaleMatcher newLocaleMatcher(LocalePriorityList lpl, LanguageMatcherData data, double d) { 41bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert return new LocaleMatcher(lpl, data == null ? LANGUAGE_MATCHER_DATA : data, d); 42bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 43bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 44bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private LocaleMatcher newLocaleMatcher(String string) { 45bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert return new LocaleMatcher(LocalePriorityList.add(string).build(), LANGUAGE_MATCHER_DATA); 46bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 47bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 48bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // public LocaleMatcher(LocalePriorityList languagePriorityList, 49bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // LocaleMatcherData matcherData, double threshold) 50bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static void main(String[] args) throws Exception { 527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert new LocaleMatcherTest().run(args); 537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 55bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert public void testParentLocales() { 56bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert assertCloser("es_AR", "es_419", "es_ES"); 57bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert assertCloser("es_AR", "es_419", "es"); 58bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 59bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert assertCloser("es_AR", "es_MX", "es"); 60bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert assertCloser("es_AR", "es_MX", "es"); 61bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 62bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert assertCloser("en_AU", "en_GB", "en_US"); 63bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert assertCloser("en_AU", "en_GB", "en"); 64bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 65bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert assertCloser("en_AU", "en_NZ", "en_US"); 66bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert assertCloser("en_AU", "en_NZ", "en"); 67bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 68bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert assertCloser("pt_AO", "pt_PT", "pt_BR"); 69bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert assertCloser("pt_AO", "pt_PT", "pt"); 70bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 71bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert assertCloser("zh_HK", "zh_MO", "zh_TW"); 72bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert assertCloser("zh_HK", "zh_MO", "zh_CN"); 73bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert assertCloser("zh_HK", "zh_MO", "zh"); 74bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 75bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 76bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private void assertCloser(String a, String closer, String further) { 77bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert LocaleMatcher matcher = newLocaleMatcher(further + ", " + closer); 78bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert assertEquals("test " + a + " is closer to " + closer + " than to " + further, new ULocale(closer), matcher.getBestMatch(a)); 79bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert matcher = newLocaleMatcher(closer + ", " + further); 80bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert assertEquals("test " + a + " is closer to " + closer + " than to " + further, new ULocale(closer), matcher.getBestMatch(a)); 81bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 82bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 83bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // public void testParentLocales() { 84bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // // find all the regions that have a closer relation because of an explicit parent 85bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // Set<String> explicitParents = new HashSet<>(INFO.getExplicitParents()); 86bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // explicitParents.remove("root"); 87bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // Set<String> otherParents = new HashSet<>(INFO.getExplicitParents()); 88bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // for (String locale : explicitParents) { 89bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // while (true) { 90bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // locale = LocaleIDParser.getParent(locale); 91bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // if (locale == null || locale.equals("root")) { 92bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // break; 93bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // } 94bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // otherParents.add(locale); 95bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // } 96bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // } 97bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // otherParents.remove("root"); 98bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // 99bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // for (String locale : CONFIG.getCldrFactory().getAvailable()) { 100bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // String parentId = LocaleIDParser.getParent(locale); 101bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // String parentIdSimple = LocaleIDParser.getSimpleParent(locale); 102bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // if (!explicitParents.contains(parentId) && !otherParents.contains(parentIdSimple)) { 103bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // continue; 104bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // } 105bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // System.out.println(locale + "\t" + CONFIG.getEnglish().getName(locale) + "\t" + parentId + "\t" + parentIdSimple); 106bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // } 107bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // } 108bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 1097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void testChinese() { 110bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert LocaleMatcher matcher = newLocaleMatcher("zh_CN, zh_TW, iw"); 1117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ULocale taiwanChinese = new ULocale("zh_TW"); 1127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ULocale chinaChinese = new ULocale("zh_CN"); 1137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals("zh_CN, zh_TW, iw;", taiwanChinese, matcher.getBestMatch("zh_Hant_TW")); 1147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals("zh_CN, zh_TW, iw;", taiwanChinese, matcher.getBestMatch("zh_Hant")); 1157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals("zh_CN, zh_TW, iw;", taiwanChinese, matcher.getBestMatch("zh_TW")); 1167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals("zh_CN, zh_TW, iw;", chinaChinese, matcher.getBestMatch("zh_Hans_CN")); 1177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals("zh_CN, zh_TW, iw;", chinaChinese, matcher.getBestMatch("zh_CN")); 1187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals("zh_CN, zh_TW, iw;", chinaChinese, matcher.getBestMatch("zh")); 1197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals("zh_CN, zh_TW, iw;", taiwanChinese, matcher.getBestMatch("zh_Hant_HK")); 1207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void testenGB() { 123bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert final LocaleMatcher matcher = newLocaleMatcher("fr, en, en_GB, es_MX, es_419, es"); 1247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals("en_GB", matcher.getBestMatch("en_NZ").toString()); 1257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals("es", matcher.getBestMatch("es_ES").toString()); 1267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals("es_419", matcher.getBestMatch("es_AR").toString()); 1277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals("es_MX", matcher.getBestMatch("es_MX").toString()); 1287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void testFallbacks() { 1317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert LocalePriorityList lpl = LocalePriorityList.add("en, hi").build(); 132bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert final LocaleMatcher matcher = newLocaleMatcher(lpl, null, 0.09); 1337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals("hi", matcher.getBestMatch("sa").toString()); 1347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void testOverrideData() { 1377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert double threshold = 0.05; 1387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert LanguageMatcherData localeMatcherData = new LanguageMatcherData() 1397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert .addDistance("br", "fr", 10, true) 140bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert .addDistance("es", "cy", 10, true); 1417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert logln(localeMatcherData.toString()); 1427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 143bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert final LocaleMatcher matcher = newLocaleMatcher( 144bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert LocalePriorityList 145bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert .add(ULocale.ENGLISH) 146bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert .add(ULocale.FRENCH) 147bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert .add(ULocale.UK) 148bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert .build(), localeMatcherData, threshold); 1497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert logln(matcher.toString()); 1507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals(ULocale.FRENCH, matcher.getBestMatch(new ULocale("br"))); 152bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert assertEquals(ULocale.ENGLISH, matcher.getBestMatch(new ULocale("es"))); // one 153bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // way 1547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void testBasics() { 157bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert final LocaleMatcher matcher = newLocaleMatcher(LocalePriorityList.add(ULocale.FRENCH).add(ULocale.UK) 158bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert .add(ULocale.ENGLISH).build()); 1597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert logln(matcher.toString()); 1607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals(ULocale.UK, matcher.getBestMatch(ULocale.UK)); 1627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals(ULocale.ENGLISH, matcher.getBestMatch(ULocale.US)); 1637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals(ULocale.FRENCH, matcher.getBestMatch(ULocale.FRANCE)); 1647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals(ULocale.FRENCH, matcher.getBestMatch(ULocale.JAPAN)); 1657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void testFallback() { 1687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // check that script fallbacks are handled right 169bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert final LocaleMatcher matcher = newLocaleMatcher("zh_CN, zh_TW, iw"); 1707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals(new ULocale("zh_TW"), matcher.getBestMatch("zh_Hant")); 1717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals(new ULocale("zh_CN"), matcher.getBestMatch("zh")); 1727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals(new ULocale("zh_CN"), matcher.getBestMatch("zh_Hans_CN")); 1737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals(new ULocale("zh_TW"), matcher.getBestMatch("zh_Hant_HK")); 1747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals(new ULocale("he"), matcher.getBestMatch("iw_IT")); 1757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void testSpecials() { 1787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // check that nearby languages are handled 179bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert final LocaleMatcher matcher = newLocaleMatcher("en, fil, ro, nn"); 1807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals(new ULocale("fil"), matcher.getBestMatch("tl")); 1817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals(new ULocale("ro"), matcher.getBestMatch("mo")); 182bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert assertEquals(new ULocale("nn"), matcher.getBestMatch("nb")); 1837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // make sure default works 1847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals(new ULocale("en"), matcher.getBestMatch("ja")); 1857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void testRegionalSpecials() { 1887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // verify that en_AU is closer to en_GB than to en (which is en_US) 189bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert final LocaleMatcher matcher = newLocaleMatcher("en, en_GB, es, es_419"); 1907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals("es_MX in {en, en_GB, es, es_419}", new ULocale("es_419"), matcher.getBestMatch("es_MX")); 191bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert assertEquals("en_AU in {en, en_GB, es, es_419}", new ULocale("en_GB"), matcher.getBestMatch("en_AU")); 1927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals("es_ES in {en, en_GB, es, es_419}", new ULocale("es"), matcher.getBestMatch("es_ES")); 1937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 195bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert public void testHK() { 196bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // HK and MO are closer to each other for Hant than to TW 197bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert final LocaleMatcher matcher = newLocaleMatcher("zh, zh_TW, zh_MO"); 198bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert assertEquals("zh_HK in {zh, zh_TW, zh_MO}", ZH_MO, matcher.getBestMatch("zh_HK")); 199bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert final LocaleMatcher matcher2 = newLocaleMatcher("zh, zh_TW, zh_HK"); 200bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert assertEquals("zh_MO in {zh, zh_TW, zh_HK}", ZH_HK, matcher2.getBestMatch("zh_MO")); 201bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 202bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 2037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void TestLocaleMatcherCoverage() { 2047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Add tests for better code coverage 205bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert LocaleMatcher matcher = newLocaleMatcher(LocalePriorityList.add(null, 0).build(), null); 2067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert logln(matcher.toString()); 2077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert LanguageMatcherData data = new LanguageMatcherData(); 2097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert LanguageMatcherData clone = data.cloneAsThawed(); 2117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (clone.equals(data)) { 2137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert errln("Error cloneAsThawed() is equal."); 2147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (data.isFrozen()) { 217bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert errln("Error LocaleMatcherData is frozen!"); 2187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private void assertEquals(Object expected, Object string) { 2227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals("", expected, string); 2237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 224bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 2257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private void assertNull(Object bestMatch) { 2267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertNull("", bestMatch); 2277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void testEmpty() { 230bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert final LocaleMatcher matcher = newLocaleMatcher(""); 2317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertNull(matcher.getBestMatch(ULocale.FRENCH)); 2327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert static final ULocale ENGLISH_CANADA = new ULocale("en_CA"); 2357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void testMatch_exact() { 2377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals(1.0, 238bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert LocaleMatcher.match(ENGLISH_CANADA, ENGLISH_CANADA)); 2397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void testMatch_none() { 2427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert double match = LocaleMatcher.match( 243bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert new ULocale("ar_MK"), 244bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert ENGLISH_CANADA); 2457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertTrue("Actual < 0: " + match, 0 <= match); 2467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertTrue("Actual > 0.15 (~ language + script distance): " + match, 0.2 > match); 2477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void testMatch_matchOnMazimized() { 2507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ULocale undTw = new ULocale("und_TW"); 2517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ULocale zhHant = new ULocale("zh_Hant"); 2527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert double matchZh = LocaleMatcher.match(undTw, new ULocale("zh")); 2537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert double matchZhHant = LocaleMatcher.match(undTw, zhHant); 2547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertTrue("und_TW should be closer to zh_Hant (" + matchZhHant + 255bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert ") than to zh (" + matchZh + ")", 256bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert matchZh < matchZhHant); 2577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert double matchEnHantTw = LocaleMatcher.match(new ULocale("en_Hant_TW"), 258bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert zhHant); 2597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertTrue("zh_Hant should be closer to und_TW (" + matchZhHant + 260bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert ") than to en_Hant_TW (" + matchEnHantTw + ")", 261bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert matchEnHantTw < matchZhHant); 2627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertTrue("zh should be closer to und_TW (" + matchZh + 263bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert ") than to en_Hant_TW (" + matchEnHantTw + ")", 264bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert matchEnHantTw < matchZh); 2657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void testMatchGrandfatheredCode() { 268bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert final LocaleMatcher matcher = newLocaleMatcher("fr, i_klingon, en_Latn_US"); 2697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals("en_Latn_US", matcher.getBestMatch("en_GB_oed").toString()); 270bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // assertEquals("tlh", matcher.getBestMatch("i_klingon").toString()); 2717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void testGetBestMatchForList_exactMatch() { 274bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert final LocaleMatcher matcher = newLocaleMatcher("fr, en_GB, ja, es_ES, es_MX"); 2757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals("ja", matcher.getBestMatch("ja, de").toString()); 2767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void testGetBestMatchForList_simpleVariantMatch() { 279bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert final LocaleMatcher matcher = newLocaleMatcher("fr, en_GB, ja, es_ES, es_MX"); 280bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // Intentionally avoiding a perfect_match or two candidates for variant 281bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // matches. 2827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals("en_GB", matcher.getBestMatch("de, en_US").toString()); 2837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Fall back. 2847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals("fr", matcher.getBestMatch("de, zh").toString()); 2857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void testGetBestMatchForList_matchOnMaximized() { 288bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert final LocaleMatcher matcher = newLocaleMatcher("en, ja"); 289bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // final LocaleMatcher matcher = 290bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // newLocaleMatcher("fr, en, ja, es_ES, es_MX"); 2917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Check that if the preference is maximized already, it works as well. 2927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals("Match for ja_Jpan_JP (maximized already)", 293bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert "ja", matcher.getBestMatch("ja_Jpan_JP, en-AU").toString()); 294bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (true) 295bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert return; 296bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // ja_JP matches ja on likely subtags, and it's listed first, thus it 297bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // wins over 2987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // thus it wins over the second preference en_GB. 2997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals("Match for ja_JP, with likely region subtag", 300bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert "ja", matcher.getBestMatch("ja_JP, en_US").toString()); 3017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Check that if the preference is maximized already, it works as well. 3027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals("Match for ja_Jpan_JP (maximized already)", 303bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert "ja", matcher.getBestMatch("ja_Jpan_JP, en_US").toString()); 3047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void testGetBestMatchForList_noMatchOnMaximized() { 3077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Regression test for http://b/5714572 . 308bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert final LocaleMatcher matcher = newLocaleMatcher("en, de, fr, ja"); 309bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // de maximizes to de_DE. Pick the exact match for the secondary 310bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // language instead. 311bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert assertEquals("de", matcher.getBestMatch("de_CH, fr").toString()); 3127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void testBestMatchForTraditionalChinese() { 315bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // Scenario: An application that only supports Simplified Chinese (and 316bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // some other languages), 317bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // but does not support Traditional Chinese. zh_Hans_CN could be 318bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // replaced with zh_CN, zh, or 3197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // zh_Hans, it wouldn't make much of a difference. 320bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert final LocaleMatcher matcher = newLocaleMatcher("fr, zh_Hans_CN, en_US"); 3217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 322bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // The script distance (simplified vs. traditional Han) is considered 323bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // small enough 324bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // to be an acceptable match. The regional difference is considered 325bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // almost insignificant. 3267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals("zh_Hans_CN", matcher.getBestMatch("zh_TW").toString()); 3277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals("zh_Hans_CN", matcher.getBestMatch("zh_Hant").toString()); 3287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 329bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // For geo_political reasons, you might want to avoid a zh_Hant -> 330bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // zh_Hans match. 331bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // In this case, if zh_TW, zh_HK or a tag starting with zh_Hant is 332bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // requested, you can 333bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // change your call to getBestMatch to include a 2nd language 334bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // preference. 335bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // "en" is a better match since its distance to "en_US" is closer than 336bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // the distance 3377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // from "zh_TW" to "zh_CN" (script distance). 3387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals("en_US", matcher.getBestMatch("zh_TW, en").toString()); 3397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals("en_US", matcher.getBestMatch("zh_Hant_CN, en").toString()); 3407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals("zh_Hans_CN", matcher.getBestMatch("zh_Hans, en").toString()); 3417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void testUndefined() { 344bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // When the undefined language doesn't match anything in the list, 345bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // getBestMatch returns 3467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // the default, as usual. 347bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert LocaleMatcher matcher = newLocaleMatcher("it,fr"); 3487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals("it", matcher.getBestMatch("und").toString()); 3497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // When it *does* occur in the list, BestMatch returns it, as expected. 351bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert matcher = newLocaleMatcher("it,und"); 3527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals("und", matcher.getBestMatch("und").toString()); 3537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // The unusual part: 355bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // max("und") = "en_Latn_US", and since matching is based on maximized 356bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // tags, the undefined 357bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // language would normally match English. But that would produce the 358bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // counterintuitive results 3597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // that getBestMatch("und", LocaleMatcher("it,en")) would be "en", and 3607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // getBestMatch("en", LocaleMatcher("it,und")) would be "und". 3617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // 362bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // To avoid that, we change the matcher's definitions of max 363bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // (AddLikelySubtagsWithDefaults) 364bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // so that max("und")="und". That produces the following, more desirable 365bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // results: 366bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert matcher = newLocaleMatcher("it,en"); 3677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals("it", matcher.getBestMatch("und").toString()); 368bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert matcher = newLocaleMatcher("it,und"); 3697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals("it", matcher.getBestMatch("en").toString()); 3707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 372bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // public void testGetBestMatch_emptyList() { 373bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // final LocaleMatcher matcher = newLocaleMatcher( 374bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // new LocalePriorityList(new HashMap())); 375bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // assertNull(matcher.getBestMatch(ULocale.ENGLISH)); 376bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // } 3777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void testGetBestMatch_googlePseudoLocales() { 3797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Google pseudo locales are primarily based on variant subtags. 3807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // See http://sites/intl_eng/pseudo_locales. 3817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // (See below for the region code based fall back options.) 382bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert final LocaleMatcher matcher = newLocaleMatcher( 383bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert "fr, pt"); 3847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals("fr", matcher.getBestMatch("de").toString()); 3857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals("fr", matcher.getBestMatch("en_US").toString()); 3867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals("fr", matcher.getBestMatch("en").toString()); 3877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals("pt", matcher.getBestMatch("pt_BR").toString()); 3887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void testGetBestMatch_regionDistance() { 391bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert LocaleMatcher matcher = newLocaleMatcher("es_AR, es"); 3927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals("es_AR", matcher.getBestMatch("es_MX").toString()); 3937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 394bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert matcher = newLocaleMatcher("fr, en, en_GB"); 3956775e829ec5126cec90e6dff9751cf16739a2b09ccornelius assertEquals("en_GB", matcher.getBestMatch("en_CA").toString()); 3967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 397bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert matcher = newLocaleMatcher("de_AT, de_DE, de_CH"); 3987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals("de_DE", matcher.getBestMatch("de").toString()); 399bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 4006775e829ec5126cec90e6dff9751cf16739a2b09ccornelius showDistance(matcher, "en", "en_CA"); 4016775e829ec5126cec90e6dff9751cf16739a2b09ccornelius showDistance(matcher, "en_CA", "en"); 4026775e829ec5126cec90e6dff9751cf16739a2b09ccornelius showDistance(matcher, "en_US", "en_CA"); 4036775e829ec5126cec90e6dff9751cf16739a2b09ccornelius showDistance(matcher, "en_CA", "en_US"); 4046775e829ec5126cec90e6dff9751cf16739a2b09ccornelius showDistance(matcher, "en_GB", "en_CA"); 4056775e829ec5126cec90e6dff9751cf16739a2b09ccornelius showDistance(matcher, "en_CA", "en_GB"); 4066775e829ec5126cec90e6dff9751cf16739a2b09ccornelius showDistance(matcher, "en", "en_UM"); 4076775e829ec5126cec90e6dff9751cf16739a2b09ccornelius showDistance(matcher, "en_UM", "en"); 4087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 409bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 4106775e829ec5126cec90e6dff9751cf16739a2b09ccornelius private void showDistance(LocaleMatcher matcher, String desired, String supported) { 4116775e829ec5126cec90e6dff9751cf16739a2b09ccornelius ULocale desired2 = new ULocale(desired); 4126775e829ec5126cec90e6dff9751cf16739a2b09ccornelius ULocale supported2 = new ULocale(supported); 4136775e829ec5126cec90e6dff9751cf16739a2b09ccornelius double distance = matcher.match(desired2, ULocale.addLikelySubtags(desired2), supported2, ULocale.addLikelySubtags(supported2)); 4146775e829ec5126cec90e6dff9751cf16739a2b09ccornelius logln(desired + " to " + supported + " :\t" + distance); 4156775e829ec5126cec90e6dff9751cf16739a2b09ccornelius } 4166775e829ec5126cec90e6dff9751cf16739a2b09ccornelius 4177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 418bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * If all the base languages are the same, then each sublocale matches 419bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * itself most closely 4207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 4217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void testExactMatches() { 4227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String lastBase = ""; 423bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert TreeSet<ULocale> sorted = new TreeSet<ULocale>(); 4247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (ULocale loc : ULocale.getAvailableLocales()) { 4257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String language = loc.getLanguage(); 4267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (!lastBase.equals(language)) { 4277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert check(sorted); 4287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert sorted.clear(); 4297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert lastBase = language; 4307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert sorted.add(loc); 4327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert check(sorted); 4347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private void check(Set<ULocale> sorted) { 4377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (sorted.isEmpty()) { 4387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return; 4397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert check2(sorted); 4417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ULocale first = sorted.iterator().next(); 4427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ULocale max = ULocale.addLikelySubtags(first); 4437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert sorted.add(max); 4447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert check2(sorted); 4457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 446bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 4477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 4487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param sorted 4497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 4507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private void check2(Set<ULocale> sorted) { 4517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // TODO Auto-generated method stub 4527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert logln("Checking: " + sorted); 453bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert LocaleMatcher matcher = newLocaleMatcher( 454bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert LocalePriorityList.add( 455bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert sorted.toArray(new ULocale[sorted.size()])) 456bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert .build()); 4577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (ULocale loc : sorted) { 4587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String stringLoc = loc.toString(); 4597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert assertEquals(stringLoc, matcher.getBestMatch(stringLoc).toString()); 4607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4636775e829ec5126cec90e6dff9751cf16739a2b09ccornelius public void testAsymmetry() { 4646775e829ec5126cec90e6dff9751cf16739a2b09ccornelius LocaleMatcher matcher; 4656775e829ec5126cec90e6dff9751cf16739a2b09ccornelius matcher = new LocaleMatcher("mul, nl"); 4666775e829ec5126cec90e6dff9751cf16739a2b09ccornelius assertEquals("nl", matcher.getBestMatch("af").toString()); // af => nl 4676775e829ec5126cec90e6dff9751cf16739a2b09ccornelius 4686775e829ec5126cec90e6dff9751cf16739a2b09ccornelius matcher = new LocaleMatcher("mul, af"); 4696775e829ec5126cec90e6dff9751cf16739a2b09ccornelius assertEquals("mul", matcher.getBestMatch("nl").toString()); // but nl !=> af 4706775e829ec5126cec90e6dff9751cf16739a2b09ccornelius } 4716775e829ec5126cec90e6dff9751cf16739a2b09ccornelius 4727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 473bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // public void testComputeDistance_monkeyTest() { 474bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // RegionCode[] codes = RegionCode.values(); 475bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // Random random = new Random(); 476bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // for (int i = 0; i < 1000; ++i) { 477bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // RegionCode x = codes[random.nextInt(codes.length)]; 478bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // RegionCode y = codes[random.nextInt(codes.length)]; 479bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // double d = LocaleMatcher.getRegionDistance(x, y, null, null); 480bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // if (x == RegionCode.ZZ || y == RegionCode.ZZ) { 481bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // assertEquals(LocaleMatcher.REGION_DISTANCE, d); 482bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // } else if (x == y) { 483bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // assertEquals(0.0, d); 484bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // } else { 485bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // assertTrue(d > 0); 486bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // assertTrue(d <= LocaleMatcher.REGION_DISTANCE); 487bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // } 488bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // } 489bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // } 490bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 491bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert public void testGetBestMatchForList_matchOnMaximized2() { 492bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert// if (logKnownIssue("Cldrbug:8811", "Problems with LocaleMatcher test")) { 493bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert// return; 494bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert// } 495bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert final LocaleMatcher matcher = newLocaleMatcher("fr, en-GB, ja, es-ES, es-MX"); 496bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // ja-JP matches ja on likely subtags, and it's listed first, thus it wins over 497bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // thus it wins over the second preference en-GB. 498bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert assertEquals("Match for ja-JP, with likely region subtag", 499bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert "ja", matcher.getBestMatch("ja-JP, en-GB").toString()); 500bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // Check that if the preference is maximized already, it works as well. 501bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert assertEquals("Match for ja-Jpan-JP (maximized already)", 502bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert "ja", matcher.getBestMatch("ja-Jpan-JP, en-GB").toString()); 503bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 504bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 505bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert public void testGetBestMatchForList_closeEnoughMatchOnMaximized() { 506bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert// if (logKnownIssue("Cldrbug:8811", "Problems with LocaleMatcher test")) { 507bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert// return; 508bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert// } 509bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert final LocaleMatcher matcher = newLocaleMatcher("en-GB, en, de, fr, ja"); 510bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert assertEquals("de", matcher.getBestMatch("de-CH, fr").toString()); 511bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert assertEquals("en", matcher.getBestMatch("en-US, ar, nl, de, ja").toString()); 512bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 513bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 514bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert public void testGetBestMatchForPortuguese() { 515bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 516bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert// if (logKnownIssue("Cldrbug:8811", "Problems with LocaleMatcher test")) { 517bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert// return; 518bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert// } 519bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 520bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert final LocaleMatcher withPTExplicit = newLocaleMatcher("pt_PT, pt_BR, es, es_419"); 521bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert final LocaleMatcher withPTImplicit = newLocaleMatcher("pt_PT, pt, es, es_419"); 522bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // Could happen because "pt_BR" is a tier_1 language and "pt_PT" is tier_2. 523bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 524bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert final LocaleMatcher withoutPT = newLocaleMatcher("pt_BR, es, es_419"); 525bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // European user who prefers Spanish over Brazillian Portuguese as a fallback. 526bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 527bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert assertEquals("pt_PT", withPTExplicit.getBestMatch("pt_PT, es, pt").toString()); 528bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert assertEquals("pt_PT", withPTImplicit.getBestMatch("pt_PT, es, pt").toString()); 529bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert assertEquals("es", withoutPT.getBestMatch("pt_PT, es, pt").toString()); 530bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 531bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // Brazillian user who prefers South American Spanish over European Portuguese as a fallback. 532bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // The asymmetry between this case and above is because it's "pt_PT" that's missing between the 533bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // matchers as "pt_BR" is a much more common language. 534bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert assertEquals("pt_BR", withPTExplicit.getBestMatch("pt, es_419, pt_PT").toString()); 535bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert assertEquals("pt", withPTImplicit.getBestMatch("pt, es_419, pt_PT").toString()); 536bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert assertEquals("pt_BR", withoutPT.getBestMatch("pt, es_419, pt_PT").toString()); 537bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 538bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // Code that adds the user's country can get "pt_US" for a user's language. 539bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // That should fall back to "pt_BR". 540bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert assertEquals("pt_BR", withPTExplicit.getBestMatch("pt_US, pt_PT").toString()); 541bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert assertEquals("pt", withPTImplicit.getBestMatch("pt_US, pt_PT").toString()); 542bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 543bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 544bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert public void testVariantWithScriptMatch() { 545bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert// if (logKnownIssue("Cldrbug:8811", "Problems with LocaleMatcher test")) { 546bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert// return; 547bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert// } 548bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert final LocaleMatcher matcher = newLocaleMatcher("fr, en, sv"); 549bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert assertEquals("en", matcher.getBestMatch("en-GB").toString()); 550bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert assertEquals("en", matcher.getBestMatch("en-GB, sv").toString()); 551bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 552bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 553bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert public void testVariantWithScriptMatch2() { 554bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert// if (logKnownIssue("Cldrbug:8811", "Problems with LocaleMatcher test")) { 555bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert// return; 556bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert// } 557bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert final LocaleMatcher matcher = newLocaleMatcher("en, sv"); 558bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert assertEquals("en", matcher.getBestMatch("en-GB, sv").toString()); 559bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 560bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 561bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert public void testPerf() { 562bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (LANGUAGE_MATCHER_DATA == null) { 563bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert return; // skip except when testing data 564bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 565bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert final String desired = "sv, en"; 566bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 567bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert final LocaleMatcher matcherShort = newLocaleMatcher(desired); 568bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert final LocaleMatcher matcherLong = newLocaleMatcher("af, am, ar, az, be, bg, bn, bs, ca, cs, cy, cy, da, de, el, en, en-GB, es, es-419, et, eu, fa, fi, fil, fr, ga, gl, gu, hi, hr, hu, hy, id, is, it, iw, ja, ka, kk, km, kn, ko, ky, lo, lt, lv, mk, ml, mn, mr, ms, my, ne, nl, no, pa, pl, pt, pt-PT, ro, ru, si, sk, sl, sq, sr, sr-Latn, sv, sw, ta, te, th, tr, uk, ur, uz, vi, zh-CN, zh-TW, zu"); 569bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert final LocaleMatcher matcherVeryLong = newLocaleMatcher("af, af_NA, af_ZA, agq, agq_CM, ak, ak_GH, am, am_ET, ar, ar_001, ar_AE, ar_BH, ar_DJ, ar_DZ, ar_EG, ar_EH, ar_ER, ar_IL, ar_IQ, ar_JO, ar_KM, ar_KW, ar_LB, ar_LY, ar_MA, ar_MR, ar_OM, ar_PS, ar_QA, ar_SA, ar_SD, ar_SO, ar_SS, ar_SY, ar_TD, ar_TN, ar_YE, as, as_IN, asa, asa_TZ, ast, ast_ES, az, az_Cyrl, az_Cyrl_AZ, az_Latn, az_Latn_AZ, bas, bas_CM, be, be_BY, bem, bem_ZM, bez, bez_TZ, bg, bg_BG, bm, bm_ML, bn, bn_BD, bn_IN, bo, bo_CN, bo_IN, br, br_FR, brx, brx_IN, bs, bs_Cyrl, bs_Cyrl_BA, bs_Latn, bs_Latn_BA, ca, ca_AD, ca_ES, ca_ES_VALENCIA, ca_FR, ca_IT, ce, ce_RU, cgg, cgg_UG, chr, chr_US, ckb, ckb_IQ, ckb_IR, cs, cs_CZ, cu, cu_RU, cy, cy_GB, da, da_DK, da_GL, dav, dav_KE, de, de_AT, de_BE, de_CH, de_DE, de_LI, de_LU, dje, dje_NE, dsb, dsb_DE, dua, dua_CM, dyo, dyo_SN, dz, dz_BT, ebu, ebu_KE, ee, ee_GH, ee_TG, el, el_CY, el_GR, en, en_001, en_150, en_AG, en_AI, en_AS, en_AT, en_AU, en_BB, en_BE, en_BI, en_BM, en_BS, en_BW, en_BZ, en_CA, en_CC, en_CH, en_CK, en_CM, en_CX, en_CY, en_DE, en_DG, en_DK, en_DM, en_ER, en_FI, en_FJ, en_FK, en_FM, en_GB, en_GD, en_GG, en_GH, en_GI, en_GM, en_GU, en_GY, en_HK, en_IE, en_IL, en_IM, en_IN, en_IO, en_JE, en_JM, en_KE, en_KI, en_KN, en_KY, en_LC, en_LR, en_LS, en_MG, en_MH, en_MO, en_MP, en_MS, en_MT, en_MU, en_MW, en_MY, en_NA, en_NF, en_NG, en_NL, en_NR, en_NU, en_NZ, en_PG, en_PH, en_PK, en_PN, en_PR, en_PW, en_RW, en_SB, en_SC, en_SD, en_SE, en_SG, en_SH, en_SI, en_SL, en_SS, en_SX, en_SZ, en_TC, en_TK, en_TO, en_TT, en_TV, en_TZ, en_UG, en_UM, en_US, en_US_POSIX, en_VC, en_VG, en_VI, en_VU, en_WS, en_ZA, en_ZM, en_ZW, eo, eo_001, es, es_419, es_AR, es_BO, es_CL, es_CO, es_CR, es_CU, es_DO, es_EA, es_EC, es_ES, es_GQ, es_GT, es_HN, es_IC, es_MX, es_NI, es_PA, es_PE, es_PH, es_PR, es_PY, es_SV, es_US, es_UY, es_VE, et, et_EE, eu, eu_ES, ewo, ewo_CM, fa, fa_AF, fa_IR, ff, ff_CM, ff_GN, ff_MR, ff_SN, fi, fi_FI, fil, fil_PH, fo, fo_DK, fo_FO, fr, fr_BE, fr_BF, fr_BI, fr_BJ, fr_BL, fr_CA, fr_CD, fr_CF, fr_CG, fr_CH, fr_CI, fr_CM, fr_DJ, fr_DZ, fr_FR, fr_GA, fr_GF, fr_GN, fr_GP, fr_GQ, fr_HT, fr_KM, fr_LU, fr_MA, fr_MC, fr_MF, fr_MG, fr_ML, fr_MQ, fr_MR, fr_MU, fr_NC, fr_NE, fr_PF, fr_PM, fr_RE, fr_RW, fr_SC, fr_SN, fr_SY, fr_TD, fr_TG, fr_TN, fr_VU, fr_WF, fr_YT, fur, fur_IT, fy, fy_NL, ga, ga_IE, gd, gd_GB, gl, gl_ES, gsw, gsw_CH, gsw_FR, gsw_LI, gu, gu_IN, guz, guz_KE, gv, gv_IM, ha, ha_GH, ha_NE, ha_NG, haw, haw_US, he, he_IL, hi, hi_IN, hr, hr_BA, hr_HR, hsb, hsb_DE, hu, hu_HU, hy, hy_AM, id, id_ID, ig, ig_NG, ii, ii_CN, is, is_IS, it, it_CH, it_IT, it_SM, ja, ja_JP, jgo, jgo_CM, jmc, jmc_TZ, ka, ka_GE, kab, kab_DZ, kam, kam_KE, kde, kde_TZ, kea, kea_CV, khq, khq_ML, ki, ki_KE, kk, kk_KZ, kkj, kkj_CM, kl, kl_GL, kln, kln_KE, km, km_KH, kn, kn_IN, ko, ko_KP, ko_KR, kok, kok_IN, ks, ks_IN, ksb, ksb_TZ, ksf, ksf_CM, ksh, ksh_DE, kw, kw_GB, ky, ky_KG, lag, lag_TZ, lb, lb_LU, lg, lg_UG, lkt, lkt_US, ln, ln_AO, ln_CD, ln_CF, ln_CG, lo, lo_LA, lrc, lrc_IQ, lrc_IR, lt, lt_LT, lu, lu_CD, luo, luo_KE, luy, luy_KE, lv, lv_LV, mas, mas_KE, mas_TZ, mer, mer_KE, mfe, mfe_MU, mg, mg_MG, mgh, mgh_MZ, mgo, mgo_CM, mk, mk_MK, ml, ml_IN, mn, mn_MN, mr, mr_IN, ms, ms_BN, ms_MY, ms_SG, mt, mt_MT, mua, mua_CM, my, my_MM, mzn, mzn_IR, naq, naq_NA, nb, nb_NO, nb_SJ, nd, nd_ZW, ne, ne_IN, ne_NP, nl, nl_AW, nl_BE, nl_BQ, nl_CW, nl_NL, nl_SR, nl_SX, nmg, nmg_CM, nn, nn_NO, nnh, nnh_CM, nus, nus_SS, nyn, nyn_UG, om, om_ET, om_KE, or, or_IN, os, os_GE, os_RU, pa, pa_Arab, pa_Arab_PK, pa_Guru, pa_Guru_IN, pl, pl_PL, prg, prg_001, ps, ps_AF, pt, pt_AO, pt_BR, pt_CV, pt_GW, pt_MO, pt_MZ, pt_PT, pt_ST, pt_TL, qu, qu_BO, qu_EC, qu_PE, rm, rm_CH, rn, rn_BI, ro, ro_MD, ro_RO, rof, rof_TZ, root, ru, ru_BY, ru_KG, ru_KZ, ru_MD, ru_RU, ru_UA, rw, rw_RW, rwk, rwk_TZ, sah, sah_RU, saq, saq_KE, sbp, sbp_TZ, se, se_FI, se_NO, se_SE, seh, seh_MZ, ses, ses_ML, sg, sg_CF, shi, shi_Latn, shi_Latn_MA, shi_Tfng, shi_Tfng_MA, si, si_LK, sk, sk_SK, sl, sl_SI, smn, smn_FI, sn, sn_ZW, so, so_DJ, so_ET, so_KE, so_SO, sq, sq_AL, sq_MK, sq_XK, sr, sr_Cyrl, sr_Cyrl_BA, sr_Cyrl_ME, sr_Cyrl_RS, sr_Cyrl_XK, sr_Latn, sr_Latn_BA, sr_Latn_ME, sr_Latn_RS, sr_Latn_XK, sv, sv_AX, sv_FI, sv_SE, sw, sw_CD, sw_KE, sw_TZ, sw_UG, ta, ta_IN, ta_LK, ta_MY, ta_SG, te, te_IN, teo, teo_KE, teo_UG, th, th_TH, ti, ti_ER, ti_ET, tk, tk_TM, to, to_TO, tr, tr_CY, tr_TR, twq, twq_NE, tzm, tzm_MA, ug, ug_CN, uk, uk_UA, ur, ur_IN, ur_PK, uz, uz_Arab, uz_Arab_AF, uz_Cyrl, uz_Cyrl_UZ, uz_Latn, uz_Latn_UZ, vai, vai_Latn, vai_Latn_LR, vai_Vaii, vai_Vaii_LR, vi, vi_VN, vo, vo_001, vun, vun_TZ, wae, wae_CH, xog, xog_UG, yav, yav_CM, yi, yi_001, yo, yo_BJ, yo_NG, zgh, zgh_MA, zh, zh_Hans, zh_Hans_CN, zh_Hans_HK, zh_Hans_MO, zh_Hans_SG, zh_Hant, zh_Hant_HK, zh_Hant_MO, zh_Hant_TW, zu, zu_ZA"); 570bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 571bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert //LocaleMatcher.DEBUG = true; 572bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert ULocale expected = new ULocale("sv"); 573bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert assertEquals(expected, matcherShort.getBestMatch(desired)); 574bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert assertEquals(expected, matcherLong.getBestMatch(desired)); 575bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert assertEquals(expected, matcherVeryLong.getBestMatch(desired)); 576bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert //LocaleMatcher.DEBUG = false; 577bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 578bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert for (int i = 0; i < 2; ++i) { 579bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert int iterations = i == 0 ? 1000 : 100000; 580bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert boolean showMessage = i != 0; 581bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert long timeShort = timeLocaleMatcher("Duration (few supported):\t", desired, matcherShort, showMessage, iterations, 0); 582bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert @SuppressWarnings("unused") 583bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert long timeMedium = timeLocaleMatcher("Duration (med. supported):\t", desired, matcherLong, showMessage, iterations, timeShort); 584bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert @SuppressWarnings("unused") 585bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert long timeLong = timeLocaleMatcher("Duration (many supported):\t", desired, matcherVeryLong, showMessage, iterations, timeShort); 586bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 587bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 588bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 589bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private long timeLocaleMatcher(String title, String desired, LocaleMatcher matcher, 590bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert boolean showmessage, int iterations, long comparisonTime) { 591bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert long start = System.nanoTime(); 592bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert for (int i = iterations; i > 0; --i) { 593bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert matcher.getBestMatch(desired); 594bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 595bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert long delta = System.nanoTime() - start; 596bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (showmessage) warnln(title + (delta / iterations) + " nanos, " 597bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert + (comparisonTime > 0 ? (delta * 100 / comparisonTime - 100) + "% longer" : "")); 598bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert return delta; 599bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 600bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 601bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert public void Test8288() { 602bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert final LocaleMatcher matcher = newLocaleMatcher("it, en"); 603bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert assertEquals("it", matcher.getBestMatch("und").toString()); 604bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert assertEquals("en", matcher.getBestMatch("und, en").toString()); 605bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 6067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert} 607