/* ********************************************************************** * Copyright (c) 2004-2010, International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** * Author: Alan Liu * Created: January 14 2004 * Since: ICU 2.8 ********************************************************************** */ package com.ibm.icu.dev.test.util; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Hashtable; import java.util.Iterator; import java.util.Locale; import java.util.TreeMap; import com.ibm.icu.dev.test.TestFmwk; import com.ibm.icu.lang.UCharacter; import com.ibm.icu.text.BreakIterator; import com.ibm.icu.text.DateFormat; import com.ibm.icu.text.DecimalFormat; import com.ibm.icu.text.NumberFormat; import com.ibm.icu.text.SimpleDateFormat; import com.ibm.icu.text.NumberFormat.SimpleNumberFormatFactory; import com.ibm.icu.util.Calendar; import com.ibm.icu.util.IllformedLocaleException; import com.ibm.icu.util.LocaleData; import com.ibm.icu.util.ULocale; import com.ibm.icu.util.UResourceBundle; import com.ibm.icu.util.VersionInfo; import com.ibm.icu.util.ULocale.Builder; public class ULocaleTest extends TestFmwk { public static void main(String[] args) throws Exception { new ULocaleTest().run(args); } public void TestCalendar() { // TODO The CalendarFactory mechanism is not public, // so we can't test it yet. If it becomes public, // enable this code. // class CFactory implements CalendarFactory { // Locale loc; // Calendar proto; // public CFactory(Locale locale, Calendar prototype) { // loc = locale; // proto = prototype; // } // public Calendar create(TimeZone tz, Locale locale) { // // ignore tz -- not relevant to this test // return locale.equals(loc) ? // (Calendar) proto.clone() : null; // } // public String factoryName() { // return "CFactory"; // } // }; checkService("en_US_BROOKLYN", new ServiceFacade() { public Object create(ULocale req) { return Calendar.getInstance(req); } // }, null, new Registrar() { // public Object register(ULocale loc, Object prototype) { // CFactory f = new CFactory(loc, (Calendar) prototype); // return Calendar.register(f, loc); // } // public boolean unregister(Object key) { // return Calendar.unregister(key); // } }); } // Currency getLocale API is obsolete in 3.2. Since it now returns ULocale.ROOT, // and this is not equal to the requested locale zh_TW_TAIPEI, the // checkService call would always fail. So we now omit the test. /* public void TestCurrency() { checkService("zh_TW_TAIPEI", new ServiceFacade() { public Object create(ULocale req) { return Currency.getInstance(req); } }, null, new Registrar() { public Object register(ULocale loc, Object prototype) { return Currency.registerInstance((Currency) prototype, loc); } public boolean unregister(Object key) { return Currency.unregister(key); } }); } */ public void TestBreakIterator() { checkService("ja_JP_OSAKA", new ServiceFacade() { public Object create(ULocale req) { return BreakIterator.getWordInstance(req); } }, null, new Registrar() { public Object register(ULocale loc, Object prototype) { return BreakIterator.registerInstance( (BreakIterator) prototype, loc, BreakIterator.KIND_WORD); } public boolean unregister(Object key) { return BreakIterator.unregister(key); } }); } public void TestDateFormat() { checkService("de_CH_ZURICH", new ServiceFacade() { public Object create(ULocale req) { return DateFormat.getDateInstance(DateFormat.DEFAULT, req); } }, new Subobject() { public Object get(Object parent) { return ((SimpleDateFormat) parent).getDateFormatSymbols(); } }, null); } public void TestNumberFormat() { class NFactory extends SimpleNumberFormatFactory { NumberFormat proto; ULocale locale; public NFactory(ULocale loc, NumberFormat fmt) { super(loc); this.locale = loc; this.proto = fmt; } public NumberFormat createFormat(ULocale loc, int formatType) { return (NumberFormat) (locale.equals(loc) ? proto.clone() : null); } } checkService("fr_FR_NICE", new ServiceFacade() { public Object create(ULocale req) { return NumberFormat.getInstance(req); } }, new Subobject() { public Object get(Object parent) { return ((DecimalFormat) parent).getDecimalFormatSymbols(); } }, new Registrar() { public Object register(ULocale loc, Object prototype) { NFactory f = new NFactory(loc, (NumberFormat) prototype); return NumberFormat.registerFactory(f); } public boolean unregister(Object key) { return NumberFormat.unregister(key); } }); } public void TestSetULocaleKeywords() { ULocale uloc = new ULocale("en_Latn_US"); uloc = uloc.setKeywordValue("Foo", "FooValue"); if (!"en_Latn_US@foo=FooValue".equals(uloc.getName())) { errln("failed to add foo keyword, got: " + uloc.getName()); } uloc = uloc.setKeywordValue("Bar", "BarValue"); if (!"en_Latn_US@bar=BarValue;foo=FooValue".equals(uloc.getName())) { errln("failed to add bar keyword, got: " + uloc.getName()); } uloc = uloc.setKeywordValue("BAR", "NewBarValue"); if (!"en_Latn_US@bar=NewBarValue;foo=FooValue".equals(uloc.getName())) { errln("failed to change bar keyword, got: " + uloc.getName()); } uloc = uloc.setKeywordValue("BaR", null); if (!"en_Latn_US@foo=FooValue".equals(uloc.getName())) { errln("failed to delete bar keyword, got: " + uloc.getName()); } uloc = uloc.setKeywordValue(null, null); if (!"en_Latn_US".equals(uloc.getName())) { errln("failed to delete all keywords, got: " + uloc.getName()); } } /* * ticket#5060 */ public void TestJavaLocaleCompatibility() { Locale backupDefault = Locale.getDefault(); // Java Locale for ja_JP with Japanese calendar Locale jaJPJP = new Locale("ja", "JP", "JP"); Locale jaJP = new Locale("ja", "JP"); // Java Locale for th_TH with Thai digits Locale thTHTH = new Locale("th", "TH", "TH"); Calendar cal = Calendar.getInstance(jaJPJP); String caltype = cal.getType(); if (!caltype.equals("japanese")) { errln("FAIL: Invalid calendar type: " + caltype + " /expected: japanese"); } cal = Calendar.getInstance(jaJP); caltype = cal.getType(); if (!caltype.equals("gregorian")) { errln("FAIL: Invalid calendar type: " + caltype + " /expected: gregorian"); } // Default locale Locale.setDefault(jaJPJP); ULocale defUloc = ULocale.getDefault(); if (!defUloc.toString().equals("ja_JP@calendar=japanese")) { errln("FAIL: Invalid default ULocale: " + defUloc + " /expected: ja_JP@calendar=japanese"); } // Check calendar type cal = Calendar.getInstance(); caltype = cal.getType(); if (!caltype.equals("japanese")) { errln("FAIL: Invalid calendar type: " + caltype + " /expected: japanese"); } Locale.setDefault(backupDefault); // Set default via ULocale ULocale ujaJP_calJP = new ULocale("ja_JP@calendar=japanese"); ULocale.setDefault(ujaJP_calJP); if (!Locale.getDefault().equals(jaJPJP)) { errln("FAIL: ULocale#setDefault failed to set Java Locale ja_JP_JP /actual: " + Locale.getDefault()); } // Ticket#6672 - missing keywords defUloc = ULocale.getDefault(); if (!defUloc.equals(ujaJP_calJP)) { errln("FAIL: ULocale#getDefault returned " + defUloc + " /expected: ja_JP@calendar=japanese"); } // Set a incompatible base locale via Locale#setDefault Locale.setDefault(Locale.US); defUloc = ULocale.getDefault(); if (defUloc.equals(ujaJP_calJP)) { errln("FAIL: ULocale#getDefault returned " + defUloc + " /expected: " + ULocale.forLocale(Locale.US)); } Locale.setDefault(backupDefault); // We also want to map ICU locale ja@calendar=japanese to Java ja_JP_JP ULocale.setDefault(new ULocale("ja@calendar=japanese")); if (!Locale.getDefault().equals(jaJPJP)) { errln("FAIL: ULocale#setDefault failed to set Java Locale ja_JP_JP /actual: " + Locale.getDefault()); } Locale.setDefault(backupDefault); // Java no_NO_NY Locale noNONY = new Locale("no", "NO", "NY"); Locale.setDefault(noNONY); defUloc = ULocale.getDefault(); if (defUloc.toString().equals("nn_NY")) { errln("FAIL: Invalid default ULocale: " + defUloc + " /expected: nn_NY"); } Locale.setDefault(backupDefault); // Java th_TH_TH -> ICU th_TH@numbers=thai ULocale.setDefault(new ULocale("th@numbers=thai")); if (!Locale.getDefault().equals(thTHTH)) { errln("FAIL: ULocale#setDefault failed to set Java Locale th_TH_TH /actual: " + Locale.getDefault()); } Locale.setDefault(backupDefault); // Set default via ULocale ULocale.setDefault(new ULocale("nn_NO")); if (!Locale.getDefault().equals(noNONY)) { errln("FAIL: ULocale#setDefault failed to set Java Locale no_NO_NY /actual: " + Locale.getDefault()); } Locale.setDefault(backupDefault); // We also want to map ICU locale nn to Java no_NO_NY ULocale.setDefault(new ULocale("nn")); if (!Locale.getDefault().equals(noNONY)) { errln("FAIL: ULocale#setDefault failed to set Java Locale no_NO_NY /actual: " + Locale.getDefault()); } Locale.setDefault(backupDefault); } // ================= Infrastructure ================= /** * Compare two locale IDs. If they are equal, return 0. If `string' * starts with `prefix' plus an additional element, that is, string == * prefix + '_' + x, then return 1. Otherwise return a value < 0. */ static int loccmp(String string, String prefix) { int slen = string.length(), plen = prefix.length(); /* 'root' is "less than" everything */ if (prefix.equals("root")) { return string.equals("root") ? 0 : 1; } // ON JAVA (only -- not on C -- someone correct me if I'm wrong) // consider "" to be an alternate name for "root". if (plen == 0) { return slen == 0 ? 0 : 1; } if (!string.startsWith(prefix)) return -1; /* mismatch */ if (slen == plen) return 0; if (string.charAt(plen) == '_') return 1; return -2; /* false match, e.g. "en_USX" cmp "en_US" */ } /** * Check the relationship between requested locales, and report problems. * The caller specifies the expected relationships between requested * and valid (expReqValid) and between valid and actual (expValidActual). * Possible values are: * "gt" strictly greater than, e.g., en_US > en * "ge" greater or equal, e.g., en >= en * "eq" equal, e.g., en == en */ void checklocs(String label, String req, Locale validLoc, Locale actualLoc, String expReqValid, String expValidActual) { String valid = validLoc.toString(); String actual = actualLoc.toString(); int reqValid = loccmp(req, valid); int validActual = loccmp(valid, actual); boolean reqOK = (expReqValid.equals("gt") && reqValid > 0) || (expReqValid.equals("ge") && reqValid >= 0) || (expReqValid.equals("eq") && reqValid == 0); boolean valOK = (expValidActual.equals("gt") && validActual > 0) || (expValidActual.equals("ge") && validActual >= 0) || (expValidActual.equals("eq") && validActual == 0); if (reqOK && valOK) { logln("Ok: " + label + "; req=" + req + ", valid=" + valid + ", actual=" + actual); } else { errln("FAIL: " + label + "; req=" + req + ", valid=" + valid + ", actual=" + actual + (reqOK ? "" : "\n req !" + expReqValid + " valid") + (valOK ? "" : "\n val !" + expValidActual + " actual")); } } /** * Interface used by checkService defining a protocol to create an * object, given a requested locale. */ interface ServiceFacade { Object create(ULocale requestedLocale); } /** * Interface used by checkService defining a protocol to get a * contained subobject, given its parent object. */ interface Subobject { Object get(Object parent); } /** * Interface used by checkService defining a protocol to register * and unregister a service object prototype. */ interface Registrar { Object register(ULocale loc, Object prototype); boolean unregister(Object key); } /** * Use reflection to call getLocale() on the given object to * determine both the valid and the actual locale. Verify these * for correctness. */ void checkObject(String requestedLocale, Object obj, String expReqValid, String expValidActual) { Class[] getLocaleParams = new Class[] { ULocale.Type.class }; try { Class cls = obj.getClass(); Method getLocale = cls.getMethod("getLocale", getLocaleParams); ULocale valid = (ULocale) getLocale.invoke(obj, new Object[] { ULocale.VALID_LOCALE }); ULocale actual = (ULocale) getLocale.invoke(obj, new Object[] { ULocale.ACTUAL_LOCALE }); checklocs(cls.getName(), requestedLocale, valid.toLocale(), actual.toLocale(), expReqValid, expValidActual); } // Make the following exceptions _specific_ -- do not // catch(Exception), since that will catch the exception // that errln throws. catch(NoSuchMethodException e1) { // no longer an error, Currency has no getLocale // errln("FAIL: reflection failed: " + e1); } catch(SecurityException e2) { errln("FAIL: reflection failed: " + e2); } catch(IllegalAccessException e3) { errln("FAIL: reflection failed: " + e3); } catch(IllegalArgumentException e4) { errln("FAIL: reflection failed: " + e4); } catch(InvocationTargetException e5) { // no longer an error, Currency has no getLocale // errln("FAIL: reflection failed: " + e5); } } /** * Verify the correct getLocale() behavior for the given service. * @param requestedLocale the locale to request. This MUST BE * FAKE. In other words, it should be something like * en_US_FAKEVARIANT so this method can verify correct fallback * behavior. * @param svc a factory object that can create the object to be * tested. This isn't necessary here (one could just pass in the * object) but is required for the overload of this method that * takes a Registrar. */ void checkService(String requestedLocale, ServiceFacade svc) { checkService(requestedLocale, svc, null, null); } /** * Verify the correct getLocale() behavior for the given service. * @param requestedLocale the locale to request. This MUST BE * FAKE. In other words, it should be something like * en_US_FAKEVARIANT so this method can verify correct fallback * behavior. * @param svc a factory object that can create the object to be * tested. * @param sub an object that can be used to retrieve a subobject * which should also be tested. May be null. * @param reg an object that supplies the registration and * unregistration functionality to be tested. May be null. */ void checkService(String requestedLocale, ServiceFacade svc, Subobject sub, Registrar reg) { ULocale req = new ULocale(requestedLocale); Object obj = svc.create(req); checkObject(requestedLocale, obj, "gt", "ge"); if (sub != null) { Object subobj = sub.get(obj); checkObject(requestedLocale, subobj, "gt", "ge"); } if (reg != null) { logln("Info: Registering service"); Object key = reg.register(req, obj); Object objReg = svc.create(req); checkObject(requestedLocale, objReg, "eq", "eq"); if (sub != null) { Object subobj = sub.get(obj); // Assume subobjects don't come from services, so // their metadata should be structured normally. checkObject(requestedLocale, subobj, "gt", "ge"); } logln("Info: Unregistering service"); if (!reg.unregister(key)) { errln("FAIL: unregister failed"); } Object objUnreg = svc.create(req); checkObject(requestedLocale, objUnreg, "gt", "ge"); } } private static final int LOCALE_SIZE = 9; private static final String[][] rawData2 = new String[][]{ /* language code */ { "en", "fr", "ca", "el", "no", "zh", "de", "es", "ja" }, /* script code */ { "", "", "", "", "", "Hans", "", "", "" }, /* country code */ { "US", "FR", "ES", "GR", "NO", "CN", "DE", "", "JP" }, /* variant code */ { "", "", "", "", "NY", "", "", "", "" }, /* full name */ { "en_US", "fr_FR", "ca_ES", "el_GR", "no_NO_NY", "zh_Hans_CN", "de_DE@collation=phonebook", "es@collation=traditional", "ja_JP@calendar=japanese" }, /* ISO-3 language */ { "eng", "fra", "cat", "ell", "nor", "zho", "deu", "spa", "jpn" }, /* ISO-3 country */ { "USA", "FRA", "ESP", "GRC", "NOR", "CHN", "DEU", "", "JPN" }, /* LCID */ { "409", "40c", "403", "408", "814", "804", "407", "a", "411" }, /* display language (English) */ { "English", "French", "Catalan", "Greek", "Norwegian", "Chinese", "German", "Spanish", "Japanese" }, /* display script code (English) */ { "", "", "", "", "", "Simplified Han", "", "", "" }, /* display country (English) */ { "United States", "France", "Spain", "Greece", "Norway", "China", "Germany", "", "Japan" }, /* display variant (English) */ { "", "", "", "", "NY", "", "", "", "" }, /* display name (English) */ { "English (United States)", "French (France)", "Catalan (Spain)", "Greek (Greece)", "Norwegian (Norway, NY)", "Chinese (Simplified Han, China)", "German (Germany, Collation=Phonebook Order)", "Spanish (Collation=Traditional)", "Japanese (Japan, Calendar=Japanese Calendar)" }, /* display language (French) */ { "anglais", "fran\\u00E7ais", "catalan", "grec", "norv\\u00E9gien", "chinois", "allemand", "espagnol", "japonais" }, /* display script code (French) */ { "", "", "", "", "", "Hans", "", "", "" }, /* display country (French) */ { "\\u00C9tats-Unis", "France", "Espagne", "Gr\\u00E8ce", "Norv\\u00E8ge", "Chine", "Allemagne", "", "Japon" }, /* display variant (French) */ { "", "", "", "", "NY", "", "", "", "" }, /* display name (French) */ { "anglais (\\u00C9tats-Unis)", "fran\\u00E7ais (France)", "catalan (Espagne)", "grec (Gr\\u00E8ce)", "norv\\u00E9gien (Norv\\u00E8ge, NY)", "chinois (Hans, Chine)", "allemand (Allemagne, Ordonnancement=Ordre de l'annuaire)", "espagnol (Ordonnancement=Ordre traditionnel)", "japonais (Japon, Calendrier=Calendrier japonais)" }, /* display language (Catalan) */ { "angl\\u00E8s", "franc\\u00E8s", "catal\\u00E0", "grec", "noruec", "xin\\u00E9s", "alemany", "espanyol", "japon\\u00E8s" }, /* display script code (Catalan) */ { "", "", "", "", "", "Hans", "", "", "" }, /* display country (Catalan) */ { "Estats Units", "Fran\\u00E7a", "Espanya", "Gr\\u00E8cia", "Noruega", "Xina", "Alemanya", "", "Jap\\u00F3" }, /* display variant (Catalan) */ { "", "", "", "", "NY", "", "", "", "" }, /* display name (Catalan) */ { "angl\\u00E8s (Estats Units)", "franc\\u00E8s (Fran\\u00E7a)", "catal\\u00E0 (Espanya)", "grec (Gr\\u00E8cia)", "noruec (Noruega, NY)", "xin\\u00E9s (Hans, Xina)", "alemany (Alemanya, COLLATION=PHONEBOOK)", "espanyol (COLLATION=TRADITIONAL)", "japon\\u00E8s (Jap\\u00F3, CALENDAR=JAPANESE)" }, /* display language (Greek) */ { "\\u0391\\u03b3\\u03b3\\u03bb\\u03b9\\u03ba\\u03ac", "\\u0393\\u03b1\\u03bb\\u03bb\\u03b9\\u03ba\\u03ac", "\\u039a\\u03b1\\u03c4\\u03b1\\u03bb\\u03b1\\u03bd\\u03b9\\u03ba\\u03ac", "\\u0395\\u03bb\\u03bb\\u03b7\\u03bd\\u03b9\\u03ba\\u03ac", "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03b9\\u03ba\\u03ac", "\\u039A\\u03B9\\u03BD\\u03B5\\u03B6\\u03B9\\u03BA\\u03AC", "\\u0393\\u03B5\\u03C1\\u03BC\\u03B1\\u03BD\\u03B9\\u03BA\\u03AC", "\\u0399\\u03C3\\u03C0\\u03B1\\u03BD\\u03B9\\u03BA\\u03AC", "\\u0399\\u03B1\\u03C0\\u03C9\\u03BD\\u03B9\\u03BA\\u03AC" }, /* display script code (Greek) */ { "", "", "", "", "", "Hans", "", "", "" }, /* display country (Greek) */ { "\\u0397\\u03bd\\u03c9\\u03bc\\u03ad\\u03bd\\u03b5\\u03c2 \\u03a0\\u03bf\\u03bb\\u03b9\\u03c4\\u03b5\\u03af\\u03b5\\u03c2", "\\u0393\\u03b1\\u03bb\\u03bb\\u03af\\u03b1", "\\u0399\\u03c3\\u03c0\\u03b1\\u03bd\\u03af\\u03b1", "\\u0395\\u03bb\\u03bb\\u03ac\\u03b4\\u03b1", "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03af\\u03b1", "\\u039A\\u03AF\\u03BD\\u03B1", "\\u0393\\u03B5\\u03C1\\u03BC\\u03B1\\u03BD\\u03AF\\u03B1", "", "\\u0399\\u03B1\\u03C0\\u03C9\\u03BD\\u03AF\\u03B1" }, /* display variant (Greek) */ { "", "", "", "", "NY", "", "", "", "" }, /* TODO: currently there is no translation for NY in Greek fix this test when we have it */ /* display name (Greek) */ { "\\u0391\\u03b3\\u03b3\\u03bb\\u03b9\\u03ba\\u03ac (\\u0397\\u03bd\\u03c9\\u03bc\\u03ad\\u03bd\\u03b5\\u03c2 \\u03a0\\u03bf\\u03bb\\u03b9\\u03c4\\u03b5\\u03af\\u03b5\\u03c2)", "\\u0393\\u03b1\\u03bb\\u03bb\\u03b9\\u03ba\\u03ac (\\u0393\\u03b1\\u03bb\\u03bb\\u03af\\u03b1)", "\\u039a\\u03b1\\u03c4\\u03b1\\u03bb\\u03b1\\u03bd\\u03b9\\u03ba\\u03ac (\\u0399\\u03c3\\u03c0\\u03b1\\u03bd\\u03af\\u03b1)", "\\u0395\\u03bb\\u03bb\\u03b7\\u03bd\\u03b9\\u03ba\\u03ac (\\u0395\\u03bb\\u03bb\\u03ac\\u03b4\\u03b1)", "\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03b9\\u03ba\\u03ac (\\u039d\\u03bf\\u03c1\\u03b2\\u03b7\\u03b3\\u03af\\u03b1, NY)", "\\u039A\\u03B9\\u03BD\\u03B5\\u03B6\\u03B9\\u03BA\\u03AC (Hans, \\u039A\\u03AF\\u03BD\\u03B1)", "\\u0393\\u03B5\\u03C1\\u03BC\\u03B1\\u03BD\\u03B9\\u03BA\\u03AC (\\u0393\\u03B5\\u03C1\\u03BC\\u03B1\\u03BD\\u03AF\\u03B1, COLLATION=PHONEBOOK)", "\\u0399\\u03C3\\u03C0\\u03B1\\u03BD\\u03B9\\u03BA\\u03AC (COLLATION=TRADITIONAL)", "\\u0399\\u03B1\\u03C0\\u03C9\\u03BD\\u03B9\\u03BA\\u03AC (\\u0399\\u03B1\\u03C0\\u03C9\\u03BD\\u03AF\\u03B1, CALENDAR=JAPANESE)" } }; // private static final int ENGLISH = 0; // private static final int FRENCH = 1; // private static final int CATALAN = 2; // private static final int GREEK = 3; // private static final int NORWEGIAN = 4; private static final int LANG = 0; private static final int SCRIPT = 1; private static final int CTRY = 2; private static final int VAR = 3; private static final int NAME = 4; // private static final int LANG3 = 5; // private static final int CTRY3 = 6; // private static final int LCID = 7; // private static final int DLANG_EN = 8; // private static final int DSCRIPT_EN = 9; // private static final int DCTRY_EN = 10; // private static final int DVAR_EN = 11; // private static final int DNAME_EN = 12; // private static final int DLANG_FR = 13; // private static final int DSCRIPT_FR = 14; // private static final int DCTRY_FR = 15; // private static final int DVAR_FR = 16; // private static final int DNAME_FR = 17; // private static final int DLANG_CA = 18; // private static final int DSCRIPT_CA = 19; // private static final int DCTRY_CA = 20; // private static final int DVAR_CA = 21; // private static final int DNAME_CA = 22; // private static final int DLANG_EL = 23; // private static final int DSCRIPT_EL = 24; // private static final int DCTRY_EL = 25; // private static final int DVAR_EL = 26; // private static final int DNAME_EL = 27; public void TestBasicGetters() { int i; logln("Testing Basic Getters\n"); for (i = 0; i < LOCALE_SIZE; i++) { String testLocale=(rawData2[NAME][i]); logln("Testing "+ testLocale+".....\n"); String lang =ULocale.getLanguage(testLocale); if (0 !=lang.compareTo(rawData2[LANG][i])) { errln(" Language code mismatch: "+lang+" versus "+ rawData2[LANG][i]); } String ctry=ULocale.getCountry(testLocale); if (0 !=ctry.compareTo(rawData2[CTRY][i])) { errln(" Country code mismatch: "+ctry+" versus "+ rawData2[CTRY][i]); } String var=ULocale.getVariant(testLocale); if (0 !=var.compareTo(rawData2[VAR][i])) { errln(" Variant code mismatch: "+var+" versus "+ rawData2[VAR][i]); } String name = ULocale.getName(testLocale); if (0 !=name.compareTo(rawData2[NAME][i])) { errln(" Name mismatch: "+name+" versus "+ rawData2[NAME][i]); } } } public void TestPrefixes() { // POSIX ids are no longer handled by getName, so POSIX failures are ignored final String [][] testData = new String[][]{ /* null canonicalize() column means "expect same as getName()" */ {"sv", "", "FI", "AL", "sv-fi-al", "sv_FI_AL", null}, {"en", "", "GB", "", "en-gb", "en_GB", null}, {"i-hakka", "", "MT", "XEMXIJA", "i-hakka_MT_XEMXIJA", "i-hakka_MT_XEMXIJA", null}, {"i-hakka", "", "CN", "", "i-hakka_CN", "i-hakka_CN", null}, {"i-hakka", "", "MX", "", "I-hakka_MX", "i-hakka_MX", null}, {"x-klingon", "", "US", "SANJOSE", "X-KLINGON_us_SANJOSE", "x-klingon_US_SANJOSE", null}, {"mr", "", "", "", "mr.utf8", "mr.utf8", "mr"}, {"de", "", "TV", "", "de-tv.koi8r", "de_TV.koi8r", "de_TV"}, {"x-piglatin", "", "ML", "", "x-piglatin_ML.MBE", "x-piglatin_ML.MBE", "x-piglatin_ML"}, /* Multibyte English */ {"i-cherokee", "","US", "", "i-Cherokee_US.utf7", "i-cherokee_US.utf7", "i-cherokee_US"}, {"x-filfli", "", "MT", "FILFLA", "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA.gb-18030", "x-filfli_MT_FILFLA"}, {"no", "", "NO", "NY_B", "no-no-ny.utf32@B", "no_NO_NY.utf32@B", "no_NO_NY_B"}, {"no", "", "NO", "B", "no-no.utf32@B", "no_NO.utf32@B", "no_NO_B"}, {"no", "", "", "NY", "no__ny", "no__NY", null}, {"no", "", "", "NY", "no@ny", "no@ny", "no__NY"}, {"el", "Latn", "", "", "el-latn", "el_Latn", null}, {"en", "Cyrl", "RU", "", "en-cyrl-ru", "en_Cyrl_RU", null}, {"zh", "Hant", "TW", "STROKE", "zh-hant_TW_STROKE", "zh_Hant_TW_STROKE", "zh_Hant_TW@collation=stroke"}, {"zh", "Hant", "CN", "STROKE", "zh-hant_CN_STROKE", "zh_Hant_CN_STROKE", "zh_Hant_CN@collation=stroke"}, {"zh", "Hant", "TW", "PINYIN", "zh-hant_TW_PINYIN", "zh_Hant_TW_PINYIN", "zh_Hant_TW@collation=pinyin"}, {"qq", "Qqqq", "QQ", "QQ", "qq_Qqqq_QQ_QQ", "qq_Qqqq_QQ_QQ", null}, {"qq", "Qqqq", "", "QQ", "qq_Qqqq__QQ", "qq_Qqqq__QQ", null}, {"12", "3456", "78", "90", "12_3456_78_90", "12_3456_78_90", null}, /* total garbage */ // odd cases {"", "", "", "", "@FOO=bar", "@foo=bar", null}, {"", "", "", "", "_@FOO=bar", "@foo=bar", null}, {"", "", "", "", "__@FOO=bar", "@foo=bar", null}, {"", "", "", "FOO", "__foo@FOO=bar", "__FOO@foo=bar", null}, // we have some of these prefixes }; String loc, buf,buf1; final String [] testTitles = { "ULocale.getLanguage()", "ULocale.getScript()", "ULocale.getCountry()", "ULocale.getVariant()", "name", "ULocale.getName()", "canonicalize()", }; ULocale uloc; for(int row=0;row ["+buf+"]"); String expected = testData[row][n]; if (expected == null && n == (NAME+2)) { expected = testData[row][NAME+1]; } // ignore POSIX failures in getName, we don't spec behavior in this case if (n == NAME+1 && (expected.indexOf('.') != -1 || expected.indexOf('@') != -1)) { continue; } if(buf.compareTo(expected)!=0) { errln("#"+row+": "+testTitles[n]+" on "+loc+": -> ["+buf+"] (expected '"+expected+"'!)"); } if(buf1.compareTo(expected)!=0) { errln("#"+row+": "+testTitles[n]+" on ULocale object "+loc+": -> ["+buf1+"] (expected '"+expected+"'!)"); } } } } public void TestObsoleteNames(){ final String[][] tests = new String[][]{ /* locale, language3, language2, Country3, country2 */ { "eng_USA", "eng", "en", "USA", "US" }, { "kok", "kok", "kok", "", "" }, { "in", "ind", "in", "", "" }, { "id", "ind", "id", "", "" }, /* NO aliasing */ { "sh", "srp", "sh", "", "" }, { "zz_CS", "", "zz", "SCG", "CS" }, { "zz_FX", "", "zz", "FXX", "FX" }, { "zz_RO", "", "zz", "ROU", "RO" }, { "zz_TP", "", "zz", "TMP", "TP" }, { "zz_TL", "", "zz", "TLS", "TL" }, { "zz_ZR", "", "zz", "ZAR", "ZR" }, { "zz_FXX", "", "zz", "FXX", "FX" }, /* no aliasing. Doesn't go to PS(PSE). */ { "zz_ROM", "", "zz", "ROU", "RO" }, { "zz_ROU", "", "zz", "ROU", "RO" }, { "zz_ZAR", "", "zz", "ZAR", "ZR" }, { "zz_TMP", "", "zz", "TMP", "TP" }, { "zz_TLS", "", "zz", "TLS", "TL" }, { "zz_YUG", "", "zz", "YUG", "YU" }, { "mlt_PSE", "mlt", "mt", "PSE", "PS" }, { "iw", "heb", "iw", "", "" }, { "ji", "yid", "ji", "", "" }, { "jw", "jaw", "jw", "", "" }, { "sh", "srp", "sh", "", "" }, { "", "", "", "", "" } }; for(int i=0;i " + name + ", " + l.getDisplayName(ULocale.GERMAN) + ", " + l.getDisplayName(ULocale.FRANCE)); String language = l.getDisplayLanguage(); String script = l.getDisplayScript(); String country = l.getDisplayCountry(); String variant = l.getDisplayVariant(); checkName(name, language, script, country, variant, ULocale.getDefault()); for (int j = 0; j < locales.length; ++j) { ULocale dl = locales[j]; name = l.getDisplayName(dl); language = l.getDisplayLanguage(dl); script = l.getDisplayScript(dl); country = l.getDisplayCountry(dl); variant = l.getDisplayVariant(dl); if (!checkName(name, language, script, country, variant, dl)) { break; } } } } // spot check { ULocale[] locales = { ULocale.US, ULocale.GERMANY, ULocale.FRANCE }; String[] names = { "Chinese (China)", "Chinesisch (China)", "chinois (Chine)" }; String[] names2 = { "Simplified Chinese (China)", "Chinesisch (vereinfacht) (China)", "chinois simplifi\u00E9 (Chine)" }; ULocale locale = new ULocale("zh_CN"); ULocale locale2 = new ULocale("zh_Hans_CN"); for (int i = 0; i < locales.length; ++i) { String name = locale.getDisplayName(locales[i]); if (!names[i].equals(name)) { errln("expected '" + names[i] + "' but got '" + name + "'"); } } for (int i = 0; i < locales.length; ++i) { String name = locale2.getDisplayNameWithDialect(locales[i]); if (!names2[i].equals(name)) { errln("expected '" + names2[i] + "' but got '" + name + "'"); } } } } private boolean checkName(String name, String language, String script, String country, String variant, ULocale dl) { if (language.length() > 0 && name.indexOf(language) == -1) { errln("loc: " + dl + " name '" + name + "' does not contain language '" + language + "'"); return false; } if (script.length() > 0 && name.indexOf(script) == -1) { errln("loc: " + dl + " name '" + name + "' does not contain script '" + script + "'"); return false; } if (country.length() > 0 && name.indexOf(country) == -1) { errln("loc: " + dl + " name '" + name + "' does not contain country '" + country + "'"); return false; } if (variant.length() > 0 && name.indexOf(variant) == -1) { errln("loc: " + dl + " name '" + name + "' does not contain variant '" + variant + "'"); return false; } return true; } public void TestCoverage() { { //Cover displayXXX int i, j; String localeID="zh_CN"; String name, language, script, country, variant; logln("Covering APIs with signature displayXXX(String, String)"); for (i = 0; i < LOCALE_SIZE; i++) { //localeID String String testLocale=(rawData2[NAME][i]); logln("Testing "+ testLocale+"....."); name = ULocale.getDisplayName(localeID, testLocale); language = ULocale.getDisplayLanguage(localeID, testLocale); script = ULocale.getDisplayScript(localeID, testLocale); country = ULocale.getDisplayCountry(localeID, testLocale); variant = ULocale.getDisplayVariant(localeID, testLocale); if (!checkName(name, language, script, country, variant, new ULocale(testLocale))) { break; } } logln("Covering APIs with signature displayXXX(String, ULocale)\n"); for (j = 0; j < LOCALE_SIZE; j++) { String testLocale=(rawData2[NAME][j]); ULocale loc = new ULocale(testLocale); logln("Testing "+ testLocale+"....."); name = ULocale.getDisplayName(localeID, loc); language = ULocale.getDisplayLanguage(localeID, loc); script = ULocale.getDisplayScript(localeID, loc); country = ULocale.getDisplayCountry(localeID, loc); variant = ULocale.getDisplayVariant(localeID, loc); if (!checkName(name, language, script, country, variant, loc)) { break; } } } ULocale loc1 = new ULocale("en_US_BROOKLYN"); ULocale loc2 = new ULocale("en","US","BROOKLYN"); if (!loc2.equals(loc1)){ errln("ULocale.ULocale(String a, String b, String c)"); } ULocale loc3 = new ULocale("en_US"); ULocale loc4 = new ULocale("en","US"); if (!loc4.equals(loc3)){ errln("ULocale.ULocale(String a, String b)"); } ULocale loc5 = (ULocale) loc4.clone(); if (!loc5.equals(loc4)){ errln("ULocale.clone should get the same ULocale"); } ULocale.getISOCountries(); // To check the result ?! } public void TestBamBm() { // "bam" shouldn't be there since the official code is 'bm' String[] isoLanguages = ULocale.getISOLanguages(); for (int i = 0; i < isoLanguages.length; ++i) { if ("bam".equals(isoLanguages[i])) { errln("found bam"); } if (i > 0 && isoLanguages[i].compareTo(isoLanguages[i-1]) <= 0) { errln("language list out of order: '" + isoLanguages[i] + " <= " + isoLanguages[i-1]); } } } public void TestDisplayKeyword() { //prepare testing data initHashtable(); String[] data = {"en_US@collation=direct;calendar=islamic-civil", "zh_Hans@collation=pinyin;calendar=chinese", "foo_Bar_BAZ@collation=traditional;calendar=buddhist"}; for (int i = 0; i < data.length; i++) { String localeID = data[i]; logln(""); logln("Testing locale " + localeID + " ..."); ULocale loc = new ULocale(localeID); Iterator it = loc.getKeywords(); Iterator it2 = ULocale.getKeywords(localeID); //it and it2 are not equal here. No way to verify their equivalence yet. while(it.hasNext()) { String key = (String)it.next(); String key2 = (String)it2.next(); if (!key.equals(key2)) { errln("FAIL: static and non-static getKeywords returned different results."); } //To verify display of Keyword // display the above key in English String s0 = ULocale.getDisplayKeyword(key); //display in default locale String s1 = ULocale.getDisplayKeyword(key, ULocale.US); String s2 = ULocale.getDisplayKeyword(key, "en_US"); if (!s1.equals(s2)) { errln ("FAIL: one of the getDisplayKeyword methods failed."); } if (ULocale.getDefault().equals(ULocale.US) && !s1.equals(s0)) { errln ("FAIL: getDisplayKeyword methods failed for the default locale."); } if (!s1.equals(h[0].get(key))) { warnln("Locale " + localeID + " getDisplayKeyword for key: " + key + " in English expected \"" + h[0].get(key) + "\" saw \"" + s1 + "\" instead"); } else { logln("OK: getDisplayKeyword for key: " + key + " in English got " + s1); } // display the key in S-Chinese s1 = ULocale.getDisplayKeyword(key, ULocale.CHINA); s2 = ULocale.getDisplayKeyword(key, "zh_Hans"); if (!s1.equals(s2)) { errln ("one of the getDisplayKeyword methods failed."); } if (!s1.equals(h[1].get(key))) { warnln("Locale " + localeID + " getDisplayKeyword for key: " + key + " in Chinese expected \"" + h[1].get(key) + "\" saw \"" + s1 + "\" instead"); } else { logln("OK: getDisplayKeyword for key: " + key + " in Chinese got " + s1); } //To verify display of Keyword values String type = loc.getKeywordValue(key); // display type in English String ss0 = loc.getDisplayKeywordValue(key); String ss1 = loc.getDisplayKeywordValue(key, ULocale.US); String ss2 = ULocale.getDisplayKeywordValue(localeID, key, "en_US"); String ss3 = ULocale.getDisplayKeywordValue(localeID, key, ULocale.US); if (!ss1.equals(ss2) || !ss1.equals(ss3)) { errln ("FAIL: one of the getDisplayKeywordValue methods failed."); } if (ULocale.getDefault().equals(ULocale.US) && !ss1.equals(ss0)) { errln ("FAIL: getDisplayKeyword methods failed for the default locale."); } if (!ss1.equals(h[0].get(type))) { warnln(" Locale " + localeID + " getDisplayKeywordValue for key: " + key + " in English expected \"" + h[0].get(type) + "\" saw \"" + ss1 + "\" instead"); } else { logln("OK: getDisplayKeywordValue for key: " + key + " in English got " + ss1); } // display type in Chinese ss0 = loc.getDisplayKeywordValue(key); ss1 = loc.getDisplayKeywordValue(key, ULocale.CHINA); ss2 = ULocale.getDisplayKeywordValue(localeID, key, "zh_Hans"); ss3 = ULocale.getDisplayKeywordValue(localeID, key, ULocale.CHINA); if (!ss1.equals(ss2) || !ss1.equals(ss3)) { warnln ("one of the getDisplayKeywordValue methods failed."); } if (!ss1.equals(h[1].get(type))) { warnln("Locale " + localeID + " getDisplayKeywordValue for key: " + key + " in Chinese expected \"" + h[1].get(type) + "\" saw \"" + ss1 + "\" instead"); } else { logln("OK: getDisplayKeywordValue for key: " + key + " in Chinese got " + ss1); } } } } private void initHashtable() { h[0] = new Hashtable(); h[1] = new Hashtable(); //display in English h[0].put("collation", "collation"); h[0].put("calendar", "calendar"); h[0].put("currency", "Currency"); h[0].put("phonebook", "Phonebook Order"); h[0].put("pinyin", "Simplified Chinese Pinyin Sort Order"); h[0].put("traditional", "Traditional Sort Order"); h[0].put("stroke", "Stroke Order"); h[0].put("direct", "Direct Sort Order"); h[0].put("japanese", "Japanese Calendar"); h[0].put("buddhist", "Buddhist Calendar"); h[0].put("islamic", "Islamic Calendar"); h[0].put("islamic-civil", "Islamic-Civil Calendar" ); h[0].put("hebrew", "Hebrew Calendar"); h[0].put("chinese", "Chinese Calendar"); h[0].put("gregorian", "Gregorian Calendar" ); //display in S-Chinese h[1].put("collation", "\u5BF9\u7167"); h[1].put("calendar", "\u65E5\u5386"); h[1].put("currency", "\u8D27\u5E01"); h[1].put("direct", "\u987A\u5E8F"); h[1].put("phonebook", "\u7535\u8BDD\u7C3F\u987A\u5E8F"); h[1].put("pinyin", "\u62FC\u97F3\u987a\u5e8f"); h[1].put("stroke", "\u7B14\u5212\u987A\u5E8F"); h[1].put("traditional", "\u4F20\u7EDF\u5386\u6CD5"); h[1].put("japanese", "\u65E5\u672C\u65E5\u5386"); h[1].put("buddhist", "\u4F5B\u6559\u65E5\u5386"); h[1].put("islamic", "\u4F0A\u65AF\u5170\u65E5\u5386"); h[1].put("islamic-civil", "\u4F0A\u65AF\u5170\u5E0C\u5409\u6765\u5386"); h[1].put("hebrew", "\u5E0C\u4F2F\u6765\u65E5\u5386"); h[1].put("chinese", "\u519C\u5386"); h[1].put("gregorian", "\u516C\u5386"); } //Hashtables for storing expected display of keys/types of locale in English and Chinese private static Hashtable[] h = new Hashtable[2]; private static final String ACCEPT_LANGUAGE_TESTS[][] = { /*# result fallback? */ /*0*/ { "mt_MT", "false" }, /*1*/ { "en", "false" }, /*2*/ { "en", "true" }, // fell back from en-zzz to en /*3*/ { null, "true" }, /*4*/ { "es", "false" }, /*5*/ { "de", "false" }}; private static final String ACCEPT_LANGUAGE_HTTP[] = { /*0*/ "mt-mt, ja;q=0.76, en-us;q=0.95, en;q=0.92, en-gb;q=0.89, fr;q=0.87, iu-ca;q=0.84, iu;q=0.82, ja-jp;q=0.79, mt;q=0.97, de-de;q=0.74, de;q=0.71, es;q=0.68, it-it;q=0.66, it;q=0.63, vi-vn;q=0.61, vi;q=0.58, nl-nl;q=0.55, nl;q=0.53, th-th-traditional;q=.01", /*1*/ "ja;q=0.5, en;q=0.8, tlh", /*2*/ "en-zzz, de-lx;q=0.8", /*3*/ "mga-ie;q=0.9, tlh", /*4*/ "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "+ "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "+ "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "+ "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "+ "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "+ "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "+ "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "+ "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "+ "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "+ "xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, xxx-yyy;q=.01, "+ "es", /*5*/ "de;q=.9, fr;q=.9, xxx-yyy, sr;q=.8"}; public void TestAcceptLanguage() { for(int i = 0 ; i < (ACCEPT_LANGUAGE_HTTP.length); i++) { Boolean expectBoolean = new Boolean(ACCEPT_LANGUAGE_TESTS[i][1]); String expectLocale=ACCEPT_LANGUAGE_TESTS[i][0]; logln("#" + i + ": expecting: " + expectLocale + " (" + expectBoolean + ")"); boolean r[] = { false }; ULocale n = ULocale.acceptLanguage(ACCEPT_LANGUAGE_HTTP[i], r); if((n==null)&&(expectLocale!=null)) { errln("result was null! line #" + i); continue; } if(((n==null)&&(expectLocale==null)) || (n.toString().equals(expectLocale))) { logln(" locale: OK." ); } else { errln("expected " + expectLocale + " but got " + n.toString()); } if(expectBoolean.equals(new Boolean(r[0]))) { logln(" bool: OK."); } else { errln("bool: not OK, was " + new Boolean(r[0]).toString() + " expected " + expectBoolean.toString()); } } } private ULocale[] StringToULocaleArray(String acceptLanguageList){ //following code is copied from //ULocale.acceptLanguage(String acceptLanguageList, ULocale[] availableLocales, boolean[] fallback) class ULocaleAcceptLanguageQ implements Comparable { private double q; private double serial; public ULocaleAcceptLanguageQ(double theq, int theserial) { q = theq; serial = theserial; } public int compareTo(Object o) { ULocaleAcceptLanguageQ other = (ULocaleAcceptLanguageQ) o; if(q > other.q) { // reverse - to sort in descending order return -1; } else if(q < other.q) { return 1; } if(serial < other.serial) { return -1; } else if(serial > other.serial) { return 1; } else { return 0; // same object } } } // 1st: parse out the acceptLanguageList into an array TreeMap map = new TreeMap(); final int l = acceptLanguageList.length(); int n; for(n=0;n 0) { ULocale org = new ULocale(maximal); ULocale res = ULocale.minimizeSubtags(org); String exp = full_data[i][2]; if (exp.length() == 0) { if (!org.equals(res)) { errln("Original: " + full_data[i][1] + " expected: " + exp + " - but got " + res.toString()); } } else if (!res.toString().equals(exp)) { errln("Original: " + full_data[i][1] + " expected: " + exp + " - but got " + res.toString()); } } } } public void TestCLDRVersion() { //VersionInfo zeroVersion = VersionInfo.getInstance(0, 0, 0, 0); VersionInfo testExpect; VersionInfo testCurrent; VersionInfo cldrVersion; cldrVersion = LocaleData.getCLDRVersion(); this.logln("uloc_getCLDRVersion() returned: '"+cldrVersion+"'"); // why isn't this public for tests somewhere? final ClassLoader testLoader = ICUResourceBundleTest.class.getClassLoader(); UResourceBundle bundle = (UResourceBundle) UResourceBundle.getBundleInstance("com/ibm/icu/dev/data/testdata", ULocale.ROOT, testLoader); testExpect = VersionInfo.getInstance(bundle.getString("ExpectCLDRVersionAtLeast")); testCurrent = VersionInfo.getInstance(bundle.getString("CurrentCLDRVersion")); logln("(data) ExpectCLDRVersionAtLeast { "+testExpect+""); if(cldrVersion.compareTo(testExpect)<0) { errln("CLDR version is too old, expect at least "+testExpect+"."); } int r = cldrVersion.compareTo(testCurrent); if ( r < 0 ) { logln("CLDR version is behind 'current' (for testdata/root.txt) "+testCurrent+". Some things may fail.\n"); } else if ( r > 0) { logln("CLDR version is ahead of 'current' (for testdata/root.txt) "+testCurrent+". Some things may fail.\n"); } else { // CLDR version is OK. } } public void TestToLanguageTag() { final String[][] locale_to_langtag = { {"", "und"}, {"en", "en"}, {"en_US", "en-US"}, {"iw_IL", "he-IL"}, {"sr_Latn_SR", "sr-Latn-SR"}, {"en__POSIX", "en-posix"}, // {"en_POSIX", "en"}, /* ICU4J locale parser successfully parse en_POSIX as language:en/variant:POSIX */ {"und_555", "und-555"}, {"123", "und"}, {"%$#&", "und"}, {"_Latn", "und-Latn"}, {"_DE", "und-DE"}, {"und_FR", "und-FR"}, {"th_TH_TH", "th-TH-x-variant-th"}, {"bogus", "bogus"}, {"foooobarrr", "und"}, //{"az_AZ_CYRL", "az-cyrl-az"}, /* ICU4J does not have this specia locale mapping */ {"aa_BB_CYRL", "aa-BB-x-variant-cyrl"}, {"en_US_1234", "en-US-1234"}, {"en_US_VARIANTA_VARIANTB", "en-US-varianta-variantb"}, {"en_US_VARIANTB_VARIANTA", "en-US-variantb-varianta"}, {"ja__9876_5432", "ja-9876-5432"}, {"zh_Hant__VAR", "zh-Hant-x-variant-var"}, {"es__BADVARIANT_GOODVAR", "es"}, {"es__GOODVAR_BAD_BADVARIANT", "es-goodvar-x-variant-bad"}, {"en@calendar=gregorian", "en-u-ca-gregory"}, {"de@collation=phonebook;calendar=gregorian", "de-u-ca-gregory-co-phonebk"}, {"th@numbers=thai;z=extz;x=priv-use;a=exta", "th-a-exta-u-nu-thai-z-extz-x-priv-use"}, {"en@timezone=America/New_York;calendar=japanese", "en-u-ca-japanese-tz-usnyc"}, {"en@timezone=US/Eastern", "en-u-tz-usnyc"}, {"en@x=x-y-z;a=a-b-c", "en-x-x-y-z"}, {"it@collation=badcollationtype;colStrength=identical;cu=usd-eur", "it-u-ks-identic"}, }; for (int i = 0; i < locale_to_langtag.length; i++) { ULocale loc = new ULocale(locale_to_langtag[i][0]); String langtag = loc.toLanguageTag(); if (!langtag.equals(locale_to_langtag[i][1])) { errln("FAIL: toLanguageTag returned language tag [" + langtag + "] for locale [" + loc + "] - expected: [" + locale_to_langtag[i][1] + "]"); } } } public void TestForLanguageTag() { final Integer NOERROR = Integer.valueOf(-1); final Object[][] langtag_to_locale = { {"en", "en", NOERROR}, {"en-us", "en_US", NOERROR}, {"und-us", "_US", NOERROR}, {"und-latn", "_Latn", NOERROR}, {"en-us-posix", "en_US_POSIX", NOERROR}, {"de-de_euro", "de", Integer.valueOf(3)}, {"kok-in", "kok_IN", NOERROR}, {"123", "", Integer.valueOf(0)}, {"en_us", "", Integer.valueOf(0)}, {"en-latn-x", "en_Latn", Integer.valueOf(8)}, {"art-lojban", "jbo", NOERROR}, {"zh-hakka", "hak", NOERROR}, {"zh-cmn-CH", "cmn_CH", NOERROR}, {"xxx-yy", "xxx_YY", NOERROR}, {"fr-234", "fr_234", NOERROR}, {"i-default", "", NOERROR}, {"i-test", "", Integer.valueOf(0)}, {"ja-jp-jp", "ja_JP", Integer.valueOf(6)}, {"bogus", "bogus", NOERROR}, {"boguslang", "", Integer.valueOf(0)}, {"EN-lATN-us", "en_Latn_US", NOERROR}, {"und-variant-1234", "__VARIANT_1234", NOERROR}, {"und-varzero-var1-vartwo", "__VARZERO", Integer.valueOf(12)}, {"en-u-ca-gregory", "en@calendar=gregorian", NOERROR}, {"en-U-cu-USD", "en@currency=usd", NOERROR}, {"ar-x-1-2-3", "ar@x=1-2-3", NOERROR}, {"fr-u-nu-latn-cu-eur", "fr@currency=eur;numbers=latn", NOERROR}, {"de-k-kext-u-co-phonebk-nu-latn", "de@collation=phonebook;k=kext;numbers=latn", NOERROR}, {"ja-u-cu-jpy-ca-jp", "ja@currency=jpy", Integer.valueOf(15)}, {"en-us-u-tz-usnyc", "en_US@timezone=America/New_York", NOERROR}, {"und-a-abc-def", "@a=abc-def", NOERROR}, {"zh-u-ca-chinese-x-u-ca-chinese", "zh@calendar=chinese;x=u-ca-chinese", NOERROR}, {"fr--FR", "fr", Integer.valueOf(3)}, {"fr-", "fr", Integer.valueOf(3)}, }; for (int i = 0; i < langtag_to_locale.length; i++) { String tag = (String)langtag_to_locale[i][0]; ULocale expected = new ULocale((String)langtag_to_locale[i][1]); ULocale loc = ULocale.forLanguageTag(tag); if (!loc.equals(expected)) { errln("FAIL: forLanguageTag returned locale [" + loc + "] for language tag [" + tag + "] - expected: [" + expected + "]"); } } // Use locale builder to check errors for (int i = 0; i < langtag_to_locale.length; i++) { String tag = (String)langtag_to_locale[i][0]; ULocale expected = new ULocale((String)langtag_to_locale[i][1]); int errorIdx = ((Integer)langtag_to_locale[i][2]).intValue(); try { Builder bld = new Builder(); bld.setLanguageTag(tag); ULocale loc = bld.build(); if (!loc.equals(expected)) { errln("FAIL: forLanguageTag returned locale [" + loc + "] for language tag [" + tag + "] - expected: [" + expected + "]"); } if (errorIdx != NOERROR.intValue()) { errln("FAIL: Builder.setLanguageTag should throw an exception for input tag [" + tag + "]"); } } catch (IllformedLocaleException ifle) { if (ifle.getErrorIndex() != errorIdx) { errln("FAIL: Builder.setLanguageTag returned error index " + ifle.getErrorIndex() + " for input language tag [" + tag + "] expected: " + errorIdx); } } } } /* * Test that if you use any locale without keyword that you will get a NULL * string returned and not throw and exception. */ public void Test4735() { try { new ULocale("und").getDisplayKeywordValue("calendar",ULocale.GERMAN); new ULocale("en").getDisplayKeywordValue("calendar",ULocale.GERMAN); } catch (Exception e) { errln("Unexpected exception: " + e.getMessage()); } } public void TestGetFallback() { // Testing static String getFallback(String) final String[][] TESTIDS = { {"en_US", "en", "", ""}, // ULocale.getFallback("") should return "" {"EN_us_Var", "en_US", "en", ""}, // Case is always normalized {"de_DE@collation=phonebook", "de@collation=phonebook", "@collation=phonebook", "@collation=phonebook"}, // Keyword is preserved {"en__POSIX", "en", ""}, // Trailing empty segment should be truncated {"_US_POSIX", "_US", ""}, // Same as above {"root", ""}, // No canonicalization }; for (String[] chain : TESTIDS) { for (int i = 1; i < chain.length; i++) { String fallback = ULocale.getFallback(chain[i-1]); assertEquals("getFallback(\"" + chain[i-1] + "\")", chain[i], fallback); } } // Testing ULocale getFallback() final ULocale[][] TESTLOCALES = { {new ULocale("en_US"), new ULocale("en"), ULocale.ROOT, null}, {new ULocale("en__POSIX"), new ULocale("en"), ULocale.ROOT, null}, {new ULocale("de_DE@collation=phonebook"), new ULocale("de@collation=phonebook"), new ULocale("@collation=phonebook"), null}, {new ULocale("_US_POSIX"), new ULocale("_US"), ULocale.ROOT, null}, {new ULocale("root"), ULocale.ROOT, null}, }; for(ULocale[] chain : TESTLOCALES) { for (int i = 1; i < chain.length; i++) { ULocale fallback = chain[i-1].getFallback(); assertEquals("ULocale(" + chain[i-1] + ").getFallback()", chain[i], fallback); } } } }