1aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin/* GENERATED SOURCE. DO NOT MODIFY. */
2aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin/*
3aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin ******************************************************************************************
4aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin * Copyright (C) 2009-2015, Google, Inc.; International Business Machines Corporation and *
5aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin * others. All Rights Reserved.                                                           *
6aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin ******************************************************************************************
7aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin */
8aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
9aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffinpackage android.icu.dev.test.util;
10aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
11aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffinimport java.util.Set;
12aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffinimport java.util.TreeSet;
13aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
14aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffinimport android.icu.dev.test.TestFmwk;
15aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffinimport android.icu.util.LocaleMatcher;
16aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffinimport android.icu.util.LocaleMatcher.LanguageMatcherData;
17aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffinimport android.icu.util.LocalePriorityList;
18aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffinimport android.icu.util.ULocale;
193a45e58d9461ee00f295ca8a6a29ef0860559e7ePaul Duffinimport org.junit.runner.RunWith;
203a45e58d9461ee00f295ca8a6a29ef0860559e7ePaul Duffinimport android.icu.junit.IcuTestFmwkRunner;
21aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
22aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin/**
23aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin * Test the LocaleMatcher.
24aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin *
25aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin * @author markdavis
26aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin */
273a45e58d9461ee00f295ca8a6a29ef0860559e7ePaul Duffin@RunWith(IcuTestFmwkRunner.class)
28aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin@SuppressWarnings("deprecation")
29aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffinpublic class LocaleMatcherTest extends TestFmwk {
30aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
31aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
32aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    private static final ULocale ZH_MO = new ULocale("zh_MO");
33aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    private static final ULocale ZH_HK = new ULocale("zh_HK");
34aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    static LanguageMatcherData LANGUAGE_MATCHER_DATA = LocaleMatcherShim.load();
35aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
36aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    private LocaleMatcher newLocaleMatcher(LocalePriorityList build) {
37aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        return new LocaleMatcher(build, LANGUAGE_MATCHER_DATA);
38aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
39aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
40aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    private LocaleMatcher newLocaleMatcher(LocalePriorityList build, LanguageMatcherData data) {
41aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        return new LocaleMatcher(build, data == null ? LANGUAGE_MATCHER_DATA : data);
42aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
43aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
44aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    private LocaleMatcher newLocaleMatcher(LocalePriorityList lpl, LanguageMatcherData data, double d) {
45aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        return new LocaleMatcher(lpl, data == null ? LANGUAGE_MATCHER_DATA : data, d);
46aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
47aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
48aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    private LocaleMatcher newLocaleMatcher(String string) {
49aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        return new LocaleMatcher(LocalePriorityList.add(string).build(), LANGUAGE_MATCHER_DATA);
50aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
51aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
52aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    // public LocaleMatcher(LocalePriorityList languagePriorityList,
53aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    // LocaleMatcherData matcherData, double threshold)
54aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
55aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public static void main(String[] args) throws Exception {
56aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        new LocaleMatcherTest().run(args);
57aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
58aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
59aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public void testParentLocales() {
60aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertCloser("es_AR", "es_419", "es_ES");
61aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertCloser("es_AR", "es_419", "es");
62aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
63aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertCloser("es_AR", "es_MX", "es");
64aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertCloser("es_AR", "es_MX", "es");
65aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
66aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertCloser("en_AU", "en_GB", "en_US");
67aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertCloser("en_AU", "en_GB", "en");
68aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
69aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertCloser("en_AU", "en_NZ", "en_US");
70aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertCloser("en_AU", "en_NZ", "en");
71aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
72aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertCloser("pt_AO", "pt_PT", "pt_BR");
73aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertCloser("pt_AO", "pt_PT", "pt");
74aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
75aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertCloser("zh_HK", "zh_MO", "zh_TW");
76aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertCloser("zh_HK", "zh_MO", "zh_CN");
77aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertCloser("zh_HK", "zh_MO", "zh");
78aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
79aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
80aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    private void assertCloser(String a, String closer, String further) {
81aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        LocaleMatcher matcher = newLocaleMatcher(further + ", " + closer);
82aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("test " + a + " is closer to " + closer + " than to " + further, new ULocale(closer), matcher.getBestMatch(a));
83aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        matcher = newLocaleMatcher(closer + ", " + further);
84aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("test " + a + " is closer to " + closer + " than to " + further, new ULocale(closer), matcher.getBestMatch(a));
85aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
86aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
87aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    //    public void testParentLocales() {
88aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    //        // find all the regions that have a closer relation because of an explicit parent
89aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    //        Set<String> explicitParents = new HashSet<>(INFO.getExplicitParents());
90aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    //        explicitParents.remove("root");
91aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    //        Set<String> otherParents = new HashSet<>(INFO.getExplicitParents());
92aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    //        for (String locale : explicitParents) {
93aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    //            while (true) {
94aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    //                locale = LocaleIDParser.getParent(locale);
95aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    //                if (locale == null || locale.equals("root")) {
96aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    //                    break;
97aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    //                }
98aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    //                otherParents.add(locale);
99aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    //            }
100aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    //        }
101aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    //        otherParents.remove("root");
102aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    //
103aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    //        for (String locale : CONFIG.getCldrFactory().getAvailable()) {
104aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    //            String parentId = LocaleIDParser.getParent(locale);
105aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    //            String parentIdSimple = LocaleIDParser.getSimpleParent(locale);
106aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    //            if (!explicitParents.contains(parentId) && !otherParents.contains(parentIdSimple)) {
107aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    //                continue;
108aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    //            }
109aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    //            System.out.println(locale + "\t" + CONFIG.getEnglish().getName(locale) + "\t" + parentId + "\t" + parentIdSimple);
110aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    //        }
111aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    //    }
112aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
113aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public void testChinese() {
114aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        LocaleMatcher matcher = newLocaleMatcher("zh_CN, zh_TW, iw");
115aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        ULocale taiwanChinese = new ULocale("zh_TW");
116aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        ULocale chinaChinese = new ULocale("zh_CN");
117aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("zh_CN, zh_TW, iw;", taiwanChinese, matcher.getBestMatch("zh_Hant_TW"));
118aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("zh_CN, zh_TW, iw;", taiwanChinese, matcher.getBestMatch("zh_Hant"));
119aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("zh_CN, zh_TW, iw;", taiwanChinese, matcher.getBestMatch("zh_TW"));
120aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("zh_CN, zh_TW, iw;", chinaChinese, matcher.getBestMatch("zh_Hans_CN"));
121aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("zh_CN, zh_TW, iw;", chinaChinese, matcher.getBestMatch("zh_CN"));
122aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("zh_CN, zh_TW, iw;", chinaChinese, matcher.getBestMatch("zh"));
123aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("zh_CN, zh_TW, iw;", taiwanChinese, matcher.getBestMatch("zh_Hant_HK"));
124aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
125aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
126aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public void testenGB() {
127aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        final LocaleMatcher matcher = newLocaleMatcher("fr, en, en_GB, es_MX, es_419, es");
128aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("en_GB", matcher.getBestMatch("en_NZ").toString());
129aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("es", matcher.getBestMatch("es_ES").toString());
130aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("es_419", matcher.getBestMatch("es_AR").toString());
131aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("es_MX", matcher.getBestMatch("es_MX").toString());
132aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
133aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
134aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public void testFallbacks() {
135aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        LocalePriorityList lpl = LocalePriorityList.add("en, hi").build();
136aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        final LocaleMatcher matcher = newLocaleMatcher(lpl, null, 0.09);
137aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("hi", matcher.getBestMatch("sa").toString());
138aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
139aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
140aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public void testOverrideData() {
141aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        double threshold = 0.05;
142aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        LanguageMatcherData localeMatcherData = new LanguageMatcherData()
143aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        .addDistance("br", "fr", 10, true)
144aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        .addDistance("es", "cy", 10, true);
145aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        logln(localeMatcherData.toString());
146aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
147aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        final LocaleMatcher matcher = newLocaleMatcher(
148aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            LocalePriorityList
149aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            .add(ULocale.ENGLISH)
150aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            .add(ULocale.FRENCH)
151aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            .add(ULocale.UK)
152aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            .build(), localeMatcherData, threshold);
153aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        logln(matcher.toString());
154aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
155aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals(ULocale.FRENCH, matcher.getBestMatch(new ULocale("br")));
156aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals(ULocale.ENGLISH, matcher.getBestMatch(new ULocale("es"))); // one
157aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // way
158aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
159aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
160aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public void testBasics() {
161aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        final LocaleMatcher matcher = newLocaleMatcher(LocalePriorityList.add(ULocale.FRENCH).add(ULocale.UK)
162aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            .add(ULocale.ENGLISH).build());
163aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        logln(matcher.toString());
164aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
165aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals(ULocale.UK, matcher.getBestMatch(ULocale.UK));
166aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals(ULocale.ENGLISH, matcher.getBestMatch(ULocale.US));
167aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals(ULocale.FRENCH, matcher.getBestMatch(ULocale.FRANCE));
168aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals(ULocale.FRENCH, matcher.getBestMatch(ULocale.JAPAN));
169aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
170aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
171aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public void testFallback() {
172aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // check that script fallbacks are handled right
173aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        final LocaleMatcher matcher = newLocaleMatcher("zh_CN, zh_TW, iw");
174aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals(new ULocale("zh_TW"), matcher.getBestMatch("zh_Hant"));
175aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals(new ULocale("zh_CN"), matcher.getBestMatch("zh"));
176aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals(new ULocale("zh_CN"), matcher.getBestMatch("zh_Hans_CN"));
177aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals(new ULocale("zh_TW"), matcher.getBestMatch("zh_Hant_HK"));
178aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals(new ULocale("he"), matcher.getBestMatch("iw_IT"));
179aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
180aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
181aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public void testSpecials() {
182aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // check that nearby languages are handled
183aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        final LocaleMatcher matcher = newLocaleMatcher("en, fil, ro, nn");
184aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals(new ULocale("fil"), matcher.getBestMatch("tl"));
185aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals(new ULocale("ro"), matcher.getBestMatch("mo"));
186aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals(new ULocale("nn"), matcher.getBestMatch("nb"));
187aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // make sure default works
188aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals(new ULocale("en"), matcher.getBestMatch("ja"));
189aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
190aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
191aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public void testRegionalSpecials() {
192aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // verify that en_AU is closer to en_GB than to en (which is en_US)
193aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        final LocaleMatcher matcher = newLocaleMatcher("en, en_GB, es, es_419");
194aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("es_MX in {en, en_GB, es, es_419}", new ULocale("es_419"), matcher.getBestMatch("es_MX"));
195aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("en_AU in {en, en_GB, es, es_419}", new ULocale("en_GB"), matcher.getBestMatch("en_AU"));
196aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("es_ES in {en, en_GB, es, es_419}", new ULocale("es"), matcher.getBestMatch("es_ES"));
197aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
198aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
199aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public void testHK() {
200aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // HK and MO are closer to each other for Hant than to TW
201aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        final LocaleMatcher matcher = newLocaleMatcher("zh, zh_TW, zh_MO");
202aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("zh_HK in {zh, zh_TW, zh_MO}", ZH_MO, matcher.getBestMatch("zh_HK"));
203aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        final LocaleMatcher matcher2 = newLocaleMatcher("zh, zh_TW, zh_HK");
204aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("zh_MO in {zh, zh_TW, zh_HK}", ZH_HK, matcher2.getBestMatch("zh_MO"));
205aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
206aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
207aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public void TestLocaleMatcherCoverage() {
208aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // Add tests for better code coverage
209aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        LocaleMatcher matcher = newLocaleMatcher(LocalePriorityList.add(null, 0).build(), null);
210aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        logln(matcher.toString());
211aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
212aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        LanguageMatcherData data = new LanguageMatcherData();
213aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
214aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        LanguageMatcherData clone = data.cloneAsThawed();
215aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
216aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        if (clone.equals(data)) {
217aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            errln("Error cloneAsThawed() is equal.");
218aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        }
219aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
220aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        if (data.isFrozen()) {
221aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            errln("Error LocaleMatcherData is frozen!");
222aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        }
223aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
224aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
225aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    private void assertEquals(Object expected, Object string) {
226aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("", expected, string);
227aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
228aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
229aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    private void assertNull(Object bestMatch) {
230aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertNull("", bestMatch);
231aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
232aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
233aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public void testEmpty() {
234aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        final LocaleMatcher matcher = newLocaleMatcher("");
235aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertNull(matcher.getBestMatch(ULocale.FRENCH));
236aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
237aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
238aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    static final ULocale ENGLISH_CANADA = new ULocale("en_CA");
239aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
240aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public void testMatch_exact() {
241aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals(1.0,
242aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            LocaleMatcher.match(ENGLISH_CANADA, ENGLISH_CANADA));
243aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
244aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
245aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public void testMatch_none() {
246aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        double match = LocaleMatcher.match(
247aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            new ULocale("ar_MK"),
248aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            ENGLISH_CANADA);
249aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertTrue("Actual < 0: " + match, 0 <= match);
250aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertTrue("Actual > 0.15 (~ language + script distance): " + match, 0.2 > match);
251aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
252aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
253aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public void testMatch_matchOnMazimized() {
254aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        ULocale undTw = new ULocale("und_TW");
255aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        ULocale zhHant = new ULocale("zh_Hant");
256aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        double matchZh = LocaleMatcher.match(undTw, new ULocale("zh"));
257aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        double matchZhHant = LocaleMatcher.match(undTw, zhHant);
258aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertTrue("und_TW should be closer to zh_Hant (" + matchZhHant +
259aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            ") than to zh (" + matchZh + ")",
260aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            matchZh < matchZhHant);
261aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        double matchEnHantTw = LocaleMatcher.match(new ULocale("en_Hant_TW"),
262aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            zhHant);
263aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertTrue("zh_Hant should be closer to und_TW (" + matchZhHant +
264aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            ") than to en_Hant_TW (" + matchEnHantTw + ")",
265aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            matchEnHantTw < matchZhHant);
266aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertTrue("zh should be closer to und_TW (" + matchZh +
267aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            ") than to en_Hant_TW (" + matchEnHantTw + ")",
268aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            matchEnHantTw < matchZh);
269aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
270aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
271aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public void testMatchGrandfatheredCode() {
272aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        final LocaleMatcher matcher = newLocaleMatcher("fr, i_klingon, en_Latn_US");
273aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("en_Latn_US", matcher.getBestMatch("en_GB_oed").toString());
274aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // assertEquals("tlh", matcher.getBestMatch("i_klingon").toString());
275aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
276aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
277aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public void testGetBestMatchForList_exactMatch() {
278aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        final LocaleMatcher matcher = newLocaleMatcher("fr, en_GB, ja, es_ES, es_MX");
279aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("ja", matcher.getBestMatch("ja, de").toString());
280aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
281aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
282aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public void testGetBestMatchForList_simpleVariantMatch() {
283aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        final LocaleMatcher matcher = newLocaleMatcher("fr, en_GB, ja, es_ES, es_MX");
284aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // Intentionally avoiding a perfect_match or two candidates for variant
285aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // matches.
286aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("en_GB", matcher.getBestMatch("de, en_US").toString());
287aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // Fall back.
288aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("fr", matcher.getBestMatch("de, zh").toString());
289aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
290aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
291aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public void testGetBestMatchForList_matchOnMaximized() {
292aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        final LocaleMatcher matcher = newLocaleMatcher("en, ja");
293aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // final LocaleMatcher matcher =
294aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // newLocaleMatcher("fr, en, ja, es_ES, es_MX");
295aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // Check that if the preference is maximized already, it works as well.
296aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("Match for ja_Jpan_JP (maximized already)",
297aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            "ja", matcher.getBestMatch("ja_Jpan_JP, en-AU").toString());
298aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        if (true)
299aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            return;
300aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // ja_JP matches ja on likely subtags, and it's listed first, thus it
301aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // wins over
302aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // thus it wins over the second preference en_GB.
303aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("Match for ja_JP, with likely region subtag",
304aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            "ja", matcher.getBestMatch("ja_JP, en_US").toString());
305aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // Check that if the preference is maximized already, it works as well.
306aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("Match for ja_Jpan_JP (maximized already)",
307aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            "ja", matcher.getBestMatch("ja_Jpan_JP, en_US").toString());
308aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
309aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
310aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public void testGetBestMatchForList_noMatchOnMaximized() {
311aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // Regression test for http://b/5714572 .
312aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        final LocaleMatcher matcher = newLocaleMatcher("en, de, fr, ja");
313aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // de maximizes to de_DE. Pick the exact match for the secondary
314aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // language instead.
315aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("de", matcher.getBestMatch("de_CH, fr").toString());
316aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
317aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
318aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public void testBestMatchForTraditionalChinese() {
319aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // Scenario: An application that only supports Simplified Chinese (and
320aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // some other languages),
321aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // but does not support Traditional Chinese. zh_Hans_CN could be
322aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // replaced with zh_CN, zh, or
323aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // zh_Hans, it wouldn't make much of a difference.
324aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        final LocaleMatcher matcher = newLocaleMatcher("fr, zh_Hans_CN, en_US");
325aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
326aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // The script distance (simplified vs. traditional Han) is considered
327aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // small enough
328aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // to be an acceptable match. The regional difference is considered
329aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // almost insignificant.
330aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("zh_Hans_CN", matcher.getBestMatch("zh_TW").toString());
331aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("zh_Hans_CN", matcher.getBestMatch("zh_Hant").toString());
332aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
333aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // For geo_political reasons, you might want to avoid a zh_Hant ->
334aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // zh_Hans match.
335aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // In this case, if zh_TW, zh_HK or a tag starting with zh_Hant is
336aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // requested, you can
337aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // change your call to getBestMatch to include a 2nd language
338aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // preference.
339aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // "en" is a better match since its distance to "en_US" is closer than
340aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // the distance
341aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // from "zh_TW" to "zh_CN" (script distance).
342aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("en_US", matcher.getBestMatch("zh_TW, en").toString());
343aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("en_US", matcher.getBestMatch("zh_Hant_CN, en").toString());
344aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("zh_Hans_CN", matcher.getBestMatch("zh_Hans, en").toString());
345aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
346aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
347aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public void testUndefined() {
348aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // When the undefined language doesn't match anything in the list,
349aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // getBestMatch returns
350aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // the default, as usual.
351aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        LocaleMatcher matcher = newLocaleMatcher("it,fr");
352aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("it", matcher.getBestMatch("und").toString());
353aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
354aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // When it *does* occur in the list, BestMatch returns it, as expected.
355aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        matcher = newLocaleMatcher("it,und");
356aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("und", matcher.getBestMatch("und").toString());
357aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
358aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // The unusual part:
359aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // max("und") = "en_Latn_US", and since matching is based on maximized
360aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // tags, the undefined
361aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // language would normally match English. But that would produce the
362aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // counterintuitive results
363aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // that getBestMatch("und", LocaleMatcher("it,en")) would be "en", and
364aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // getBestMatch("en", LocaleMatcher("it,und")) would be "und".
365aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        //
366aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // To avoid that, we change the matcher's definitions of max
367aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // (AddLikelySubtagsWithDefaults)
368aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // so that max("und")="und". That produces the following, more desirable
369aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // results:
370aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        matcher = newLocaleMatcher("it,en");
371aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("it", matcher.getBestMatch("und").toString());
372aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        matcher = newLocaleMatcher("it,und");
373aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("it", matcher.getBestMatch("en").toString());
374aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
375aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
376aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    // public void testGetBestMatch_emptyList() {
377aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    // final LocaleMatcher matcher = newLocaleMatcher(
378aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    // new LocalePriorityList(new HashMap()));
379aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    // assertNull(matcher.getBestMatch(ULocale.ENGLISH));
380aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    // }
381aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
382aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public void testGetBestMatch_googlePseudoLocales() {
383aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // Google pseudo locales are primarily based on variant subtags.
384aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // See http://sites/intl_eng/pseudo_locales.
385aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // (See below for the region code based fall back options.)
386aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        final LocaleMatcher matcher = newLocaleMatcher(
387aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            "fr, pt");
388aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("fr", matcher.getBestMatch("de").toString());
389aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("fr", matcher.getBestMatch("en_US").toString());
390aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("fr", matcher.getBestMatch("en").toString());
391aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("pt", matcher.getBestMatch("pt_BR").toString());
392aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
393aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
394aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public void testGetBestMatch_regionDistance() {
395aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        LocaleMatcher matcher = newLocaleMatcher("es_AR, es");
396aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("es_AR", matcher.getBestMatch("es_MX").toString());
397aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
398aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        matcher = newLocaleMatcher("fr, en, en_GB");
399aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("en_GB", matcher.getBestMatch("en_CA").toString());
400aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
401aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        matcher = newLocaleMatcher("de_AT, de_DE, de_CH");
402aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("de_DE", matcher.getBestMatch("de").toString());
403aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
404aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        showDistance(matcher, "en", "en_CA");
405aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        showDistance(matcher, "en_CA", "en");
406aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        showDistance(matcher, "en_US", "en_CA");
407aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        showDistance(matcher, "en_CA", "en_US");
408aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        showDistance(matcher, "en_GB", "en_CA");
409aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        showDistance(matcher, "en_CA", "en_GB");
410aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        showDistance(matcher, "en", "en_UM");
411aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        showDistance(matcher, "en_UM", "en");
412aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
413aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
414aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    private void showDistance(LocaleMatcher matcher, String desired, String supported) {
415aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        ULocale desired2 = new ULocale(desired);
416aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        ULocale supported2 = new ULocale(supported);
417aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        double distance = matcher.match(desired2, ULocale.addLikelySubtags(desired2), supported2, ULocale.addLikelySubtags(supported2));
418aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        logln(desired + " to " + supported + " :\t" + distance);
419aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
420aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
421aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    /**
422aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     * If all the base languages are the same, then each sublocale matches
423aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     * itself most closely
424aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     */
425aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public void testExactMatches() {
426aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        String lastBase = "";
427aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        TreeSet<ULocale> sorted = new TreeSet<ULocale>();
428aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        for (ULocale loc : ULocale.getAvailableLocales()) {
429aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            String language = loc.getLanguage();
430aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            if (!lastBase.equals(language)) {
431aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                check(sorted);
432aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                sorted.clear();
433aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                lastBase = language;
434aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            }
435aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            sorted.add(loc);
436aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        }
437aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        check(sorted);
438aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
439aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
440aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    private void check(Set<ULocale> sorted) {
441aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        if (sorted.isEmpty()) {
442aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            return;
443aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        }
444aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        check2(sorted);
445aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        ULocale first = sorted.iterator().next();
446aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        ULocale max = ULocale.addLikelySubtags(first);
447aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        sorted.add(max);
448aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        check2(sorted);
449aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
450aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
451aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    /**
452aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     * @param sorted
453aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     */
454aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    private void check2(Set<ULocale> sorted) {
455aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // TODO Auto-generated method stub
456aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        logln("Checking: " + sorted);
457aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        LocaleMatcher matcher = newLocaleMatcher(
458aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            LocalePriorityList.add(
459aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                sorted.toArray(new ULocale[sorted.size()]))
460aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                .build());
461aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        for (ULocale loc : sorted) {
462aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            String stringLoc = loc.toString();
463aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            assertEquals(stringLoc, matcher.getBestMatch(stringLoc).toString());
464aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        }
465aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
466aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
467aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public void testAsymmetry() {
468aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        LocaleMatcher matcher;
469aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        matcher = new LocaleMatcher("mul, nl");
470aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("nl", matcher.getBestMatch("af").toString()); // af => nl
471aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
472aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        matcher = new LocaleMatcher("mul, af");
473aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("mul", matcher.getBestMatch("nl").toString()); // but nl !=> af
474aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
475aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
476aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
477aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    // public void testComputeDistance_monkeyTest() {
478aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    // RegionCode[] codes = RegionCode.values();
479aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    // Random random = new Random();
480aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    // for (int i = 0; i < 1000; ++i) {
481aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    // RegionCode x = codes[random.nextInt(codes.length)];
482aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    // RegionCode y = codes[random.nextInt(codes.length)];
483aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    // double d = LocaleMatcher.getRegionDistance(x, y, null, null);
484aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    // if (x == RegionCode.ZZ || y == RegionCode.ZZ) {
485aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    // assertEquals(LocaleMatcher.REGION_DISTANCE, d);
486aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    // } else if (x == y) {
487aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    // assertEquals(0.0, d);
488aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    // } else {
489aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    // assertTrue(d > 0);
490aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    // assertTrue(d <= LocaleMatcher.REGION_DISTANCE);
491aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    // }
492aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    // }
493aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    // }
494aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
495aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public void testGetBestMatchForList_matchOnMaximized2() {
496aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin//        if (logKnownIssue("Cldrbug:8811", "Problems with LocaleMatcher test")) {
497aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin//            return;
498aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin//        }
499aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        final LocaleMatcher matcher = newLocaleMatcher("fr, en-GB, ja, es-ES, es-MX");
500aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // ja-JP matches ja on likely subtags, and it's listed first, thus it wins over
501aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // thus it wins over the second preference en-GB.
502aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("Match for ja-JP, with likely region subtag",
503aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            "ja", matcher.getBestMatch("ja-JP, en-GB").toString());
504aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // Check that if the preference is maximized already, it works as well.
505aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("Match for ja-Jpan-JP (maximized already)",
506aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            "ja", matcher.getBestMatch("ja-Jpan-JP, en-GB").toString());
507aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
508aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
509aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public void testGetBestMatchForList_closeEnoughMatchOnMaximized() {
510aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin//        if (logKnownIssue("Cldrbug:8811", "Problems with LocaleMatcher test")) {
511aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin//            return;
512aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin//        }
513aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        final LocaleMatcher matcher = newLocaleMatcher("en-GB, en, de, fr, ja");
514aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("de", matcher.getBestMatch("de-CH, fr").toString());
515aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("en", matcher.getBestMatch("en-US, ar, nl, de, ja").toString());
516aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
517aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
518aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public void testGetBestMatchForPortuguese() {
519aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
520aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin//        if (logKnownIssue("Cldrbug:8811", "Problems with LocaleMatcher test")) {
521aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin//            return;
522aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin//        }
523aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
524aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        final LocaleMatcher withPTExplicit = newLocaleMatcher("pt_PT, pt_BR, es, es_419");
525aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        final LocaleMatcher withPTImplicit = newLocaleMatcher("pt_PT, pt, es, es_419");
526aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // Could happen because "pt_BR" is a tier_1 language and "pt_PT" is tier_2.
527aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
528aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        final LocaleMatcher withoutPT = newLocaleMatcher("pt_BR, es, es_419");
529aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // European user who prefers Spanish over Brazillian Portuguese as a fallback.
530aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
531aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("pt_PT", withPTExplicit.getBestMatch("pt_PT, es, pt").toString());
532aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("pt_PT", withPTImplicit.getBestMatch("pt_PT, es, pt").toString());
533aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("es", withoutPT.getBestMatch("pt_PT, es, pt").toString());
534aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
535aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // Brazillian user who prefers South American Spanish over European Portuguese as a fallback.
536aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // The asymmetry between this case and above is because it's "pt_PT" that's missing between the
537aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // matchers as "pt_BR" is a much more common language.
538aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("pt_BR", withPTExplicit.getBestMatch("pt, es_419, pt_PT").toString());
539aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("pt", withPTImplicit.getBestMatch("pt, es_419, pt_PT").toString());
540aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("pt_BR", withoutPT.getBestMatch("pt, es_419, pt_PT").toString());
541aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
542aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // Code that adds the user's country can get "pt_US" for a user's language.
543aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // That should fall back to "pt_BR".
544aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("pt_BR", withPTExplicit.getBestMatch("pt_US, pt_PT").toString());
545aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("pt", withPTImplicit.getBestMatch("pt_US, pt_PT").toString());
546aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
547aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
548aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public void testVariantWithScriptMatch() {
549aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin//        if (logKnownIssue("Cldrbug:8811", "Problems with LocaleMatcher test")) {
550aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin//            return;
551aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin//        }
552aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        final LocaleMatcher matcher = newLocaleMatcher("fr, en, sv");
553aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("en", matcher.getBestMatch("en-GB").toString());
554aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("en", matcher.getBestMatch("en-GB, sv").toString());
555aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
556aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
557aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public void testVariantWithScriptMatch2() {
558aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin//        if (logKnownIssue("Cldrbug:8811", "Problems with LocaleMatcher test")) {
559aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin//            return;
560aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin//        }
561aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        final LocaleMatcher matcher = newLocaleMatcher("en, sv");
562aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("en", matcher.getBestMatch("en-GB, sv").toString());
563aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
564aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
565aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public void testPerf() {
566aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        if (LANGUAGE_MATCHER_DATA == null) {
567aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            return; // skip except when testing data
568aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        }
569aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        final String desired = "sv, en";
570aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
571aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        final LocaleMatcher matcherShort = newLocaleMatcher(desired);
572aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        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");
573aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        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");
574aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
575aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        //LocaleMatcher.DEBUG = true;
576aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        ULocale expected = new ULocale("sv");
577aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals(expected, matcherShort.getBestMatch(desired));
578aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals(expected, matcherLong.getBestMatch(desired));
579aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals(expected, matcherVeryLong.getBestMatch(desired));
580aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        //LocaleMatcher.DEBUG = false;
581aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
582aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        for (int i = 0; i < 2; ++i) {
583aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            int iterations = i == 0 ? 1000 : 100000;
584aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            boolean showMessage = i != 0;
585aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            long timeShort = timeLocaleMatcher("Duration (few  supported):\t", desired, matcherShort, showMessage, iterations, 0);
586aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            @SuppressWarnings("unused")
587aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            long timeMedium = timeLocaleMatcher("Duration (med. supported):\t", desired, matcherLong, showMessage, iterations, timeShort);
588aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            @SuppressWarnings("unused")
589aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            long timeLong = timeLocaleMatcher("Duration (many supported):\t", desired, matcherVeryLong, showMessage, iterations, timeShort);
590aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        }
591aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
592aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
593aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    private long timeLocaleMatcher(String title, String desired, LocaleMatcher matcher,
594aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        boolean showmessage, int iterations, long comparisonTime) {
595aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        long start = System.nanoTime();
596aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        for (int i = iterations; i > 0; --i) {
597aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            matcher.getBestMatch(desired);
598aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        }
599aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        long delta = System.nanoTime() - start;
600aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        if (showmessage) warnln(title + (delta / iterations) + " nanos, "
601aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            + (comparisonTime > 0 ? (delta * 100 / comparisonTime - 100) + "% longer" : ""));
602aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        return delta;
603aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
604aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
605aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public void Test8288() {
606aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        final LocaleMatcher matcher = newLocaleMatcher("it, en");
607aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("it", matcher.getBestMatch("und").toString());
608aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        assertEquals("en", matcher.getBestMatch("und, en").toString());
609aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
610aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin}
611