1aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin/* GENERATED SOURCE. DO NOT MODIFY. */
2f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert// © 2016 and later: Unicode, Inc. and others.
3f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert// License & terms of use: http://www.unicode.org/copyright.html#License
4aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin/*
5aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin **********************************************************************
6aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin * Copyright (c) 2015, International Business Machines
7aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin * Corporation and others.  All Rights Reserved.
8aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin **********************************************************************
9aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin * Author: Alan Liu
10aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin * Created: January 14 2004
11aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin * Since: ICU 2.8
12aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin **********************************************************************
13aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin */
14aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffinpackage android.icu.dev.test.util;
15aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
16aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffinimport java.lang.reflect.InvocationTargetException;
17aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffinimport java.lang.reflect.Method;
18aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffinimport java.util.ArrayList;
19aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffinimport java.util.Arrays;
20aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffinimport java.util.Collections;
21aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffinimport java.util.LinkedHashSet;
22aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffinimport java.util.List;
23aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffinimport java.util.Locale;
24aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffinimport java.util.Set;
25aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
26f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubertimport org.junit.Test;
27f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert
28aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffinimport android.icu.dev.test.TestFmwk;
29aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffinimport android.icu.text.Collator;
30aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffinimport android.icu.text.DisplayContext;
31aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffinimport android.icu.text.DisplayContext.Type;
32aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffinimport android.icu.text.LocaleDisplayNames;
33aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffinimport android.icu.text.LocaleDisplayNames.UiListItem;
34aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffinimport android.icu.util.IllformedLocaleException;
35aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffinimport android.icu.util.ULocale;
36aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
37aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffinpublic class ULocaleCollationTest extends TestFmwk {
38f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert    @Test
39aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public void TestCollator() {
40aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        checkService("ja_JP_YOKOHAMA", new ServiceFacade() {
41aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            public Object create(ULocale req) {
42aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                return Collator.getInstance(req);
43aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            }
44aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        }, null, new Registrar() {
45aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            public Object register(ULocale loc, Object prototype) {
46aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                return Collator.registerInstance((Collator) prototype, loc);
47aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            }
48aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            public boolean unregister(Object key) {
49aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                return Collator.unregister(key);
50aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            }
51aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        });
52aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
53aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
54aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
55aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    /**
56aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     * Interface used by checkService defining a protocol to create an
57aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     * object, given a requested locale.
58aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     */
59aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    interface ServiceFacade {
60aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        Object create(ULocale requestedLocale);
61aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
62aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
63aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    /**
64aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     * Interface used by checkService defining a protocol to get a
65aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     * contained subobject, given its parent object.
66aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     */
67aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    interface Subobject {
68aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        Object get(Object parent);
69aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
70aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
71aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    /**
72aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     * Interface used by checkService defining a protocol to register
73aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     * and unregister a service object prototype.
74aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     */
75aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    interface Registrar {
76aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        Object register(ULocale loc, Object prototype);
77aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        boolean unregister(Object key);
78aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
79aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
80aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
81aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
82aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    /**
83aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     * Compare two locale IDs.  If they are equal, return 0.  If `string'
84aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     * starts with `prefix' plus an additional element, that is, string ==
85aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     * prefix + '_' + x, then return 1.  Otherwise return a value < 0.
86aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     */
87aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    static int loccmp(String string, String prefix) {
88aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        int slen = string.length(),
89aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                plen = prefix.length();
90aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        /* 'root' is "less than" everything */
91aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        if (prefix.equals("root")) {
92aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            return string.equals("root") ? 0 : 1;
93aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        }
94aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // ON JAVA (only -- not on C -- someone correct me if I'm wrong)
95aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // consider "" to be an alternate name for "root".
96aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        if (plen == 0) {
97aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            return slen == 0 ? 0 : 1;
98aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        }
99aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        if (!string.startsWith(prefix)) return -1; /* mismatch */
100aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        if (slen == plen) return 0;
101aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        if (string.charAt(plen) == '_') return 1;
102aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        return -2; /* false match, e.g. "en_USX" cmp "en_US" */
103aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
104aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
105aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    /**
106aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     * Check the relationship between requested locales, and report problems.
107aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     * The caller specifies the expected relationships between requested
108aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     * and valid (expReqValid) and between valid and actual (expValidActual).
109aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     * Possible values are:
110aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     * "gt" strictly greater than, e.g., en_US > en
111aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     * "ge" greater or equal,      e.g., en >= en
112aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     * "eq" equal,                 e.g., en == en
113aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     */
114aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    void checklocs(String label,
115aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            String req,
116aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            Locale validLoc,
117aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            Locale actualLoc,
118aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            String expReqValid,
119aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            String expValidActual) {
120aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        String valid = validLoc.toString();
121aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        String actual = actualLoc.toString();
122aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        int reqValid = loccmp(req, valid);
123aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        int validActual = loccmp(valid, actual);
124aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        boolean reqOK = (expReqValid.equals("gt") && reqValid > 0) ||
125aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                (expReqValid.equals("ge") && reqValid >= 0) ||
126aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                (expReqValid.equals("eq") && reqValid == 0);
127aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        boolean valOK = (expValidActual.equals("gt") && validActual > 0) ||
128aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                (expValidActual.equals("ge") && validActual >= 0) ||
129aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                (expValidActual.equals("eq") && validActual == 0);
130aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        if (reqOK && valOK) {
131aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            logln("Ok: " + label + "; req=" + req + ", valid=" + valid +
132aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                    ", actual=" + actual);
133aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        } else {
134aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            errln("FAIL: " + label + "; req=" + req + ", valid=" + valid +
135aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                    ", actual=" + actual +
136aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                    (reqOK ? "" : "\n  req !" + expReqValid + " valid") +
137aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                    (valOK ? "" : "\n  val !" + expValidActual + " actual"));
138aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        }
139aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
140aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
141aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    /**
142aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     * Use reflection to call getLocale() on the given object to
143aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     * determine both the valid and the actual locale.  Verify these
144aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     * for correctness.
145aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     */
146aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    void checkObject(String requestedLocale, Object obj,
147aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            String expReqValid, String expValidActual) {
148aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        Class[] getLocaleParams = new Class[] { ULocale.Type.class };
149aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        try {
150aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            Class cls = obj.getClass();
151aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            Method getLocale = cls.getMethod("getLocale", getLocaleParams);
152aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            ULocale valid = (ULocale) getLocale.invoke(obj, new Object[] {
153aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                    ULocale.VALID_LOCALE });
154aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            ULocale actual = (ULocale) getLocale.invoke(obj, new Object[] {
155aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                    ULocale.ACTUAL_LOCALE });
156aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            checklocs(cls.getName(), requestedLocale,
157aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                    valid.toLocale(), actual.toLocale(),
158aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                    expReqValid, expValidActual);
159aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        }
160aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
161aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // Make the following exceptions _specific_ -- do not
162aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // catch(Exception), since that will catch the exception
163aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        // that errln throws.
164aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        catch(NoSuchMethodException e1) {
165aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            // no longer an error, Currency has no getLocale
166aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            // errln("FAIL: reflection failed: " + e1);
167aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        } catch(SecurityException e2) {
168aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            errln("FAIL: reflection failed: " + e2);
169aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        } catch(IllegalAccessException e3) {
170aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            errln("FAIL: reflection failed: " + e3);
171aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        } catch(IllegalArgumentException e4) {
172aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            errln("FAIL: reflection failed: " + e4);
173aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        } catch(InvocationTargetException e5) {
174aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            // no longer an error, Currency has no getLocale
175aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            // errln("FAIL: reflection failed: " + e5);
176aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        }
177aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
178aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
179aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    /**
180aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     * Verify the correct getLocale() behavior for the given service.
181aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     * @param requestedLocale the locale to request.  This MUST BE
182aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     * FAKE.  In other words, it should be something like
183aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     * en_US_FAKEVARIANT so this method can verify correct fallback
184aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     * behavior.
185aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     * @param svc a factory object that can create the object to be
186aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     * tested.  This isn't necessary here (one could just pass in the
187aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     * object) but is required for the overload of this method that
188aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     * takes a Registrar.
189aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     */
190aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    void checkService(String requestedLocale, ServiceFacade svc) {
191aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        checkService(requestedLocale, svc, null, null);
192aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
193aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
194aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    /**
195aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     * Verify the correct getLocale() behavior for the given service.
196aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     * @param requestedLocale the locale to request.  This MUST BE
197aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     * FAKE.  In other words, it should be something like
198aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     * en_US_FAKEVARIANT so this method can verify correct fallback
199aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     * behavior.
200aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     * @param svc a factory object that can create the object to be
201aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     * tested.
202aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     * @param sub an object that can be used to retrieve a subobject
203aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     * which should also be tested.  May be null.
204aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     * @param reg an object that supplies the registration and
205aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     * unregistration functionality to be tested.  May be null.
206aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin     */
207aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    void checkService(String requestedLocale, ServiceFacade svc,
208aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            Subobject sub, Registrar reg) {
209aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        ULocale req = new ULocale(requestedLocale);
210aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        Object obj = svc.create(req);
211aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        checkObject(requestedLocale, obj, "gt", "ge");
212aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        if (sub != null) {
213aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            Object subobj = sub.get(obj);
214aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            checkObject(requestedLocale, subobj, "gt", "ge");
215aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        }
216aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        if (reg != null) {
217aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            logln("Info: Registering service");
218aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            Object key = reg.register(req, obj);
219aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            Object objReg = svc.create(req);
220aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            checkObject(requestedLocale, objReg, "eq", "eq");
221aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            if (sub != null) {
222aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                Object subobj = sub.get(obj);
223aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                // Assume subobjects don't come from services, so
224aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                // their metadata should be structured normally.
225aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                checkObject(requestedLocale, subobj, "gt", "ge");
226aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            }
227aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            logln("Info: Unregistering service");
228aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            if (!reg.unregister(key)) {
229aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                errln("FAIL: unregister failed");
230aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            }
231aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            Object objUnreg = svc.create(req);
232aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            checkObject(requestedLocale, objUnreg, "gt", "ge");
233aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        }
234aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
235aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
236f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert    @Test
237aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public void TestNameList() {
238aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        String[][][] tests = {
239aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                /* name in French, name in self, minimized, modified */
240aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                {{"fr-Cyrl-BE", "fr-Cyrl-CA"},
241aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                    {"Français (cyrillique, Belgique)", "Français (cyrillique, Belgique)", "fr_Cyrl_BE", "fr_Cyrl_BE"},
242aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                    {"Français (cyrillique, Canada)", "Français (cyrillique, Canada)", "fr_Cyrl_CA", "fr_Cyrl_CA"},
243aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                },
244aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                {{"en", "de", "fr", "zh"},
245aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                    {"Allemand", "Deutsch", "de", "de"},
246aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                    {"Anglais", "English", "en", "en"},
247aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                    {"Chinois", "中文", "zh", "zh"},
248aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                    {"Français", "Français", "fr", "fr"},
249aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                },
250aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                // some non-canonical names
251aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                {{"iw", "iw-US", "no", "no-Cyrl", "in", "in-YU"},
252aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                    {"Hébreu (États-Unis)", "עברית (ארצות הברית)", "iw_US", "iw_US"},
253aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                    {"Hébreu (Israël)", "עברית (ישראל)", "iw", "iw_IL"},
254aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                    {"Indonésien (Indonésie)", "Indonesia (Indonesia)", "in", "in_ID"},
255aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                    {"Indonésien (Serbie)", "Indonesia (Serbia)", "in_YU", "in_YU"},
256aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                    {"Norvégien (cyrillique)", "Norsk (kyrillisk)", "no_Cyrl", "no_Cyrl"},
257aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                    {"Norvégien (latin)", "Norsk (latinsk)", "no", "no_Latn"},
258aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                },
259aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                {{"zh-Hant-TW", "en", "en-gb", "fr", "zh-Hant", "de", "de-CH", "zh-TW"},
260aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                    {"Allemand (Allemagne)", "Deutsch (Deutschland)", "de", "de_DE"},
261aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                    {"Allemand (Suisse)", "Deutsch (Schweiz)", "de_CH", "de_CH"},
262aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                    {"Anglais (États-Unis)", "English (United States)", "en", "en_US"},
263aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                    {"Anglais (Royaume-Uni)", "English (United Kingdom)", "en_GB", "en_GB"},
264aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                    {"Chinois (traditionnel)", "中文(繁體)", "zh_Hant", "zh_Hant"},
265aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                    {"Français", "Français", "fr", "fr"},
266aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                },
267aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                {{"zh", "en-gb", "en-CA", "fr-Latn-FR"},
268aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                    {"Anglais (Canada)", "English (Canada)", "en_CA", "en_CA"},
269aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                    {"Anglais (Royaume-Uni)", "English (United Kingdom)", "en_GB", "en_GB"},
270aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                    {"Chinois", "中文", "zh", "zh"},
271aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                    {"Français", "Français", "fr", "fr"},
272aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                },
273aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                {{"en-gb", "fr", "zh-Hant", "zh-SG", "sr", "sr-Latn"},
274aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                    {"Anglais (Royaume-Uni)", "English (United Kingdom)", "en_GB", "en_GB"},
275f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert                    {"Chinois (simplifié, Singapour)", "中文(简体,新加坡)", "zh_SG", "zh_Hans_SG"},
276aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                    {"Chinois (traditionnel, Taïwan)", "中文(繁體,台灣)", "zh_Hant", "zh_Hant_TW"},
277aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                    {"Français", "Français", "fr", "fr"},
278aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                    {"Serbe (cyrillique)", "Српски (ћирилица)", "sr", "sr_Cyrl"},
279aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                    {"Serbe (latin)", "Srpski (latinica)", "sr_Latn", "sr_Latn"},
280aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                },
281aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                {{"fr-Cyrl", "fr-Arab"},
282aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                    {"Français (arabe)", "Français (arabe)", "fr_Arab", "fr_Arab"},
283aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                    {"Français (cyrillique)", "Français (cyrillique)", "fr_Cyrl", "fr_Cyrl"},
284aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                },
285aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                {{"fr-Cyrl-BE", "fr-Arab-CA"},
286aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                    {"Français (arabe, Canada)", "Français (arabe, Canada)", "fr_Arab_CA", "fr_Arab_CA"},
287aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                    {"Français (cyrillique, Belgique)", "Français (cyrillique, Belgique)", "fr_Cyrl_BE", "fr_Cyrl_BE"},
288aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                }
289aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        };
290aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        ULocale french = ULocale.FRENCH;
291aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        LocaleDisplayNames names = LocaleDisplayNames.getInstance(french,
292aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                DisplayContext.CAPITALIZATION_FOR_UI_LIST_OR_MENU);
293aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        for (Type type : DisplayContext.Type.values()) {
294aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            logln("Contexts: " + names.getContext(type).toString());
295aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        }
296aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        Collator collator = Collator.getInstance(french);
297aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
298aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        for (String[][] test : tests) {
299aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            Set<ULocale> list = new LinkedHashSet<ULocale>();
300aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            List<UiListItem> expected = new ArrayList<UiListItem>();
301aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            for (String item : test[0]) {
302aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                list.add(new ULocale(item));
303aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            }
304aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            for (int i = 1; i < test.length; ++i) {
305aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                String[] rawRow = test[i];
306aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                expected.add(new UiListItem(new ULocale(rawRow[2]), new ULocale(rawRow[3]), rawRow[0], rawRow[1]));
307aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            }
308aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            List<UiListItem> newList = names.getUiList(list, false, collator);
309aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            if (!expected.equals(newList)) {
310aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                if (expected.size() != newList.size()) {
311aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                    errln(list.toString() + ": wrong size" + expected + ", " + newList);
312aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                } else {
313aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                    errln(list.toString());
314aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                    for (int i = 0; i < expected.size(); ++i) {
315aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                        assertEquals(i+"", expected.get(i), newList.get(i));
316aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                    }
317aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                }
318aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            } else {
319aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                assertEquals(list.toString(), expected, newList);
320aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            }
321aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        }
322aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
323aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin
324f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert    @Test
325aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    public void TestIllformedLocale() {
326aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        ULocale french = ULocale.FRENCH;
327aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        Collator collator = Collator.getInstance(french);
328aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        LocaleDisplayNames names = LocaleDisplayNames.getInstance(french,
329aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                DisplayContext.CAPITALIZATION_FOR_UI_LIST_OR_MENU);
330aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        for (String malformed : Arrays.asList("en-a", "$", "ü--a", "en--US")) {
331aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            try {
332aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                Set<ULocale> supported = Collections.singleton(new ULocale(malformed));
333aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                names.getUiList(supported, false, collator);
334aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                assertNull("Failed to detect bogus locale «" + malformed + "»", supported);
335aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            } catch (IllformedLocaleException e) {
336aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin                logln("Successfully detected ill-formed locale «" + malformed + "»:" + e.getMessage());
337aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin            }
338aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin        }
339aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin    }
340aefe4d1f8f1773ead1a52f7a5d2c9e0009353600Paul Duffin}
341