diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/XLocaleMatcherTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/XLocaleMatcherTest.java index c84d8c0a2d..07c87b9968 100644 --- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/XLocaleMatcherTest.java +++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/XLocaleMatcherTest.java @@ -3,38 +3,38 @@ package com.ibm.icu.dev.test.util; -import java.io.IOException; +import java.io.BufferedReader; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Random; import java.util.Set; import java.util.TreeSet; -import java.util.regex.Pattern; import org.junit.Test; import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; import com.ibm.icu.dev.test.TestFmwk; -import com.ibm.icu.impl.locale.XCldrStub.Joiner; -import com.ibm.icu.impl.locale.XCldrStub.Splitter; +import com.ibm.icu.impl.locale.XCldrStub.FileUtilities; import com.ibm.icu.impl.locale.XLocaleDistance; import com.ibm.icu.impl.locale.XLocaleDistance.DistanceOption; import com.ibm.icu.impl.locale.XLocaleMatcher; -import com.ibm.icu.text.UnicodeSet; import com.ibm.icu.util.LocaleMatcher; import com.ibm.icu.util.LocalePriorityList; import com.ibm.icu.util.Output; import com.ibm.icu.util.ULocale; +import junitparams.JUnitParamsRunner; +import junitparams.Parameters; + /** * Test the XLocaleMatcher. * * @author markdavis */ -@RunWith(JUnit4.class) +@RunWith(JUnitParamsRunner.class) public class XLocaleMatcherTest extends TestFmwk { - private static final boolean REFORMAT = false; // set to true to get a reformatted data file listed - private static final int REGION_DISTANCE = 4; private static final XLocaleDistance LANGUAGE_MATCHER_DATA = XLocaleDistance.getDefault(); @@ -56,15 +56,6 @@ public class XLocaleMatcherTest extends TestFmwk { return XLocaleMatcher.builder().setSupportedLocales(string).setThresholdDistance(d).build(); } - private XLocaleMatcher newXLocaleMatcher(LocalePriorityList string, int d, DistanceOption distanceOption) { - return XLocaleMatcher - .builder() - .setSupportedLocales(string) - .setThresholdDistance(d) - .setDistanceOption(distanceOption) - .build(); - } - // public void testParentLocales() { // // find all the regions that have a closer relation because of an explicit parent // Set explicitParents = new HashSet<>(INFO.getExplicitParents()); @@ -125,7 +116,7 @@ public class XLocaleMatcherTest extends TestFmwk { @Test public void testExactMatches() { String lastBase = ""; - TreeSet sorted = new TreeSet(); + TreeSet sorted = new TreeSet<>(); for (ULocale loc : ULocale.getAvailableLocales()) { String language = loc.getLanguage(); if (!lastBase.equals(language)) { @@ -264,75 +255,214 @@ public class XLocaleMatcherTest extends TestFmwk { return (delta / iterations); } - @Test - public void testDataDriven() throws IOException { - DataDrivenTestHelper tfh = new MyTestFileHandler() - .setFramework(this) - .run(XLocaleMatcherTest.class, "data/localeMatcherTest.txt"); - if (REFORMAT) { - System.out.println(tfh.appendLines(new StringBuilder())); + private static final class TestCase implements Cloneable { + private static final String ENDL = System.getProperties().getProperty("line.separator"); + + int lineNr = 0; + + String nameLine = ""; + String supportedLine = ""; + String defaultLine = ""; + String distanceLine = ""; + String thresholdLine = ""; + String matchLine = ""; + + String supported = ""; + String def = ""; + String distance = ""; + String threshold = ""; + String desired = ""; + String expMatch = ""; + String expDesired = ""; + String expCombined = ""; + + @Override + public TestCase clone() throws CloneNotSupportedException { + return (TestCase) super.clone(); + } + + void reset(String newNameLine) { + nameLine = newNameLine; + supportedLine = ""; + defaultLine = ""; + distanceLine = ""; + thresholdLine = ""; + + supported = ""; + def = ""; + distance = ""; + threshold = ""; + } + + String toInputsKey() { + return supported + '+' + def + '+' + distance + '+' + threshold + '+' + desired; + } + + private static void appendLine(StringBuilder sb, String line) { + if (!line.isEmpty()) { + sb.append(ENDL).append(line); + } + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(nameLine); + appendLine(sb, supportedLine); + appendLine(sb, defaultLine); + appendLine(sb, distanceLine); + appendLine(sb, thresholdLine); + sb.append(ENDL).append("line ").append(lineNr).append(':'); + appendLine(sb, matchLine); + return sb.toString(); } } - private static final Splitter COMMA_SPACE = Splitter.on(Pattern.compile(",\\s*|\\s+")).trimResults(); - private static final Joiner JOIN_COMMA_SPACE = Joiner.on(", "); - @SuppressWarnings("unused") - private static final UnicodeSet DIGITS = new UnicodeSet("[0-9]").freeze(); + private static String getSuffixAfterPrefix(String s, int limit, String prefix) { + if (prefix.length() <= limit && s.startsWith(prefix)) { + return s.substring(prefix.length(), limit); + } else { + return null; + } + } - class MyTestFileHandler extends DataDrivenTestHelper { - - Output bestDesired = new Output(); - DistanceOption distanceOption = DistanceOption.REGION_FIRST; - int threshold = -1; - - @Override - public void handle(int lineNumber, boolean breakpoint, String commentBase, List arguments) { - List supported = COMMA_SPACE.splitToList(arguments.get(0)); - final String supportedReformatted = JOIN_COMMA_SPACE.join(supported); - LocalePriorityList supportedList = LocalePriorityList.add(supportedReformatted).build(); - - Iterable desired = COMMA_SPACE.split(arguments.get(1)); - final String desiredReformatted = JOIN_COMMA_SPACE.join(desired); - LocalePriorityList desiredList = LocalePriorityList.add(desiredReformatted).build(); - - String expected = arguments.get(2); - String expectedLanguageTag = expected.equals("null") ? null : new ULocale(expected).toLanguageTag(); - - String expectedUi = arguments.size() < 4 ? null : arguments.get(3); - String expectedUiLanguageTag = expectedUi == null || expectedUi.equals("null") ? null - : new ULocale(expectedUi).toLanguageTag(); - - if (breakpoint) { - breakpoint = false; // put debugger breakpoint here to break at @debug in test file + // UsedReflectively, not private to avoid unused-warning + static List readTestCases() throws Exception { + List tests = new ArrayList<>(); + Map uniqueTests = new HashMap<>(); + TestCase test = new TestCase(); + String filename = "data/localeMatcherTest.txt"; + try (BufferedReader in = FileUtilities.openFile(XLocaleMatcherTest.class, filename)) { + String line; + while ((line = in.readLine()) != null) { + ++test.lineNr; + // Start of comment, or end of line, minus trailing spaces. + int limit = line.indexOf('#'); + if (limit < 0) { + limit = line.length(); + } + char c; + while (limit > 0 && ((c = line.charAt(limit - 1)) == ' ' || c == '\t')) { + --limit; + } + if (limit == 0) { // empty line + continue; + } + String suffix; + if (line.startsWith("** test: ")) { + test.reset(line); + } else if ((suffix = getSuffixAfterPrefix(line, limit, "@supported=")) != null) { + test.supportedLine = line; + test.supported = suffix; + } else if ((suffix = getSuffixAfterPrefix(line, limit, "@default=")) != null) { + test.defaultLine = line; + test.def = suffix; + } else if ((suffix = getSuffixAfterPrefix(line, limit, "@distance=")) != null) { + test.distanceLine = line; + test.distance = suffix; + } else if ((suffix = getSuffixAfterPrefix(line, limit, "@threshold=")) != null) { + test.thresholdLine = line; + test.threshold = suffix; + } else { + int matchSep = line.indexOf(">>"); + // >> before an inline comment, and followed by more than white space. + if (0 <= matchSep && (matchSep + 2) < limit) { + test.matchLine = line; + test.desired = line.substring(0, matchSep).trim(); + test.expDesired = test.expCombined = ""; + int start = matchSep + 2; + int expLimit = line.indexOf('|', start); + if (expLimit < 0) { + test.expMatch = line.substring(start, limit).trim(); + } else { + test.expMatch = line.substring(start, expLimit).trim(); + start = expLimit + 1; + expLimit = line.indexOf('|', start); + if (expLimit < 0) { + test.expDesired = line.substring(start, limit).trim(); + } else { + test.expDesired = line.substring(start, expLimit).trim(); + test.expCombined = line.substring(expLimit + 1, limit).trim(); + } + } + String inputs = test.toInputsKey(); + Integer prevIndex = uniqueTests.get(inputs); + if (prevIndex == null) { + uniqueTests.put(inputs, tests.size()); + } else { + System.out.println("Locale matcher test case on line " + test.lineNr + + " is a duplicate of line " + tests.get(prevIndex).lineNr); + } + tests.add(test.clone()); + } else { + throw new IllegalArgumentException("test data syntax error on line " + + test.lineNr + "\n" + line); + } + } } - XLocaleMatcher matcher = threshold < 0 && distanceOption == DistanceOption.REGION_FIRST - ? newXLocaleMatcher(supportedList) - : newXLocaleMatcher(supportedList, threshold, distanceOption); - commentBase = "(" + lineNumber + ") " + commentBase; + } + System.out.println("Number of duplicate locale matcher test cases: " + (tests.size() - uniqueTests.size())); + return tests; + } - ULocale bestSupported; - if (expectedUi != null) { - bestSupported = matcher.getBestMatch(desiredList, bestDesired); - ULocale bestUI = XLocaleMatcher.combine(bestSupported, bestDesired.value); - assertEquals(commentBase + " (UI)", expectedUiLanguageTag, bestUI == null ? null : bestUI.toLanguageTag()); - } else { - bestSupported = matcher.getBestMatch(desiredList); + private static ULocale getULocaleOrNull(String s) { + if (s.equals("null")) { + return null; + } else { + return new ULocale(s); + } + } + + @Test + @Parameters(method = "readTestCases") + public void dataDriven(TestCase test) { + XLocaleMatcher matcher; + if (test.def.isEmpty() && test.distance.isEmpty() && test.threshold.isEmpty()) { + matcher = new XLocaleMatcher(test.supported); + } else { + XLocaleMatcher.Builder builder = XLocaleMatcher.builder(); + builder.setSupportedLocales(test.supported); + if (!test.def.isEmpty()) { + builder.setDefaultLanguage(new ULocale(test.def)); } - String bestMatchLanguageTag = bestSupported == null ? null : bestSupported.toLanguageTag(); - assertEquals(commentBase, expectedLanguageTag, bestMatchLanguageTag); + if (!test.distance.isEmpty()) { + DistanceOption distance; + switch (test.distance) { + case "normal": + distance = DistanceOption.REGION_FIRST; + break; + case "script": + distance = DistanceOption.SCRIPT_FIRST; + break; + default: + throw new IllegalArgumentException("unsupported distance value " + test.distance); + } + builder.setDistanceOption(distance); + } + if (!test.threshold.isEmpty()) { + int threshold = Integer.valueOf(test.threshold); + builder.setThresholdDistance(threshold); + } + matcher = builder.build(); } - @Override - public void handleParams(String comment, List arguments) { - String switchItem = arguments.get(0); - if (switchItem.equals("@DistanceOption")) { - distanceOption = DistanceOption.valueOf(arguments.get(1)); - } else if (switchItem.equals("@Threshold")) { - threshold = Integer.valueOf(arguments.get(1)); - } else { - super.handleParams(comment, arguments); + ULocale expMatch = getULocaleOrNull(test.expMatch); + if (test.expDesired.isEmpty() && test.expCombined.isEmpty()) { + ULocale bestSupported = matcher.getBestMatch(test.desired); + assertEquals("bestSupported", expMatch, bestSupported); + } else { + LocalePriorityList desired = LocalePriorityList.add(test.desired).build(); + Output bestDesired = new Output<>(); + ULocale bestSupported = matcher.getBestMatch(desired, bestDesired); + assertEquals("bestSupported", expMatch, bestSupported); + if (!test.expDesired.isEmpty()) { + ULocale expDesired = getULocaleOrNull(test.expDesired); + assertEquals("bestDesired", expDesired, bestDesired.value); + } + if (!test.expCombined.isEmpty()) { + ULocale expCombined = getULocaleOrNull(test.expCombined); + ULocale combined = XLocaleMatcher.combine(bestSupported, bestDesired.value); + assertEquals("combined", expCombined, combined); } - return; } } } diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/data/localeMatcherTest.txt b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/data/localeMatcherTest.txt index 55c0f3f5a9..3a149dd7c4 100644 --- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/data/localeMatcherTest.txt +++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/data/localeMatcherTest.txt @@ -1,194 +1,340 @@ # © 2017 and later: Unicode, Inc. and others. # License & terms of use: http://www.unicode.org/copyright.html#License # -# Data-driven test for the XLocaleMatcher. -# Format -# • Everything after "#" is a comment -# • Arguments are separated by ";". They are: +# Data-driven test for the language/locale matcher. +# Format: +# +# Everything after "#" is a comment. +# ** test: This line starts a group of test cases. +# +# Lines starting with an '@' sign provide matcher parameters. +# @supported= +# @default= # no value = no explicit default +# @distance=[normal|script] # no value = no explicit setting +# @threshold= # no value = no explicit setting +# +# A line with ">>" is a getBestMatch() test case: +# >> match | desired | combined +# - match is the expected best supported language +# - desired is the expected best desired language +# - combined is the expected result of combine(match, desired) +# An expected language can be "null" to check for the matcher returning null. +# An empty or omitted value is not tested. (Omitted = not even the '|' separator.) +# +# ** test: A new test group resets all matcher parameters. -# supported ; desired ; expected +## X -# • The supported may have the threshold distance reset as a first item, eg 50, en, fr -# A line starting with @debug will reach a statement in the test code where you can put a breakpoint for debugging -# The test code also supports reformatting this file, by setting the REFORMAT flag. - -################################################## -# testParentLocales +** test: testParentLocales # es-419, es-AR, and es-MX are in a cluster; es is in a different one -@debug -es-419, es-ES ; es-AR ; es-419 -es-ES, es-419 ; es-AR ; es-419 +@supported=es-419, es-ES +es-AR >> es-419 +@supported=es-ES, es-419 +es-AR >> es-419 -es-419, es ; es-AR ; es-419 -es, es-419 ; es-AR ; es-419 +@supported=es-419, es +es-AR >> es-419 +@supported=es, es-419 +es-AR >> es-419 -es-MX, es ; es-AR ; es-MX -es, es-MX ; es-AR ; es-MX +@supported=es-MX, es +es-AR >> es-MX +@supported=es, es-MX +es-AR >> es-MX # en-GB, en-AU, and en-NZ are in a cluster; en in a different one -en-GB, en-US ; en-AU ; en-GB -en-US, en-GB ; en-AU ; en-GB +@supported=en-GB, en-US +en-AU >> en-GB +@supported=en-US, en-GB +en-AU >> en-GB -en-GB, en ; en-AU ; en-GB -en, en-GB ; en-AU ; en-GB +@supported=en-GB, en +en-AU >> en-GB +@supported=en, en-GB +en-AU >> en-GB -en-NZ, en-US ; en-AU ; en-NZ -en-US, en-NZ ; en-AU ; en-NZ +@supported=en-NZ, en-US +en-AU >> en-NZ +@supported=en-US, en-NZ +en-AU >> en-NZ -en-NZ, en ; en-AU ; en-NZ -en, en-NZ ; en-AU ; en-NZ +@supported=en-NZ, en +en-AU >> en-NZ +@supported=en, en-NZ +en-AU >> en-NZ # pt-AU and pt-PT in one cluster; pt-BR in another -pt-PT, pt-BR ; pt-AO ; pt-PT -pt-BR, pt-PT ; pt-AO ; pt-PT +@supported=pt-PT, pt-BR +pt-AO >> pt-PT +@supported=pt-BR, pt-PT +pt-AO >> pt-PT -pt-PT, pt ; pt-AO ; pt-PT -pt, pt-PT ; pt-AO ; pt-PT +@supported=pt-PT, pt +pt-AO >> pt-PT +@supported=pt, pt-PT +pt-AO >> pt-PT -zh-MO, zh-TW ; zh-HK ; zh-MO -zh-TW, zh-MO ; zh-HK ; zh-MO +@supported=zh-MO, zh-TW +zh-HK >> zh-MO +@supported=zh-TW, zh-MO +zh-HK >> zh-MO -zh-MO, zh-TW ; zh-HK ; zh-MO -zh-TW, zh-MO ; zh-HK ; zh-MO +@supported=zh-MO, zh-CN +zh-HK >> zh-MO +@supported=zh-CN, zh-MO +zh-HK >> zh-MO -zh-MO, zh-CN ; zh-HK ; zh-MO -zh-CN, zh-MO ; zh-HK ; zh-MO +@supported=zh-MO, zh +zh-HK >> zh-MO +@supported=zh, zh-MO +zh-HK >> zh-MO -zh-MO, zh ; zh-HK ; zh-MO -zh, zh-MO ; zh-HK ; zh-MO +@distance=script +@supported=es-419, es-ES +es-AR >> es-419 +@supported=es-ES, es-419 +es-AR >> es-419 +@supported=es-419, es +es-AR >> es-419 +@supported=es, es-419 +es-AR >> es-419 +@supported=es-MX, es +es-AR >> es-MX +@supported=es, es-MX +es-AR >> es-MX +@supported=en-GB, en-US +en-AU >> en-GB +@supported=en-US, en-GB +en-AU >> en-GB +@supported=en-GB, en +en-AU >> en-GB +@supported=en, en-GB +en-AU >> en-GB +@supported=en-NZ, en-US +en-AU >> en-NZ +@supported=en-US, en-NZ +en-AU >> en-NZ +@supported=en-NZ, en +en-AU >> en-NZ +@supported=en, en-NZ +en-AU >> en-NZ +@supported=pt-PT, pt-BR +pt-AO >> pt-PT +@supported=pt-BR, pt-PT +pt-AO >> pt-PT +@supported=pt-PT, pt +pt-AO >> pt-PT +@supported=pt, pt-PT +pt-AO >> pt-PT +@supported=zh-MO, zh-TW +zh-HK >> zh-MO +@supported=zh-TW, zh-MO +zh-HK >> zh-MO +@supported=zh-MO, zh-CN +zh-HK >> zh-MO +@supported=zh-CN, zh-MO +zh-HK >> zh-MO +@supported=zh-MO, zh +zh-HK >> zh-MO +@supported=zh, zh-MO +zh-HK >> zh-MO -################################################## -# testChinese +** test: testChinese -zh-CN, zh-TW, iw ; zh-Hant-TW ; zh-TW -zh-CN, zh-TW, iw ; zh-Hant ; zh-TW -zh-CN, zh-TW, iw ; zh-TW ; zh-TW -zh-CN, zh-TW, iw ; zh-Hans-CN ; zh-CN -zh-CN, zh-TW, iw ; zh-CN ; zh-CN -zh-CN, zh-TW, iw ; zh ; zh-CN +@supported=zh-CN, zh-TW, iw +zh-Hant-TW >> zh-TW +zh-Hant >> zh-TW +zh-TW >> zh-TW +zh-Hans-CN >> zh-CN +zh-CN >> zh-CN +zh >> zh-CN -################################################## -# testenGB +@distance=script +zh-Hant-TW >> zh-TW +zh-Hant >> zh-TW +zh-TW >> zh-TW +zh-Hans-CN >> zh-CN +zh-CN >> zh-CN +zh >> zh-CN -fr, en, en-GB, es-419, es-MX, es ; en-NZ ; en-GB -fr, en, en-GB, es-419, es-MX, es ; es-ES ; es -fr, en, en-GB, es-419, es-MX, es ; es-AR ; es-419 -fr, en, en-GB, es-419, es-MX, es ; es-MX ; es-MX +** test: testenGB -################################################## -# testFallbacks +@supported=fr, en, en-GB, es-419, es-MX, es +en-NZ >> en-GB +es-ES >> es +es-AR >> es-419 +es-MX >> es-MX -91, en, hi ; sa ; hi +@distance=script +en-NZ >> en-GB +es-ES >> es +es-AR >> es-419 +es-MX >> es-MX -################################################## -# testBasics +** test: testFallbacks -fr, en-GB, en ; en-GB ; en-GB -fr, en-GB, en ; en ; en -fr, en-GB, en ; fr ; fr -fr, en-GB, en ; ja ; fr # return first if no match +@supported=91, en, hi +sa >> hi -################################################## -# testFallback +@distance=script +sa >> hi + +** test: testBasics + +@supported=fr, en-GB, en +en-GB >> en-GB +en >> en +fr >> fr +ja >> fr # return first if no match + +@distance=script +en-GB >> en-GB +en >> en +fr >> fr +ja >> fr + +** test: testFallback # check that script fallbacks are handled right -zh-CN, zh-TW, iw ; zh-Hant ; zh-TW -zh-CN, zh-TW, iw ; zh ; zh-CN -zh-CN, zh-TW, iw ; zh-Hans-CN ; zh-CN -zh-CN, zh-TW, iw ; zh-Hant-HK ; zh-TW -zh-CN, zh-TW, iw ; he-IT ; iw +@supported=zh-CN, zh-TW, iw +zh-Hant >> zh-TW +zh >> zh-CN +zh-Hans-CN >> zh-CN +zh-Hant-HK >> zh-TW +he-IT >> iw -################################################## -# testSpecials +@distance=script +zh-Hant >> zh-TW +zh >> zh-CN +zh-Hans-CN >> zh-CN +zh-Hant-HK >> zh-TW +he-IT >> iw + +** test: testSpecials # check that nearby languages are handled -en, fil, ro, nn ; tl ; fil -en, fil, ro, nn ; mo ; ro -en, fil, ro, nn ; nb ; nn +@supported=en, fil, ro, nn +tl >> fil +mo >> ro +nb >> nn # make sure default works -en, fil, ro, nn ; ja ; en +ja >> en -################################################## -# testRegionalSpecials +@distance=script +tl >> fil +mo >> ro +nb >> nn +ja >> en + +** test: testRegionalSpecials # verify that en-AU is closer to en-GB than to en (which is en-US) -en, en-GB, es, es-419 ; es-MX ; es-419 -en, en-GB, es, es-419 ; en-AU ; en-GB -en, en-GB, es, es-419 ; es-ES ; es +@supported=en, en-GB, es, es-419 +es-MX >> es-419 +en-AU >> en-GB +es-ES >> es -################################################## -# testHK +@distance=script +es-MX >> es-419 +en-AU >> en-GB +es-ES >> es + +** test: testHK # HK and MO are closer to each other for Hant than to TW -zh, zh-TW, zh-MO ; zh-HK ; zh-MO -zh, zh-TW, zh-HK ; zh-MO ; zh-HK +@supported=zh, zh-TW, zh-MO +zh-HK >> zh-MO +@supported=zh, zh-TW, zh-HK +zh-MO >> zh-HK -################################################## -# testMatch-exact +@distance=script +@supported=zh, zh-TW, zh-MO +zh-HK >> zh-MO +@supported=zh, zh-TW, zh-HK +zh-MO >> zh-HK -# see localeDistance.txt +** test: testMatch-matchOnMazimized -################################################## -# testMatch-none +@supported=zh, zh-Hant +und-TW >> zh-Hant # und-TW should be closer to zh-Hant than to zh -# see localeDistance.txt +@supported=en-Hant-TW, und-TW +zh-Hant >> und-TW # zh-Hant should be closer to und-TW than to en-Hant-TW +zh >> und-TW # zh should be closer to und-TW than to en-Hant-TW -################################################## -# testMatch-matchOnMazimized +@distance=script +@supported=zh, zh-Hant +und-TW >> zh-Hant +@supported=en-Hant-TW, und-TW +zh-Hant >> und-TW +zh >> und-TW -zh, zh-Hant ; und-TW ; zh-Hant # und-TW should be closer to zh-Hant than to zh -en-Hant-TW, und-TW ; zh-Hant ; und-TW # zh-Hant should be closer to und-TW than to en-Hant-TW -en-Hant-TW, und-TW ; zh ; und-TW # zh should be closer to und-TW than to en-Hant-TW +** test: testMatchGrandfatheredCode -################################################## -# testMatchGrandfatheredCode +@supported=fr, i-klingon, en-Latn-US +en-GB-oed >> en-Latn-US -fr, i-klingon, en-Latn-US ; en-GB-oed ; en-Latn-US +@distance=script +en-GB-oed >> en-Latn-US -################################################## -# testGetBestMatchForList-exactMatch -fr, en-GB, ja, es-ES, es-MX ; ja, de ; ja +** test: testGetBestMatchForList-exactMatch +@supported=fr, en-GB, ja, es-ES, es-MX +ja, de >> ja -################################################## -# testGetBestMatchForList-simpleVariantMatch -fr, en-GB, ja, es-ES, es-MX ; de, en-US ; en-GB # Intentionally avoiding a perfect-match or two candidates for variant matches. +@distance=script +ja, de >> ja + +** test: testGetBestMatchForList-simpleVariantMatch +@supported=fr, en-GB, ja, es-ES, es-MX +de, en-US >> en-GB # Intentionally avoiding a perfect-match or two candidates for variant matches. # Fallback. -fr, en-GB, ja, es-ES, es-MX ; de, zh ; fr +de, zh >> fr -################################################## -# testGetBestMatchForList-matchOnMaximized +@distance=script +de, en-US >> en-GB +de, zh >> fr + +** test: testGetBestMatchForList-matchOnMaximized # Check that if the preference is maximized already, it works as well. -en, ja ; ja-Jpan-JP, en-AU ; ja # Match for ja-Jpan-JP (maximized already) +@supported=en, ja +ja-Jpan-JP, en-AU >> ja # Match for ja-Jpan-JP (maximized already) # ja-JP matches ja on likely subtags, and it's listed first, thus it wins over the second preference en-GB. -en, ja ; ja-JP, en-US ; ja # Match for ja-Jpan-JP (maximized already) +ja-JP, en-US >> ja # Match for ja-Jpan-JP (maximized already) # Check that if the preference is maximized already, it works as well. -en, ja ; ja-Jpan-JP, en-US ; ja # Match for ja-Jpan-JP (maximized already) +ja-Jpan-JP, en-US >> ja # Match for ja-Jpan-JP (maximized already) -################################################## -# testGetBestMatchForList-noMatchOnMaximized +@distance=script +ja-Jpan-JP, en-AU >> ja +ja-JP, en-US >> ja +ja-Jpan-JP, en-US >> ja + +** test: testGetBestMatchForList-noMatchOnMaximized # Regression test for http://b/5714572 . # de maximizes to de-DE. Pick the exact match for the secondary language instead. -en, de, fr, ja ; de-CH, fr ; de +@supported=en, de, fr, ja +de-CH, fr >> de -################################################## -# testBestMatchForTraditionalChinese +@distance=script +de-CH, fr >> de + +** test: testBestMatchForTraditionalChinese # Scenario: An application that only supports Simplified Chinese (and some other languages), # but does not support Traditional Chinese. zh-Hans-CN could be replaced with zh-CN, zh, or @@ -197,28 +343,37 @@ en, de, fr, ja ; de-CH, fr ; de # The script distance (simplified vs. traditional Han) is considered small enough # to be an acceptable match. The regional difference is considered almost insignificant. -fr, zh-Hans-CN, en-US ; zh-TW ; zh-Hans-CN -fr, zh-Hans-CN, en-US ; zh-Hant ; zh-Hans-CN +@supported=fr, zh-Hans-CN, en-US +zh-TW >> zh-Hans-CN +zh-Hant >> zh-Hans-CN -# For geo-political reasons, you might want to avoid a zh-Hant -> zh-Hans match. +# For geopolitical reasons, you might want to avoid a zh-Hant -> zh-Hans match. # In this case, if zh-TW, zh-HK or a tag starting with zh-Hant is requested, you can # change your call to getBestMatch to include a 2nd language preference. # "en" is a better match since its distance to "en-US" is closer than the distance # from "zh-TW" to "zh-CN" (script distance). -fr, zh-Hans-CN, en-US ; zh-TW, en ; en-US -fr, zh-Hans-CN, en-US ; zh-Hant-CN, en, en ; en-US -fr, zh-Hans-CN, en-US ; zh-Hans, en ; zh-Hans-CN +zh-TW, en >> en-US +zh-Hant-CN, en >> en-US +zh-Hans, en >> zh-Hans-CN -################################################## -# testUndefined +@distance=script +zh-TW >> zh-Hans-CN +zh-Hant >> zh-Hans-CN +zh-TW, en >> en-US +zh-Hant-CN, en >> en-US +zh-Hans, en >> zh-Hans-CN + +** test: testUndefined # When the undefined language doesn't match anything in the list, # getBestMatch returns the default, as usual. -it, fr ; und ; it +@supported=it, fr +und >> it # When it *does* occur in the list, bestMatch returns it, as expected. -it, und ; und ; und +@supported=it, und +und >> und # The unusual part: max("und") = "en-Latn-US", and since matching is based on maximized # tags, the undefined language would normally match English. But that would produce the @@ -229,159 +384,1570 @@ it, und ; und ; und # so that max("und")="und". That produces the following, more desirable # results: -it, en ; und ; it -it, und ; en ; it +@supported=it, en +und >> it +@supported=it, und +en >> it -################################################## -# testGetBestMatch-regionDistance +@distance=script +@supported=it, fr +und >> it +@supported=it, und +und >> und +@supported=it, en +und >> it +@supported=it, und +en >> it -es-AR, es ; es-MX ; es-AR -fr, en, en-GB ; en-CA ; en-GB -de-AT, de-DE, de-CH ; de ; de-DE +** test: testGetBestMatch-regionDistance -################################################## -# testAsymmetry +@supported=es-AR, es +es-MX >> es-AR +@supported=fr, en, en-GB +en-CA >> en-GB +@supported=de-AT, de-DE, de-CH +de >> de-DE -mul, nl ; af ; nl # af => nl -mul, af ; nl ; mul # but nl !=> af +@distance=script +@supported=es-AR, es +es-MX >> es-AR +@supported=fr, en, en-GB +en-CA >> en-GB +@supported=de-AT, de-DE, de-CH +de >> de-DE -################################################## -# testGetBestMatchForList-matchOnMaximized2 +** test: testAsymmetry + +@supported=mul, nl +af >> nl # af => nl +@supported=mul, af +nl >> mul # but nl !=> af + +@distance=script +@supported=mul, nl +af >> nl +@supported=mul, af +nl >> mul + +** test: testGetBestMatchForList-matchOnMaximized2 # ja-JP matches ja on likely subtags, and it's listed first, thus it wins over the second preference en-GB. -fr, en-GB, ja, es-ES, es-MX ; ja-JP, en-GB ; ja # Match for ja-JP, with likely region subtag +@supported=fr, en-GB, ja, es-ES, es-MX +ja-JP, en-GB >> ja # Match for ja-JP, with likely region subtag # Check that if the preference is maximized already, it works as well. -fr, en-GB, ja, es-ES, es-MX ; ja-Jpan-JP, en-GB ; ja # Match for ja-Jpan-JP (maximized already) +ja-Jpan-JP, en-GB >> ja # Match for ja-Jpan-JP (maximized already) -################################################## -# testGetBestMatchForList-closeEnoughMatchOnMaximized +@distance=script +ja-JP, en-GB >> ja +ja-Jpan-JP, en-GB >> ja -en-GB, en, de, fr, ja ; de-CH, fr ; de -en-GB, en, de, fr, ja ; en-US, ar, nl, de, ja ; en +** test: testGetBestMatchForList-closeEnoughMatchOnMaximized -################################################## -# testGetBestMatchForPortuguese +@supported=en-GB, en, de, fr, ja +de-CH, fr >> de +en-US, ar, nl, de, ja >> en + +@distance=script +de-CH, fr >> de +en-US, ar, nl, de, ja >> en + +** test: testGetBestMatchForPortuguese # pt might be supported and not pt-PT -# European user who prefers Spanish over Brazillian Portuguese as a fallback. +# European user who prefers Spanish over Brazilian Portuguese as a fallback. -pt-PT, pt-BR, es, es-419 ; pt-PT, es, pt ; pt-PT -pt-PT, pt, es, es-419 ; pt-PT, es, pt ; pt-PT # pt implicit +@supported=pt-PT, pt-BR, es, es-419 +pt-PT, es, pt >> pt-PT +@supported=pt-PT, pt, es, es-419 +pt-PT, es, pt >> pt-PT # pt implicit -# Brazillian user who prefers South American Spanish over European Portuguese as a fallback. +# Brazilian user who prefers South American Spanish over European Portuguese as a fallback. # The asymmetry between this case and above is because it's "pt-PT" that's missing between the # matchers as "pt-BR" is a much more common language. -pt-PT, pt-BR, es, es-419 ; pt, es-419, pt-PT ; pt-BR -pt-PT, pt-BR, es, es-419 ; pt-PT, es, pt ; pt-PT -pt-PT, pt, es, es-419 ; pt-PT, es, pt ; pt-PT -pt-PT, pt, es, es-419 ; pt, es-419, pt-PT ; pt +@supported=pt-PT, pt-BR, es, es-419 +pt, es-419, pt-PT >> pt-BR +pt-PT, es, pt >> pt-PT +@supported=pt-PT, pt, es, es-419 +pt-PT, es, pt >> pt-PT +pt, es-419, pt-PT >> pt -pt-BR, es, es-419 ; pt, es-419, pt-PT ; pt-BR +@supported=pt-BR, es, es-419 +pt, es-419, pt-PT >> pt-BR # Code that adds the user's country can get "pt-US" for a user's language. # That should fall back to "pt-BR". -pt-PT, pt-BR, es, es-419 ; pt-US, pt-PT ; pt-BR -pt-PT, pt, es, es-419 ; pt-US, pt-PT, pt ; pt # pt-BR implicit +@supported=pt-PT, pt-BR, es, es-419 +pt-US, pt-PT >> pt-BR +@supported=pt-PT, pt, es, es-419 +pt-US, pt-PT, pt >> pt # pt-BR implicit -################################################## -# testVariantWithScriptMatch 1 and 2 +@distance=script +@supported=pt-PT, pt-BR, es, es-419 +pt-PT, es, pt >> pt-PT +@supported=pt-PT, pt, es, es-419 +pt-PT, es, pt >> pt-PT -fr, en, sv ; en-GB ; en -fr, en, sv ; en-GB ; en -en, sv ; en-GB, sv ; en +@supported=pt-PT, pt-BR, es, es-419 +pt, es-419, pt-PT >> pt-BR +pt-PT, es, pt >> pt-PT +@supported=pt-PT, pt, es, es-419 +pt-PT, es, pt >> pt-PT +pt, es-419, pt-PT >> pt -################################################## -# testLongLists +@supported=pt-BR, es, es-419 +pt, es-419, pt-PT >> pt-BR -en, sv ; sv ; sv -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 ; sv ; sv -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 ; sv ; sv +@supported=pt-PT, pt-BR, es, es-419 +pt-US, pt-PT >> pt-BR +@supported=pt-PT, pt, es, es-419 +pt-US, pt-PT, pt >> pt -################################################## -# test8288 +** test: testVariantWithScriptMatch 1 and 2 -it, en ; und ; it -it, en ; und, en ; en +@supported=fr, en, sv +en-GB >> en +@supported=en, sv +en-GB, sv >> en + +@distance=script +@supported=fr, en, sv +en-GB >> en +@supported=en, sv +en-GB, sv >> en + +** test: testLongLists + +@supported=en, sv +sv >> sv + +@supported=af, am, ar, az, be, bg, bn, bs, ca, cs, 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 +sv >> sv + +@supported=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 +sv >> sv + +@distance=script +@supported=en, sv +sv >> sv + +@supported=af, am, ar, az, be, bg, bn, bs, ca, cs, 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 +sv >> sv + +@supported=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 +sv >> sv + +** test: test8288 + +@supported=it, en +und >> it +und, en >> en # examples from # http://unicode.org/repos/cldr/tags/latest/common/bcp47/ # http://unicode.org/repos/cldr/tags/latest/common/validity/variant.xml -################################################## -# testUnHack +@distance=script +und >> it +und, en >> en -en-NZ, en-IT ; en-US ; en-NZ +** test: testUnHack -################################################## -# testEmptySupported => null - ; en ; null +@supported=en-NZ, en-IT +en-US >> en-NZ + +@distance=script +en-US >> en-NZ + +** test: testEmptySupported => null +en >> null -################################################## # testVariantsAndExtensions -################################################## -# tests the .combine() method -und, fr ; fr-BE-fonipa ; fr ; fr-BE-fonipa -und, fr-CA ; fr-BE-fonipa ; fr-CA ; fr-BE-fonipa -und, fr-fonupa ; fr-BE-fonipa ; fr-fonupa ; fr-BE-fonipa -und, no ; nn-BE-fonipa ; no ; no-BE-fonipa -und, en-GB-u-sd-gbsct ; en-fonipa-u-nu-Arab-ca-buddhist-t-m0-iso-i0-pinyin ; en-GB-u-sd-gbsct ; en-GB-fonipa-u-nu-Arab-ca-buddhist-t-m0-iso-i0-pinyin +** test: tests the .combine() method -en-PSCRACK, de-PSCRACK, fr-PSCRACK, pt-PT-PSCRACK ; fr-PSCRACK ; fr-PSCRACK -en-PSCRACK, de-PSCRACK, fr-PSCRACK, pt-PT-PSCRACK ; fr ; en-PSCRACK # was: fr-PSCRACK -en-PSCRACK, de-PSCRACK, fr-PSCRACK, pt-PT-PSCRACK ; de-CH ; en-PSCRACK # was: de-PSCRACK +@supported=und, fr +fr-BE-fonipa >> fr | | fr-BE-fonipa +@supported=und, fr-CA +fr-BE-fonipa >> fr-CA | | fr-BE-fonipa +@supported=und, fr-fonupa +fr-BE-fonipa >> fr-fonupa | | fr-BE-fonipa +@supported=und, no +nn-BE-fonipa >> no | | no-BE-fonipa +@supported=und, en-GB-u-sd-gbsct +en-fonipa-u-nu-Arab-ca-buddhist-t-m0-iso-i0-pinyin >> en-GB-u-sd-gbsct | | en-GB-fonipa-u-nu-Arab-ca-buddhist-t-m0-iso-i0-pinyin -################################################## -# testClusters +@supported=en-PSCRACK, de-PSCRACK, fr-PSCRACK, pt-PT-PSCRACK +fr-PSCRACK >> fr-PSCRACK +fr >> en-PSCRACK +de-CH >> en-PSCRACK + +@distance=script +@supported=und, fr +fr-BE-fonipa >> fr +@supported=und, fr-CA +fr-BE-fonipa >> fr-CA +@supported=und, fr-fonupa +fr-BE-fonipa >> fr-fonupa +@supported=und, no +nn-BE-fonipa >> no | | no-BE-fonipa +@supported=und, en-GB-u-sd-gbsct +en-fonipa-u-nu-Arab-ca-buddhist-t-m0-iso-i0-pinyin >> en-GB-u-sd-gbsct | | en-GB-fonipa-u-nu-Arab-ca-buddhist-t-m0-iso-i0-pinyin + +@supported=en-PSCRACK, de-PSCRACK, fr-PSCRACK, pt-PT-PSCRACK +fr-PSCRACK >> fr-PSCRACK +fr >> en-PSCRACK +de-CH >> en-PSCRACK + +** test: testClusters # we favor es-419 over others in cluster. Clusters: es- {ES, MA, EA} {419, AR, MX} -und, es, es-MA, es-MX, es-419 ; es-AR ; es-419 -und, es-MA, es, es-419, es-MX ; es-AR ; es-419 -und, es, es-MA, es-MX, es-419 ; es-EA ; es -und, es-MA, es, es-419, es-MX ; es-EA ; es +@supported=und, es, es-MA, es-MX, es-419 +es-AR >> es-419 +@supported=und, es-MA, es, es-419, es-MX +es-AR >> es-419 +@supported=und, es, es-MA, es-MX, es-419 +es-EA >> es +@supported=und, es-MA, es, es-419, es-MX +es-EA >> es # of course, fall back to within cluster -und, es, es-MA, es-MX ; es-AR ; es-MX -und, es-MA, es, es-MX ; es-AR ; es-MX -und, es-MA, es-MX, es-419 ; es-EA ; es-MA -und, es-MA, es-419, es-MX ; es-EA ; es-MA +@supported=und, es, es-MA, es-MX +es-AR >> es-MX +@supported=und, es-MA, es, es-MX +es-AR >> es-MX +@supported=und, es-MA, es-MX, es-419 +es-EA >> es-MA +@supported=und, es-MA, es-419, es-MX +es-EA >> es-MA # we favor es-GB over others in cluster. Clusters: en- {US, GU, VI} {GB, IN, ZA} -und, en, en-GU, en-IN, en-GB ; en-ZA ; en-GB -und, en-GU, en, en-GB, en-IN ; en-ZA ; en-GB -und, en, en-GU, en-IN, en-GB ; en-VI ; en -und, en-GU, en, en-GB, en-IN ; en-VI ; en +@supported=und, en, en-GU, en-IN, en-GB +en-ZA >> en-GB +@supported=und, en-GU, en, en-GB, en-IN +en-ZA >> en-GB +@supported=und, en, en-GU, en-IN, en-GB +en-VI >> en +@supported=und, en-GU, en, en-GB, en-IN +en-VI >> en # of course, fall back to within cluster -und, en, en-GU, en-IN ; en-ZA ; en-IN -und, en-GU, en, en-IN ; en-ZA ; en-IN -und, en-GU, en-IN, en-GB ; en-VI ; en-GU -und, en-GU, en-GB, en-IN ; en-VI ; en-GU +@supported=und, en, en-GU, en-IN +en-ZA >> en-IN +@supported=und, en-GU, en, en-IN +en-ZA >> en-IN +@supported=und, en-GU, en-IN, en-GB +en-VI >> en-GU +@supported=und, en-GU, en-GB, en-IN +en-VI >> en-GU -################################################## -# testThreshold -@Threshold=60 +@distance=script +@supported=und, es, es-MA, es-MX, es-419 +es-AR >> es-419 +@supported=und, es-MA, es, es-419, es-MX +es-AR >> es-419 +@supported=und, es, es-MA, es-MX, es-419 +es-EA >> es +@supported=und, es-MA, es, es-419, es-MX +es-EA >> es -50, und, fr-CA-fonupa ; fr-BE-fonipa ; fr-CA-fonupa ; fr-BE-fonipa -50, und, fr-Cyrl-CA-fonupa ; fr-BE-fonipa ; fr-Cyrl-CA-fonupa ; fr-Cyrl-BE-fonipa +@supported=und, es, es-MA, es-MX +es-AR >> es-MX +@supported=und, es-MA, es, es-MX +es-AR >> es-MX +@supported=und, es-MA, es-MX, es-419 +es-EA >> es-MA +@supported=und, es-MA, es-419, es-MX +es-EA >> es-MA -@Threshold=-1 # restore +@supported=und, en, en-GU, en-IN, en-GB +en-ZA >> en-GB +@supported=und, en-GU, en, en-GB, en-IN +en-ZA >> en-GB +@supported=und, en, en-GU, en-IN, en-GB +en-VI >> en +@supported=und, en-GU, en, en-GB, en-IN +en-VI >> en -################################################## -# testScriptFirst -@DistanceOption=SCRIPT_FIRST -@debug +@supported=und, en, en-GU, en-IN +en-ZA >> en-IN +@supported=und, en-GU, en, en-IN +en-ZA >> en-IN +@supported=und, en-GU, en-IN, en-GB +en-VI >> en-GU +@supported=und, en-GU, en-GB, en-IN +en-VI >> en-GU -ru, fr ; zh, pl ; fr -ru, fr ; zh-Cyrl, pl ; ru -#hr, en-Cyrl; sr ; en-Cyrl -da, ru, hr; sr ; ru +** test: testThreshold +@supported=50, und, fr-CA-fonupa +@threshold=60 +fr-BE-fonipa >> fr-CA-fonupa | | fr-BE-fonipa +@supported=und, fr-Cyrl-CA-fonupa +fr-BE-fonipa >> fr-Cyrl-CA-fonupa | | fr-Cyrl-BE-fonipa +@threshold=50 +fr-BE-fonipa >> und + +@distance=script +@supported=50, und, fr-CA-fonupa +@threshold= +fr-BE-fonipa >> fr-CA-fonupa | | fr-BE-fonipa +@supported=und, fr-Cyrl-CA-fonupa +fr-BE-fonipa >> fr-Cyrl-CA-fonupa | fr-BE-fonipa + +** test: testScriptFirst +@supported=ru, fr +zh, pl >> ru +zh-Cyrl, pl >> ru +@supported=hr, en-Cyrl +sr >> hr +@supported=da, ru, hr +sr >> da + +@distance=script +@supported=ru, fr +zh, pl >> fr +zh-Cyrl, pl >> ru +@supported=hr, en-Cyrl +sr >> en-Cyrl +@supported=da, ru, hr +sr >> ru + +## III + +** test: testBasicsWithDefault +@supported=en-GB, en +@default=fr +en-GB >> en-GB +en-US >> en +fr >> fr +ja >> fr + +@distance=script +en-GB >> en-GB +en-US >> en +fr >> en-GB +ja >> en-GB + +** test: testEmptyWithDefault +@default=en +fr >> en + +** test: testGetBestMatchForList_exactMatch +@supported=fr, en-GB, ja, es-ES, es-MX +ja, de >> ja + +** test: testGetBestMatchForList_simpleVariantMatch +# Intentionally avoiding a perfect-match or two candidates for variant matches. +@supported=fr, en-GB, ja, es-ES, es-MX +de, en-US >> en-GB +# Fall back. +de, zh >> fr + +** test: TestEuHack +@supported=en-NZ, en-IT +en-US >> en-NZ + +** test: TestBasics +@supported=fr, en-GB, en +en-GB >> en-GB +en-US >> en +fr-FR >> fr +ja-JP >> fr +# For a language that doesn't match anything, return the default. +zu >> en-GB +root >> fr + +@distance=script +en-GB >> en-GB +en-US >> en +fr-FR >> fr +ja-JP >> fr +zu >> en-GB +root >> en + +** test: TestExactMatch +@supported=fr, en-GB, ja, es-ES, es-MX +ja, de >> ja + +** test: TestSimpleVariantMatch +@supported=fr, en-GB, ja, es-ES, es-MX +de, en-US >> en-GB +de, zh >> fr + +** test: TestMatchOnMaximized +# ja-JP matches ja on likely subtags, and it's listed first, thus it wins +# over the secondary preference en-GB. +@supported=fr, en-GB, ja, es-ES, es-MX +ja-JP, en-GB >> ja +# Check that if the preference is maximized already, it works as well. +ja-Jpan-JP, en-GB >> ja +@supported=fr, zh-Hant, en +zh, en >> en + +@distance=script +zh, en >> en + +** test: TestCloseEnoughMatchOnMaximized +@supported=en-GB, en, de, fr, ja +de-CH, fr >> de +en-US, ar, nl, de, ja >> en + +** test: TestGetBestMatchForPortuguese +# 1. a supported set containing an explicit pt: {pt-PT, pt-BR, es, es-419} +# 2. a supported set containing an implicit pt: {pt-PT, pt, es, es-419} +# 3. a supported set containing no pt: {pt-BR, es, es-419} +# European user who prefers Spanish over Brazilian Portuguese as a fallback. +@supported=pt-PT, pt-BR, es, es-419 +pt-PT, es, pt >> pt-PT +@supported=pt-PT, pt, es, es-419 +pt-PT, es, pt >> pt-PT +@supported=pt-BR, es, es-419 +pt-PT, es, pt >> pt-BR + +# Brazilian user who prefers South American Spanish over European Portuguese +# as a fallback. The asymmetry between this case and above is because it's +# "pt-PT" that's missing between the matchers. +@supported=pt-PT, pt-BR, es, es-419 +pt, es-419, pt-PT >> pt-BR +@supported=pt-PT, pt, es, es-419 +pt, es-419, pt-PT >> pt +@supported=pt-BR, es, es-419 +pt, es-419, pt-PT >> pt-BR + +# Sometimes we get "pt-US" for a user's language (which CLDR doesn't +# recognize) but we deal with that as a synonym for "pt-BR". +@supported=pt-PT, pt-BR, es, es-419 +pt-US, pt-PT >> pt-BR +@supported=pt-PT, pt, es, es-419 +pt-US, pt-PT >> pt + +@distance=script +@supported=pt-BR, es, es-419 +pt-PT, es, pt >> pt-BR +@supported=pt-PT, pt, es, es-419 +pt-US, pt-PT >> pt + +** test: TestScriptAndRegion +@supported=en-GB, en +en-CA >> en-GB +# fr-CA is a "close enough" match to "fr" to be returned in favor of "en-GB" +@supported=fr, en-GB, en +fr-CA, en-CA >> fr +@supported=zh-Hant, zh-TW +zh-HK >> zh-Hant + +@distance=script +@supported=en-GB, en +en-CA >> en-GB +@supported=fr, en-GB, en +fr-CA, en-CA >> fr +@supported=zh-Hant, zh-TW +zh-HK >> zh-Hant + +** test: TestFallback +@supported=zh-CN, zh-TW, iw +zh-Hant >> zh-TW +zh >> zh-CN +zh-Hans-CN >> zh-CN +zh-Hant-HK >> zh-TW +he-IT >> iw + +** test: TestFallbackWithDefault +# Check that script fallbacks are handled right and that we don't have to +# fall back to the default. +@supported=zh-CN, zh-TW, iw +@default=fr +zh-Hant >> zh-TW +zh >> zh-CN +zh-Hans-CN >> zh-CN +zh-Hant-HK >> zh-TW +he-IT >> iw + +@distance=script +zh-Hant >> zh-TW +zh >> zh-CN +zh-Hans-CN >> zh-CN +zh-Hant-HK >> zh-TW +he-IT >> iw + +** test: TestSpecials +# Check that nearby languages are handled. +@supported=en, fil, ro, nn +tl >> fil +mo >> ro +nb >> nn +ja >> en # Make sure default works. + +** test: TestRegionalSpecials +# Verify that en-AU is closer to en-GB than to en (which is en-US). +@supported=en, en-GB, es-ES, es-419 +en-AU >> en-GB +# Following 2 cases test closer/smaller region difference. +es-MX >> es-419 +es-PT >> es-ES + +@distance=script +en-AU >> en-GB +es-MX >> es-419 +es-PT >> es-ES + +** test: TestEmpty +fr >> null + +** test: TestUndefined +# When the undefined language doesn't match anything in the list, +# return the default. +@supported=it, fr +und >> it +# When it *does* occur in the list, return it. +@supported=it, und +und >> und +# The unusual part: +# max("und") = "en-Latn-US", and since matching is based on +# maximized tags, the undefined language would normally match +# English. But that would produce the counterintuitive results +# that BestMatchFor("und", LanguageMatcher("it,en")) would be "en", +# and BestMatchFor("en", LanguageMatcher("it,und")) would be "und". + +# To avoid that, we change the matcher's definitions of max +# (AddLikelySubtagsWithDefaults) so that max("und")="und". That +# produces the following, more desirable results: +@supported=it, en +und >> it +@supported=it, und +en >> it + +** test: TestVariantWithScriptMatch +@supported=fr, en, sv +en-GB >> en +en-GB, sv >> en + +@distance=script +en-GB, sv >> en + +** test: Serbian +@supported=und, sr +sr-ME >> sr +@supported=und, sr-ME +sr >> sr-ME +@supported=und, sr-Latn +bs >> und +@supported=und, bs +sr-Latn >> und +@supported=und, sr +bs >> und +@supported=und, bs +sr >> und +@supported=und, sr-Latn +sr >> sr-Latn +@supported=und, sr +sr-Latn >> sr + +@distance=script +sr-ME >> sr +@supported=und, sr-ME +sr >> sr-ME +@supported=und, sr-Latn +bs >> sr-Latn +@supported=und, bs +sr-Latn >> bs +@supported=und, sr +bs >> und +@supported=und, bs +sr >> und +@supported=und, sr-Latn +sr >> sr-Latn +@supported=und, sr +sr-Latn >> sr + +** test: MatchGooglePrivateUseSubtag +@supported=fr, x-bork, en-Latn-US +x-piglatin >> fr +x-bork >> x-bork +@supported=fr, en-GB, x-bork, es-ES, es-419 +x-piglatin >> fr +x-bork >> x-bork + +@distance=script +@supported=fr, x-bork, en-Latn-US +x-piglatin >> x-bork +x-bork >> x-bork +@supported=fr, en-GB, x-bork, es-ES, es-419 +x-piglatin >> x-bork +x-bork >> x-bork + +** test: MatchGrandfatheredCode +@supported=fr, i-klingon, en-Latn-US +en-GB-oed >> en-Latn-US +i-klingon >> tlh + +@distance=script +en-GB-oed >> en-Latn-US +i-klingon >> tlh + +** test: MatchGooglePseudoLocale +# Google pseudo locales using variant subtags. +# (See below for the region code based pseudo locales.) +@supported=fr, en-PSACCENT, ar-PSBIDI, en-PSCRACK, zh-Hans-PSCRACK, pt-PT-PSCRACK, pt +de >> fr +en-US >> fr +en >> fr +ar-PSBIDI >> ar-PSBIDI +en-PSACCENT >> en-PSACCENT +en-PSCRACK >> en-PSCRACK +pt-BR >> pt +pt-PT-PSCRACK >> pt-PT-PSCRACK +zh-Hans-PSCRACK >> zh-Hans-PSCRACK + +@distance=script +de >> fr +en-US >> fr +en >> fr +ar-PSBIDI >> ar-PSBIDI +en-PSACCENT >> en-PSACCENT +en-PSCRACK >> en-PSCRACK +pt-BR >> pt +pt-PT-PSCRACK >> pt-PT-PSCRACK +zh-Hans-PSCRACK >> zh-Hans-PSCRACK + +** test: MatchGooglePseudoLocaleWithFallbacks +# Pseudo locales based on the fall back option (XA..XC region codes). +@supported=fr, en-XA, ar-XB, en-XC, zh-Hans-XC, pt +de >> fr +en-US >> fr +en >> fr +ar-XB >> ar-XB +en-XA >> en-XA +en-XC >> en-XC +pt-BR >> pt +zh-Hans-XC >> zh-Hans-XC + +@distance=script +de >> fr +en-US >> fr +en >> fr +ar-XB >> ar-XB +en-XA >> en-XA +en-XC >> en-XC +pt-BR >> pt +zh-Hans-XC >> zh-Hans-XC + +** test: DoNotMatchGooglePseudoLocale +@supported=fr, en-XA, ar-XB, en-PSACCENT, ar-PSBIDI, en-DE, pt, ar-SY, ar-PSCRACK +de >> fr +# We wouldn't want to return pseudo locales when there's a good match for an +# ordinary locale. +# Note: If LanguageMatcher was not aware of PSACCENT, it would consider the +# distance from "en" to "en-PSACCENT" smaller than to "en-DE" (the standard +# variant distance is smaller than a region distance). +en >> en-DE +ar-EG >> ar-SY +pt-BR >> pt +ar-XB >> ar-XB +ar-PSBIDI >> ar-PSBIDI +en-XA >> en-XA +en-PSACCENT >> en-PSACCENT +ar-PSCRACK >> ar-PSCRACK + +@distance=script +de >> en-DE +en >> en-DE +ar-EG >> ar-SY +pt-BR >> pt +ar-XB >> ar-XB +ar-PSBIDI >> ar-PSBIDI +en-XA >> en-XA +en-PSACCENT >> en-PSACCENT +ar-PSCRACK >> ar-PSCRACK + +** test: BestMatchForTraditionalChinese +# Scenario: An application that only supports Simplified Chinese (and some +# other languages), but does not support Traditional Chinese. zh-Hans-CN +# could be replaced with zh-CN, zh, or zh-Hans, it wouldn't make much of a +# difference. +# The script distance (simplified vs. traditional Han) is considered small +# enough to be an acceptable match. The regional difference is considered +# almost insignificant. +@supported=fr, zh-Hans-CN, en-US +zh-TW >> zh-Hans-CN +zh-Hant >> zh-Hans-CN + +# For geopolitical reasons, you might want to avoid a zh-Hant -> zh-Hans +# match. In this case, if zh-TW, zh-HK or a tag starting with zh-Hant is +# requested, you can change your call to getBestMatch to include a 2nd +# language preference. "en" is a better match since its distance to "en-US" +# is closer than the distance from "zh-TW" to "zh-CN" (script distance). +zh-TW, en >> en-US +zh-Hant-CN, en >> en-US +zh-Hans, en >> zh-Hans-CN + +** test: MaxBeforeEquals +# Compare maximized forms of earlier items before testing equality +# of later items. +@supported=en, fr-CA +en-US, fr-CA >> en + +@distance=script +en-US, fr-CA >> en + +** test: SiblingDefaultRegion +@supported=de-AT, de-DE, de-CH +de >> de-DE + +** test: ReturnDefaultInsteadOfNullForEmptyPriorityList +@default=und +de >> und + +** test: ReturnSpecifiedDefaultForNoMatch +@supported=de, en, fr +@default=und +hi >> und + +@distance=script +hi >> de + +** test: MatchedLanguageIgnoresDefault +@supported=de, en, fr +@default=und +fr >> fr + +@distance=script +fr >> fr + +## GenX + +** test: TwoSpanishes +@supported=es, es-MX +@default=und +es-001 >> es +und >> und +ca >> und +gl-ES >> es +es >> es +es-MX >> es-MX +es-002 >> es +es-003 >> es-MX +es-005 >> es-MX +es-019 >> es-MX +es-029 >> es-MX +es-419 >> es-MX +es-142 >> es +es-150 >> es +es-AD >> es +es-AR >> es-MX +es-BO >> es-MX +es-BZ >> es-MX +es-CA >> es-MX +es-CL >> es-MX +es-CO >> es-MX +es-CR >> es-MX +es-CU >> es-MX +es-DO >> es-MX +es-EC >> es-MX +es-ES >> es +es-GI >> es +es-GQ >> es +es-GT >> es-MX +es-HN >> es-MX +es-NI >> es-MX +es-PA >> es-MX +es-PE >> es-MX +es-PH >> es +es-PR >> es-MX +es-PY >> es-MX +es-SV >> es-MX +es-US >> es-MX +es-UY >> es-MX +es-VE >> es-MX + +@distance=script +es-001 >> es +und >> es +ca >> es +gl-ES >> es +es >> es +es-MX >> es-MX +es-002 >> es +es-003 >> es-MX +es-005 >> es-MX +es-019 >> es-MX +es-029 >> es-MX +es-419 >> es-MX +es-142 >> es +es-150 >> es +es-AD >> es +es-AR >> es-MX +es-BO >> es-MX +es-BZ >> es-MX +es-CA >> es-MX +es-CL >> es-MX +es-CO >> es-MX +es-CR >> es-MX +es-CU >> es-MX +es-DO >> es-MX +es-EC >> es-MX +es-ES >> es +es-GI >> es +es-GQ >> es +es-GT >> es-MX +es-HN >> es-MX +es-NI >> es-MX +es-PA >> es-MX +es-PE >> es-MX +es-PH >> es +es-PR >> es-MX +es-PY >> es-MX +es-SV >> es-MX +es-US >> es-MX +es-UY >> es-MX +es-VE >> es-MX + +** test: Three Spanishes +@supported=es, es-419, es-MX +@default=und +es-001 >> es +und >> und +ca >> und +gl-ES >> es +es >> es +es-419 >> es-419 +es-002 >> es +es-003 >> es-419 +es-005 >> es-419 +es-019 >> es-419 +es-029 >> es-419 +es-142 >> es +es-150 >> es +es-AD >> es +es-AR >> es-419 +es-BO >> es-419 +es-BZ >> es-419 +es-CA >> es-419 +es-CL >> es-419 +es-CO >> es-419 +es-CR >> es-419 +es-CU >> es-419 +es-DO >> es-419 +es-EC >> es-419 +es-ES >> es +es-GI >> es +es-GQ >> es +es-GT >> es-419 +es-HN >> es-419 +es-MX >> es-MX +es-NI >> es-419 +es-PA >> es-419 +es-PE >> es-419 +es-PH >> es +es-PR >> es-419 +es-PY >> es-419 +es-SV >> es-419 +es-US >> es-419 +es-UY >> es-419 +es-VE >> es-419 + +@distance=script +es-001 >> es +und >> es +ca >> es +gl-ES >> es +es >> es +es-419 >> es-419 +es-002 >> es +es-003 >> es-419 +es-005 >> es-419 +es-019 >> es-419 +es-029 >> es-419 +es-142 >> es +es-150 >> es +es-AD >> es +es-AR >> es-419 +es-BO >> es-419 +es-BZ >> es-419 +es-CA >> es-419 +es-CL >> es-419 +es-CO >> es-419 +es-CR >> es-419 +es-CU >> es-419 +es-DO >> es-419 +es-EC >> es-419 +es-ES >> es +es-GI >> es +es-GQ >> es +es-GT >> es-419 +es-HN >> es-419 +es-MX >> es-MX +es-NI >> es-419 +es-PA >> es-419 +es-PE >> es-419 +es-PH >> es +es-PR >> es-419 +es-PY >> es-419 +es-SV >> es-419 +es-US >> es-419 +es-UY >> es-419 +es-VE >> es-419 + +** test: Englishes +@supported=en-GB, en-US +@default=und +und >> und +ja >> und +fr-CA >> und + +# Great Britain fallback +en-AU >> en-GB +en-BZ >> en-GB +en-CA >> en-GB +en-IN >> en-GB +en-IE >> en-GB +en-JM >> en-GB +en-NZ >> en-GB +en-PK >> en-GB +en-TT >> en-GB +en-ZA >> en-GB + +# United States fallback +en-US >> en-US +en >> en-US + +@distance=script +und >> en-GB +ja >> en-GB +fr-CA >> en-GB +en-AU >> en-GB +en-BZ >> en-GB +en-CA >> en-GB +en-IN >> en-GB +en-IE >> en-GB +en-JM >> en-GB +en-NZ >> en-GB +en-PK >> en-GB +en-TT >> en-GB +en-ZA >> en-GB +en-US >> en-US +en >> en-US + +** test: TestFallback +# manyEnMatcher +@supported=en-GB, en-US, en, en-AU +@default=und +und >> und +ja >> und +fr-CA >> und + +# nonUsMatcher +fr >> und + +# onlyAuMatcher +@supported=en-AU, ja, ca +fr >> und + +# noEnMatcher +@supported=pl, ja, ca +fr >> und + +@distance=script +@supported=en-GB, en-US, en, en-AU +und >> en-GB +ja >> en-GB +fr-CA >> en-GB +fr >> en-GB +@supported=en-AU, ja, ca +fr >> en-AU +@supported=pl, ja, ca +fr >> pl + +## Go + +** test: basics +@supported=fr, en-GB, en +en-GB >> en-GB +en-US >> en +fr-FR >> fr +ja-JP >> fr + +** test: script fallbacks +@supported=zh-CN, zh-TW, iw +zh-Hant >> zh-TW +zh >> zh-CN +zh-Hans-CN >> zh-CN +zh-Hant-HK >> zh-TW +@default=iw +he-IT >> iw + +@distance=script +he-IT >> iw + +** test: language-specific script fallbacks 1 +@supported=en, sr, nl +sr-Latn >> sr +sh >> en +hr >> en +bs >> en +nl-Cyrl >> en # Mark: Expected value should be en not sr. Script difference exceeds threshold, so can't be nl + +@distance=script +sr-Latn >> sr +hr >> en +bs >> en +nl-Cyrl >> sr + +** test: language-specific script fallbacks 2 +@supported=en, sr-Latn +sr >> sr-Latn +sr-Cyrl >> sr-Latn +@default=und +hr >> und + +@distance=script +@default= +sr >> sr-Latn +sr-Cyrl >> sr-Latn +@default=und +hr >> en + +** test: don't match hr to sr-Latn +@supported=en, sr-Latn +hr >> en + +@distance=script +hr >> en + +** test: both deprecated and not +@supported=fil, tl, iw, he +he-IT >> iw +he >> he +iw >> iw +fil-IT >> fil +fil >> fil +tl >> tl + +@distance=script +he-IT >> iw +he >> he +iw >> iw +fil-IT >> fil +fil >> fil +tl >> tl + +** test: nearby languages: Nynorsk to Bokmål +@supported=en, nb +nn >> nb + +@distance=script +nn >> nb + +** test: nearby languages: Danish does not match nn +@supported=en, nn +da >> en + +@distance=script +da >> en + +** test: nearby languages: Danish matches no +@supported=en, no +da >> no + +@distance=script +da >> no + +** test: nearby languages: Danish matches nb +@supported=en, nb +da >> nb + +** test: prefer matching languages over language variants. +@supported=nn, en-GB +no, en-US >> nn +nb, en-US >> nn + +@distance=script +no, en-US >> nn +nb, en-US >> nn + +** test: deprecated version is closer than same language with other differences +@supported=nl, he, en-GB +iw, en-US >> he + +@distance=script +iw, en-US >> he + +** test: macro equivalent is closer than same language with other differences +@supported=nl, zh, en-GB, no +cmn, en-US >> zh +nb, en-US >> no + +@distance=script +cmn, en-US >> zh +nb, en-US >> no + +** test: legacy equivalent is closer than same language with other differences +@supported=nl, fil, en-GB +tl, en-US >> fil + +@distance=script +tl, en-US >> fil + +** test: distinguish near equivalents +@supported=en, ro, mo, ro-MD +ro >> ro +mo >> mo +ro-MD >> ro-MD + +@distance=script +ro >> ro +mo >> mo +ro-MD >> ro-MD + +** test: maximization of legacy +@supported=sr-Cyrl, sr-Latn, ro, ro-MD +sh >> sr-Latn +mo >> ro + +@distance=script +sh >> sr-Latn +mo >> ro + +** test: empty +fr >> null +en >> null + +** test: private use subtags +@supported=fr, en-GB, x-bork, es-ES, es-419 +x-piglatin >> fr +x-bork >> x-bork + +** test: grandfathered codes +@supported=fr, i-klingon, en-Latn-US +en-GB-oed >> en-Latn-US +i-klingon >> tlh + + +** test: simple variant match +@supported=fr, en-GB, ja, es-ES, es-MX +de, en-US >> en-GB +de, zh >> fr + +** test: best match for traditional Chinese +@supported=fr, zh-Hans-CN, en-US +zh-TW >> zh-Hans-CN +zh-Hant >> zh-Hans-CN +zh-TW, en >> en-US +zh-Hant-CN, en >> en-US +zh-Hans, en >> zh-Hans-CN + +** test: more specific script should win in case regions are identical +@supported=af, af-Latn, af-Arab +af >> af +af-ZA >> af +af-Latn-ZA >> af +af-Latn >> af-Latn + +@distance=script +af >> af +af-ZA >> af +af-Latn-ZA >> af +af-Latn >> af-Latn + +** test: more specific region should win +@supported=nl, nl-NL, nl-BE +nl >> nl +nl-Latn >> nl +nl-Latn-NL >> nl +nl-NL >> nl-NL + +@distance=script +nl >> nl +nl-Latn >> nl +nl-Latn-NL >> nl +nl-NL >> nl-NL + +** test: region may replace matched if matched is enclosing +@supported=es-419, es +@default=es-MX +es-MX >> es-419 +@default= +es-SG >> es + +@distance=script +@default=es-MX +es-MX >> es-419 +@default= +es-SG >> es + +** test: more specific region wins over more specific script +@supported=nl, nl-Latn, nl-NL, nl-BE +nl >> nl +nl-Latn >> nl-Latn +nl-NL >> nl-NL +nl-Latn-NL >> nl + +@distance=script +nl >> nl +nl-Latn >> nl-Latn +nl-NL >> nl-NL +nl-Latn-NL >> nl + +** test: region distance Portuguese +@supported=pt, pt-PT +pt-ES >> pt-PT + +@distance=script +pt-ES >> pt-PT + +** test: if no preferred locale specified, pick top language, not regional +@supported=en, fr, fr-CA, fr-CH +fr-US >> fr + +@distance=script +fr-US >> fr + +** test: region distance German +@supported=de-AT, de-DE, de-CH +de >> de-DE + +** test: en-AU is closer to en-GB than to en (which is en-US) +@supported=en, en-GB, es-ES, es-419 +en-AU >> en-GB +@default=es-MX +es-MX >> es-419 +@default= +es-PT >> es-ES + +@distance=script +en-AU >> en-GB +es-MX >> es-419 +@default= +es-PT >> es-ES + +** test: undefined +@supported=it, fr +und >> it + +** test: und does not match en +@supported=it, en +und >> it + +** test: undefined in priority list +@supported=it, und +und >> und +en >> it + +** test: undefined +@supported=it, fr, zh +und-FR >> fr +und-CN >> zh +und-Hans >> zh +und-Hant >> zh +und-Latn >> it + +@distance=script +und-FR >> fr +und-CN >> zh +und-Hans >> zh +und-Hant >> zh +und-Latn >> it + +** test: match on maximized tag +@supported=fr, en-GB, ja, es-ES, es-MX +ja-JP, en-GB >> ja +ja-Jpan-JP, en-GB >> ja + +** test: pick best maximized tag +@supported=ja, ja-Jpan-US, ja-JP, en, ru +ja-Jpan, ru >> ja +ja-JP, ru >> ja-JP +ja-US, ru >> ja-Jpan-US + +@distance=script +ja-Jpan, ru >> ja +ja-JP, ru >> ja-JP +ja-US, ru >> ja-Jpan-US + +** test: termination: pick best maximized match +@supported=ja, ja-Jpan, ja-JP, en, ru +ja-Jpan-JP, ru >> ja +ja-Jpan, ru >> ja-Jpan + +@distance=script +ja-Jpan-JP, ru >> ja +ja-Jpan, ru >> ja-Jpan + +** test: same language over exact, but distinguish when user is explicit +@supported=fr, en-GB, ja, es-ES, es-MX +ja, de >> ja +@supported=en, de, fr, ja +de-CH, fr >> de +@supported=en-GB, nl +en, nl >> en-GB +en, nl, en-GB >> en-GB + +@distance=script +@supported=fr, en-GB, ja, es-ES, es-MX +ja, de >> ja +@supported=en, de, fr, ja +de-CH, fr >> de +@supported=en-GB, nl +en, nl >> en-GB +en, nl, en-GB >> en-GB + +** test: parent relation preserved +@supported=en, en-US, en-GB, es, es-419, pt, pt-BR, pt-PT, zh, zh-Hant, zh-Hant-HK +en-150 >> en-GB +en-AU >> en-GB +en-BE >> en-GB +en-GG >> en-GB +en-GI >> en-GB +en-HK >> en-GB +en-IE >> en-GB +en-IM >> en-GB +en-IN >> en-GB +en-JE >> en-GB +en-MT >> en-GB +en-NZ >> en-GB +en-PK >> en-GB +en-SG >> en-GB +en-DE >> en-GB +@default=es-AR +es-AR >> es-419 +@default=es-BO +es-BO >> es-419 +@default=es-CL +es-CL >> es-419 +@default=es-CO +es-CO >> es-419 +@default=es-CR +es-CR >> es-419 +@default=es-CU +es-CU >> es-419 +@default=es-DO +es-DO >> es-419 +@default=es-EC +es-EC >> es-419 +@default=es-GT +es-GT >> es-419 +@default=es-HN +es-HN >> es-419 +@default=es-MX +es-MX >> es-419 +@default=es-NI +es-NI >> es-419 +@default=es-PA +es-PA >> es-419 +@default=es-PE +es-PE >> es-419 +@default=es-PR +es-PR >> es-419 +@default= +es-PT >> es +@default=es-PY +es-PY >> es-419 +@default=es-SV +es-SV >> es-419 +@default= +es-US >> es-419 +@default=es-UY +es-UY >> es-419 +@default=es-VE +es-VE >> es-419 +@default= +pt-AO >> pt-PT +pt-CV >> pt-PT +pt-GW >> pt-PT +pt-MO >> pt-PT +pt-MZ >> pt-PT +pt-ST >> pt-PT +pt-TL >> pt-PT + +@distance=script +en-150 >> en-GB +en-AU >> en-GB +en-BE >> en-GB +en-GG >> en-GB +en-GI >> en-GB +en-HK >> en-GB +en-IE >> en-GB +en-IM >> en-GB +en-IN >> en-GB +en-JE >> en-GB +en-MT >> en-GB +en-NZ >> en-GB +en-PK >> en-GB +en-SG >> en-GB +en-DE >> en-GB +@default=es-AR +es-AR >> es-419 +@default=es-BO +es-BO >> es-419 +@default=es-CL +es-CL >> es-419 +@default=es-CO +es-CO >> es-419 +@default=es-CR +es-CR >> es-419 +@default=es-CU +es-CU >> es-419 +@default=es-DO +es-DO >> es-419 +@default=es-EC +es-EC >> es-419 +@default=es-GT +es-GT >> es-419 +@default=es-HN +es-HN >> es-419 +@default=es-MX +es-MX >> es-419 +@default=es-NI +es-NI >> es-419 +@default=es-PA +es-PA >> es-419 +@default=es-PE +es-PE >> es-419 +@default=es-PR +es-PR >> es-419 +@default= +es-PT >> es +@default=es-PY +es-PY >> es-419 +@default=es-SV +es-SV >> es-419 +@default= +es-US >> es-419 +@default=es-UY +es-UY >> es-419 +@default=es-VE +es-VE >> es-419 +@default= +pt-AO >> pt-PT +pt-CV >> pt-PT +pt-GW >> pt-PT +pt-MO >> pt-PT +pt-MZ >> pt-PT +pt-ST >> pt-PT +pt-TL >> pt-PT + +** test: preserve extensions +@supported=en, de, sl-NEDIS +@default=de-u-co-phonebk +de-FR-u-co-phonebk >> de +@default=sl-NEDIS-u-cu-eur +sl-NEDIS-u-cu-eur >> sl-NEDIS +sl-u-cu-eur >> sl-NEDIS +sl-HR-NEDIS-u-cu-eur >> sl-NEDIS +@default=de-t-m0-iso-i0-pinyin +de-t-m0-iso-i0-pinyin >> de + +@distance=script +@default=de-u-co-phonebk +de-FR-u-co-phonebk >> de +@default=sl-NEDIS-u-cu-eur +sl-NEDIS-u-cu-eur >> sl-NEDIS +sl-u-cu-eur >> sl-NEDIS +sl-HR-NEDIS-u-cu-eur >> sl-NEDIS +@default=de-t-m0-iso-i0-pinyin +de-t-m0-iso-i0-pinyin >> de + +## ULS + +** test: testEmptyUserLanguagesGetsEmpty_getBestMatches +@supported=de + >> de + +** test: testNoStrongMatchGetsEmpty_getBestMatches +@supported=de +fr >> de + +@distance=script +fr >> de + +** test: testLooseMatchForGeneral_getBestMatches +@supported=es-419 +es-MX >> es-419 + +@distance=script +es-MX >> es-419 + +** test: testLooseMatchForEnglish_getBestMatches +@supported=en, en-GB +en-CA >> en-GB + +@distance=script +en-CA >> en-GB + +** test: testLooseMatchForChinese_getBestMatches +@supported=zh +zh-TW >> zh + +@distance=script +zh-TW >> zh + +## Geo + +** test: testGetBestMatchWithMinMatchScore +@supported=fr-FR, fr, fr-CA, en +@default=und +fr >> fr # Exact match is chosen. +@supported=en, fr, fr-CA +fr-FR >> fr # Parent match is chosen. +@supported=en, fr-CA +fr-FR >> fr-CA # Sibling match is chosen. +@supported=fr-CA, fr-FR +fr >> fr-FR # Inferred region match is chosen. +fr-SN >> fr-CA +@supported=en, fr-FR +fr >> fr-FR # Child match is chosen. +@supported=de, en, it +fr >> und +@supported=iw, en +iw-Latn >> und +@supported=iw, no +ru >> und +@supported=iw-Latn, iw-Cyrl, iw +ru >> und +@supported=iw, iw-Latn +ru >> und +en >> und +@supported=en, uk +ru >> und +@supported=zh-TW, en +zh-CN >> zh-TW +@supported=ja +ru >> und + +@distance=script +@supported=fr-FR, fr, fr-CA, en +fr >> fr +@supported=en, fr, fr-CA +fr-FR >> fr +@supported=en, fr-CA +fr-FR >> fr-CA +@supported=fr-CA, fr-FR +fr >> fr-FR +fr-SN >> fr-CA +@supported=en, fr-FR +fr >> fr-FR +@supported=de, en, it +fr >> de +@supported=iw, en +iw-Latn >> en +@supported=iw, no +ru >> iw +@supported=iw-Latn, iw-Cyrl, iw +ru >> iw-Cyrl +@supported=iw, iw-Latn +ru >> iw +en >> iw-Latn +@supported=en, uk +ru >> uk +@supported=zh-TW, en +zh-CN >> zh-TW +@supported=ja +ru >> ja