/* ******************************************************************************* * Copyright (C) 2002-2010, International Business Machines Corporation and * * others. All Rights Reserved. * ******************************************************************************* */ /** * Port From: ICU4C v2.1 : cintltest * Source File: $ICU4CRoot/source/test/cintltest/cmsccoll.c */ package com.ibm.icu.dev.test.collator; import java.util.Arrays; import java.util.Locale; import java.util.Set; import java.util.TreeSet; import com.ibm.icu.dev.test.TestFmwk; import com.ibm.icu.impl.ICUResourceBundle; import com.ibm.icu.impl.ImplicitCEGenerator; import com.ibm.icu.impl.Utility; import com.ibm.icu.text.CollationElementIterator; import com.ibm.icu.text.CollationKey; import com.ibm.icu.text.Collator; import com.ibm.icu.text.Normalizer; import com.ibm.icu.text.RawCollationKey; import com.ibm.icu.text.RuleBasedCollator; import com.ibm.icu.text.UTF16; import com.ibm.icu.text.CollationKey.BoundMode; import com.ibm.icu.util.ULocale; import com.ibm.icu.util.UResourceBundle; public class CollationMiscTest extends TestFmwk { public static void main(String[] args) throws Exception { new CollationMiscTest().run(args); // new CollationMiscTest().TestLocaleRuleBasedCollators(); } //private static final int NORM_BUFFER_TEST_LEN_ = 32; private static final class Tester { int u; String NFC; String NFD; } private static final boolean hasCollationElements(Locale locale) { ICUResourceBundle rb = (ICUResourceBundle)UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_COLLATION_BASE_NAME,locale); if (rb != null) { try { String collkey = rb.getStringWithFallback("collations/default"); ICUResourceBundle elements = rb.getWithFallback("collations/" + collkey); if (elements != null) { return true; } } catch (Exception e) { } } return false; } public void TestComposeDecompose() { Tester t[] = new Tester[0x30000]; t[0] = new Tester(); logln("Testing UCA extensively\n"); RuleBasedCollator coll; try { coll = (RuleBasedCollator)Collator.getInstance(Locale.ENGLISH); } catch (Exception e) { warnln("Error opening collator\n"); return; } int noCases = 0; for (int u = 0; u < 0x30000; u ++) { String comp = UTF16.valueOf(u); int len = comp.length(); t[noCases].NFC = Normalizer.normalize(u, Normalizer.NFC); t[noCases].NFD = Normalizer.normalize(u, Normalizer.NFD); if (t[noCases].NFC.length() != t[noCases].NFD.length() || (t[noCases].NFC.compareTo(t[noCases].NFD) != 0) || (len != t[noCases].NFD.length()) || (comp.compareTo(t[noCases].NFD) != 0)) { t[noCases].u = u; if (len != t[noCases].NFD.length() || (comp.compareTo(t[noCases].NFD) != 0)) { t[noCases].NFC = comp; } noCases ++; t[noCases] = new Tester(); } } for (int u = 0; u < noCases; u ++) { if (!coll.equals(t[u].NFC, t[u].NFD)) { errln("Failure: codePoint \\u" + Integer.toHexString(t[u].u) + " fails TestComposeDecompose in the UCA"); CollationTest.doTest(this, coll, t[u].NFC, t[u].NFD, 0); } } logln("Testing locales, number of cases = " + noCases); Locale loc[] = Collator.getAvailableLocales(); for (int i = 0; i < loc.length; i ++) { if (hasCollationElements(loc[i])) { logln("Testing locale " + loc[i].getDisplayName()); coll = (RuleBasedCollator)Collator.getInstance(loc[i]); coll.setStrength(Collator.IDENTICAL); for (int u = 0; u < noCases; u ++) { if (!coll.equals(t[u].NFC, t[u].NFD)) { errln("Failure: codePoint \\u" + Integer.toHexString(t[u].u) + " fails TestComposeDecompose for locale " + loc[i].getDisplayName()); // this tests for the iterators too CollationTest.doTest(this, coll, t[u].NFC, t[u].NFD, 0); } } } } } public void TestRuleOptions() { // values here are hardcoded and are correct for the current UCA when // the UCA changes, one might be forced to change these values. // (\\u02d0, \\U00010FFFC etc...) String[] rules = { // cannot test this anymore, as [last primary ignorable] doesn't // have a code point associated to it anymore // "&[before 3][last primary ignorable]<< 1) { errln("***** invalid call to reportCResult ****"); return; } boolean ok1 = (compareResult == expectedResult); boolean ok2 = (keyResult == expectedResult); boolean ok3 = (incResult == expectedResult); if (ok1 && ok2 && ok3 /* synwee to undo && !isVerbose()*/) { return; } else { String msg1 = ok1? "Ok: compare(\"" : "FAIL: compare(\""; String msg2 = "\", \""; String msg3 = "\") returned "; String msg4 = "; expected "; String sExpect = new String(""); String sResult = new String(""); sResult = appendCompareResult(compareResult, sResult); sExpect = appendCompareResult(expectedResult, sExpect); if (ok1) { // logln(msg1 + source + msg2 + target + msg3 + sResult); } else { errln(msg1 + source + msg2 + target + msg3 + sResult + msg4 + sExpect); } msg1 = ok2 ? "Ok: key(\"" : "FAIL: key(\""; msg2 = "\").compareTo(key(\""; msg3 = "\")) returned "; sResult = appendCompareResult(keyResult, sResult); if (ok2) { // logln(msg1 + source + msg2 + target + msg3 + sResult); } else { errln(msg1 + source + msg2 + target + msg3 + sResult + msg4 + sExpect); msg1 = " "; msg2 = " vs. "; errln(msg1 + prettify(sourceKey) + msg2 + prettify(targetKey)); } msg1 = ok3 ? "Ok: incCompare(\"" : "FAIL: incCompare(\""; msg2 = "\", \""; msg3 = "\") returned "; sResult = appendCompareResult(incResult, sResult); if (ok3) { // logln(msg1 + source + msg2 + target + msg3 + sResult); } else { errln(msg1 + source + msg2 + target + msg3 + sResult + msg4 + sExpect); } } } String appendCompareResult(int result, String target) { if (result == -1) { //LESS target += "LESS"; } else if (result == 0) { //EQUAL target += "EQUAL"; } else if (result == 1) { //GREATER target += "GREATER"; } else { String huh = "?"; target += huh + result; } return target; } String prettify(CollationKey sourceKey) { int i; byte[] bytes= sourceKey.toByteArray(); String target = "["; for (i = 0; i < bytes.length; i++) { String numStr = Integer.toHexString(bytes[i]); if (numStr.length()>2) { target += numStr.substring(numStr.length()-2); } else { target += numStr; } target += " "; } target += "]"; return target; } public void TestBeforePrefixFailure() { String[] rules = { "&g <<< a&[before 3]\uff41 <<< x", "&\u30A7=\u30A7=\u3047=\uff6a&\u30A8=\u30A8=\u3048=\uff74&[before 3]\u30a7<<<\u30a9", "&[before 3]\u30a7<<<\u30a9&\u30A7=\u30A7=\u3047=\uff6a&\u30A8=\u30A8=\u3048=\uff74", }; String[][] data = { {"x", "\uff41"}, {"\u30a9", "\u30a7"}, {"\u30a9", "\u30a7"}, }; for(int i = 0; i< rules.length; i++) { genericRulesStarter(rules[i], data[i]); } } public void TestContractionClosure() { String[] rules = { "&b=\u00e4\u00e4", "&b=\u00C5", }; String[][] data = { { "b", "\u00e4\u00e4", "a\u0308a\u0308", "\u00e4a\u0308", "a\u0308\u00e4" }, { "b", "\u00C5", "A\u030A", "\u212B" }, }; for(int i = 0; i< rules.length; i++) { genericRulesStarterWithResult(rules[i], data[i], 0); } } public void TestPrefixCompose() { String rule1 = "&\u30a7<<<\u30ab|\u30fc=\u30ac|\u30fc"; String string = rule1; try { RuleBasedCollator coll = new RuleBasedCollator(string); logln("rule:" + coll.getRules()); } catch (Exception e) { warnln("Error open RuleBasedCollator rule = " + string); } } public void TestStrCollIdenticalPrefix() { String rule = "&\ud9b0\udc70=\ud9b0\udc71"; String test[] = { "ab\ud9b0\udc70", "ab\ud9b0\udc71" }; genericRulesStarterWithResult(rule, test, 0); } public void TestPrefix() { String[] rules = { "&z <<< z|a", "&z <<< z| a", "[strength I]&a=\ud900\udc25&z<<<\ud900\udc25|a", }; String[][] data = { {"zz", "za"}, {"zz", "za"}, {"aa", "az", "\ud900\udc25z", "\ud900\udc25a", "zz"}, }; for(int i = 0; iimage)->jamoSpecial = TRUE; // don't try this at home // genericOrderingTest(coll, koreanData); // no such locale in icu4j // logln("Using ko__LOTUS locale\n"); // genericLocaleStarter(new Locale("ko__LOTUS", ""), koreanData); } public void TestIncrementalNormalize() { Collator coll = null; // logln("Test 1 ...."); { /* Test 1. Run very long unnormalized strings, to force overflow of*/ /* most buffers along the way.*/ try { coll = Collator.getInstance(new Locale("en", "US")); } catch (Exception e) { warnln("Cannot get default instance!"); return; } char baseA =0x41; char ccMix[] = {0x316, 0x321, 0x300}; int sLen; int i; StringBuffer strA = new StringBuffer(); StringBuffer strB = new StringBuffer(); coll.setDecomposition(Collator.CANONICAL_DECOMPOSITION); for (sLen = 1000; sLen<1001; sLen++) { strA.delete(0, strA.length()); strA.append(baseA); strB.delete(0, strB.length()); strB.append(baseA); for (i=1; i< sLen; i++) { strA.append(ccMix[i % 3]); strB.insert(1, ccMix[i % 3]); } coll.setStrength(Collator.TERTIARY); // Do test with default strength, which runs CollationTest.doTest(this, (RuleBasedCollator)coll, strA.toString(), strB.toString(), 0); // optimized functions in the impl coll.setStrength(Collator.IDENTICAL); // Do again with the slow, general impl. CollationTest.doTest(this, (RuleBasedCollator)coll, strA.toString(), strB.toString(), 0); } } /* Test 2: Non-normal sequence in a string that extends to the last character*/ /* of the string. Checks a couple of edge cases.*/ // logln("Test 2 ...."); { String strA = "AA\u0300\u0316"; String strB = "A\u00c0\u0316"; coll.setStrength(Collator.TERTIARY); CollationTest.doTest(this, (RuleBasedCollator)coll, strA, strB, 0); } /* Test 3: Non-normal sequence is terminated by a surrogate pair.*/ // logln("Test 3 ...."); { String strA = "AA\u0300\u0316\uD800\uDC01"; String strB = "A\u00c0\u0316\uD800\uDC00"; coll.setStrength(Collator.TERTIARY); CollationTest.doTest(this, (RuleBasedCollator)coll, strA, strB, 1); } /* Test 4: Imbedded nulls do not terminate a string when length is specified.*/ // logln("Test 4 ...."); /* * not a valid test since string are null-terminated in java{ char strA[] = {0x41, 0x00, 0x42}; char strB[] = {0x41, 0x00, 0x00}; int result = coll.compare(new String(strA), new String(strB)); if (result != 1) { errln("ERROR 1 in test 4\n"); } result = coll.compare(new String(strA, 0, 1), new String(strB, 0, 1)); if (result != 0) { errln("ERROR 1 in test 4\n"); } CollationKey sortKeyA = coll.getCollationKey(new String(strA)); CollationKey sortKeyB = coll.getCollationKey(new String(strB)); int r = sortKeyA.compareTo(sortKeyB); if (r <= 0) { errln("Error 4 in test 4\n"); } coll.setStrength(Collator.IDENTICAL); sortKeyA = coll.getCollationKey(new String(strA)); sortKeyB = coll.getCollationKey(new String(strB)); r = sortKeyA.compareTo(sortKeyB); if (r <= 0) { errln("Error 7 in test 4\n"); } coll.setStrength(Collator.TERTIARY); } */ /* Test 5: Null characters in non-normal source strings.*/ // logln("Test 5 ...."); /* * not a valid test since string are null-terminated in java{ { char strA[] = {0x41, 0x41, 0x300, 0x316, 0x00, 0x42,}; char strB[] = {0x41, 0x41, 0x300, 0x316, 0x00, 0x00,}; int result = coll.compare(new String(strA, 0, 6), new String(strB, 0, 6)); if (result < 0) { errln("ERROR 1 in test 5\n"); } result = coll.compare(new String(strA, 0, 4), new String(strB, 0, 4)); if (result != 0) { errln("ERROR 2 in test 5\n"); } CollationKey sortKeyA = coll.getCollationKey(new String(strA)); CollationKey sortKeyB = coll.getCollationKey(new String(strB)); int r = sortKeyA.compareTo(sortKeyB); if (r <= 0) { errln("Error 4 in test 5\n"); } coll.setStrength(Collator.IDENTICAL); sortKeyA = coll.getCollationKey(new String(strA)); sortKeyB = coll.getCollationKey(new String(strB)); r = sortKeyA.compareTo(sortKeyB); if (r <= 0) { errln("Error 7 in test 5\n"); } coll.setStrength(Collator.TERTIARY); } */ /* Test 6: Null character as base of a non-normal combining sequence.*/ // logln("Test 6 ...."); /* * not a valid test since string are null-terminated in java{ { char strA[] = {0x41, 0x0, 0x300, 0x316, 0x41, 0x302,}; char strB[] = {0x41, 0x0, 0x302, 0x316, 0x41, 0x300,}; int result = coll.compare(new String(strA, 0, 5), new String(strB, 0, 5)); if (result != -1) { errln("Error 1 in test 6\n"); } result = coll.compare(new String(strA, 0, 1), new String(strB, 0, 1)); if (result != 0) { errln("Error 2 in test 6\n"); } } */ } public void TestContraction() { String[] testrules = { "&A = AB / B", "&A = A\\u0306/\\u0306", "&c = ch / h", }; String[] testdata = { "AB", "AB", "A\u0306", "ch" }; String[] testdata2 = { "\u0063\u0067", "\u0063\u0068", "\u0063\u006C", }; String[] testrules3 = { "&z < xyz &xyzw << B", "&z < xyz &xyz << B / w", "&z < ch &achm << B", "&z < ch &a << B / chm", "&\ud800\udc00w << B", "&\ud800\udc00 << B / w", "&a\ud800\udc00m << B", "&a << B / \ud800\udc00m", }; RuleBasedCollator coll = null; for (int i = 0; i < testrules.length; i ++) { CollationElementIterator iter1 = null; int j = 0; // logln("Rule " + testrules[i] + " for testing\n"); String rule = testrules[i]; try { coll = new RuleBasedCollator(rule); } catch (Exception e) { warnln("Collator creation failed " + testrules[i]); return; } try { iter1 = coll.getCollationElementIterator(testdata[i]); } catch (Exception e) { errln("Collation iterator creation failed\n"); return; } while (j < 2) { CollationElementIterator iter2; int ce; try { iter2 = coll.getCollationElementIterator(String.valueOf(testdata[i].charAt(j))); }catch (Exception e) { errln("Collation iterator creation failed\n"); return; } ce = iter2.next(); while (ce != CollationElementIterator.NULLORDER) { if (iter1.next() != ce) { errln("Collation elements in contraction split does not match\n"); return; } ce = iter2.next(); } j ++; } if (iter1.next() != CollationElementIterator.NULLORDER) { errln("Collation elements not exhausted\n"); return; } } String rule = "& a < b < c < ch < d & c = ch / h"; try { coll = new RuleBasedCollator(rule); } catch (Exception e) { errln("cannot create rulebased collator"); return; } if (coll.compare(testdata2[0], testdata2[1]) != -1) { errln("Expected " + testdata2[0] + " < " + testdata2[1]); return; } if (coll.compare(testdata2[1], testdata2[2]) != -1) { errln("Expected " + testdata2[1] + " < " + testdata2[2]); return; } for (int i = 0; i < testrules3.length; i += 2) { RuleBasedCollator coll1, coll2; CollationElementIterator iter1, iter2; char ch = 0x0042; int ce; rule = testrules3[i]; try { coll1 = new RuleBasedCollator(rule); } catch (Exception e) { errln("Fail: cannot create rulebased collator, rule:" + rule); return; } rule = testrules3[i + 1]; try { coll2 = new RuleBasedCollator(rule); } catch (Exception e) { errln("Collator creation failed " + testrules[i]); return; } try { iter1 = coll1.getCollationElementIterator(String.valueOf(ch)); iter2 = coll2.getCollationElementIterator(String.valueOf(ch)); } catch (Exception e) { errln("Collation iterator creation failed\n"); return; } ce = iter1.next(); while (ce != CollationElementIterator.NULLORDER) { if (ce != iter2.next()) { errln("CEs does not match\n"); return; } ce = iter1.next(); } if (iter2.next() != CollationElementIterator.NULLORDER) { errln("CEs not exhausted\n"); return; } } } public void TestExpansion() { String[] testrules = { "&J << K / B & K << M", "&J << K / B << M" }; String[] testdata = { "JA", "MA", "KA", "KC", "JC", "MC", }; Collator coll; for (int i = 0; i < testrules.length; i++) { // logln("Rule " + testrules[i] + " for testing\n"); String rule = testrules[i]; try { coll = new RuleBasedCollator(rule); } catch (Exception e) { warnln("Collator creation failed " + testrules[i]); return; } for (int j = 0; j < 5; j ++) { CollationTest.doTest(this, (RuleBasedCollator)coll, testdata[j], testdata[j + 1], -1); } } } public void TestContractionEndCompare() { String rules = "&b=ch"; String src = "bec"; String tgt = "bech"; Collator coll = null; try { coll = new RuleBasedCollator(rules); } catch (Exception e) { warnln("Collator creation failed " + rules); return; } CollationTest.doTest(this, (RuleBasedCollator)coll, src, tgt, 1); } public void TestLocaleRuleBasedCollators() { if (getInclusion() < 5) { // not serious enough to run this return; } Locale locale[] = Collator.getAvailableLocales(); String prevrule = null; for (int i = 0; i < locale.length; i ++) { Locale l = locale[i]; try { ICUResourceBundle rb = (ICUResourceBundle)UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_COLLATION_BASE_NAME,l); String collkey = rb.getStringWithFallback("collations/default"); ICUResourceBundle elements = rb.getWithFallback("collations/" + collkey); if (elements == null) { continue; } String rule = null; /* Object[][] colldata = (Object[][])elements; // %%CollationBin if (colldata[0][1] instanceof byte[]){ rule = (String)colldata[1][1]; } else { rule = (String)colldata[0][1]; } */ rule = elements.getString("Sequence"); RuleBasedCollator col1 = (RuleBasedCollator)Collator.getInstance(l); if (!rule.equals(col1.getRules())) { errln("Rules should be the same in the RuleBasedCollator and Locale"); } if (rule != null && rule.length() > 0 && !rule.equals(prevrule)) { RuleBasedCollator col2 = new RuleBasedCollator(rule); if (!col1.equals(col2)) { errln("Error creating RuleBasedCollator from " + "locale rules for " + l.toString()); } } prevrule = rule; } catch (Exception e) { warnln("Error retrieving resource bundle for testing: " + e.toString()); } } } public void TestOptimize() { /* this is not really a test - just trying out * whether copying of UCA contents will fail * Cannot really test, since the functionality * remains the same. */ String rules[] = { "[optimize [\\uAC00-\\uD7FF]]" }; String data[][] = { { "a", "b"} }; int i = 0; for(i = 0; i 0) { if (mergedPrefixKeys[i-1].compareTo(mergedPrefixKeys[i]) >= 0) { errln("Error while comparing prefixed keys @ strength " + strength); errln(prettify(mergedPrefixKeys[i-1])); errln(prettify(mergedPrefixKeys[i])); } if (mergedSuffixKeys[i-1].compareTo(mergedSuffixKeys[i]) >= 0) { errln("Error while comparing suffixed keys @ strength " + strength); errln(prettify(mergedSuffixKeys[i-1])); errln(prettify(mergedSuffixKeys[i])); } } } if (strength == Collator.QUATERNARY) { strength = Collator.IDENTICAL; } else { strength ++; } } } public void TestVariableTop() { // parseNextToken is not released as public so i create my own rules String rules = "& a < b < c < de < fg & hi = j"; try { RuleBasedCollator coll = new RuleBasedCollator(rules); String tokens[] = {"a", "b", "c", "de", "fg", "hi", "j", "ab"}; coll.setAlternateHandlingShifted(true); for (int i = 0; i < tokens.length; i ++) { int varTopOriginal = coll.getVariableTop(); try { int varTop = coll.setVariableTop(tokens[i]); if (i > 4) { errln("Token " + tokens[i] + " expected to fail"); } if (varTop != coll.getVariableTop()) { errln("Error setting and getting variable top"); } CollationKey key1 = coll.getCollationKey(tokens[i]); for (int j = 0; j < i; j ++) { CollationKey key2 = coll.getCollationKey(tokens[j]); if (key2.compareTo(key1) < 0) { errln("Setting variable top shouldn't change the comparison sequence"); } byte sortorder[] = key2.toByteArray(); if (sortorder.length > 0 && (key2.toByteArray())[0] > 1) { errln("Primary sort order should be 0"); } } } catch (Exception e) { CollationElementIterator iter = coll.getCollationElementIterator(tokens[i]); /*int ce =*/ iter.next(); int ce2 = iter.next(); if (ce2 == CollationElementIterator.NULLORDER) { errln("Token " + tokens[i] + " not expected to fail"); } if (coll.getVariableTop() != varTopOriginal) { errln("When exception is thrown variable top should " + "not be changed"); } } coll.setVariableTop(varTopOriginal); if (varTopOriginal != coll.getVariableTop()) { errln("Couldn't restore old variable top\n"); } } // Testing calling with error set try { coll.setVariableTop(""); errln("Empty string should throw an IllegalArgumentException"); } catch (IllegalArgumentException e) { logln("PASS: Empty string failed as expected"); } try { coll.setVariableTop(null); errln("Null string should throw an IllegalArgumentException"); } catch (IllegalArgumentException e) { logln("PASS: null string failed as expected"); } } catch (Exception e) { warnln("Error creating RuleBasedCollator"); } } public void TestUCARules() { try { // only root locale can have empty tailorings .. not English! RuleBasedCollator coll = (RuleBasedCollator)Collator.getInstance(new Locale("","","")); String rule = coll.getRules(false); if (!rule.equals("")) { errln("Empty rule string should have empty rules " + rule); } rule = coll.getRules(true); if (rule.equals("")) { errln("UCA rule string should not be empty"); } coll = new RuleBasedCollator(rule); } catch (Exception e) { warnln(e.getMessage()); } } /** * Jitterbug 2726 */ public void TestShifted() { RuleBasedCollator collator = (RuleBasedCollator) Collator.getInstance(); collator.setStrength(Collator.PRIMARY); collator.setAlternateHandlingShifted(true); CollationTest.doTest(this, collator, " a", "a", 0); // works properly CollationTest.doTest(this, collator, "a", "a ", 0); // inconsistent results } /** * Test for CollationElementIterator previous and next for the whole set of * unicode characters with normalization on. */ public void TestNumericCollation() { String basicTestStrings[] = {"hello1", "hello2", "hello123456"}; String preZeroTestStrings[] = {"avery1", "avery01", "avery001", "avery0001"}; String thirtyTwoBitNumericStrings[] = {"avery42949672960", "avery42949672961", "avery42949672962", "avery429496729610"}; String supplementaryDigits[] = {"\uD835\uDFCE", // 0 "\uD835\uDFCF", // 1 "\uD835\uDFD0", // 2 "\uD835\uDFD1", // 3 "\uD835\uDFCF\uD835\uDFCE", // 10 "\uD835\uDFCF\uD835\uDFCF", // 11 "\uD835\uDFCF\uD835\uDFD0", // 12 "\uD835\uDFD0\uD835\uDFCE", // 20 "\uD835\uDFD0\uD835\uDFCF", // 21 "\uD835\uDFD0\uD835\uDFD0" // 22 }; String foreignDigits[] = {"\u0661", "\u0662", "\u0663", "\u0661\u0660", "\u0661\u0662", "\u0661\u0663", "\u0662\u0660", "\u0662\u0662", "\u0662\u0663", "\u0663\u0660", "\u0663\u0662", "\u0663\u0663" }; // Open our collator. RuleBasedCollator coll = (RuleBasedCollator)Collator.getInstance(Locale.ENGLISH); String att[] = {"NumericCollation"}; Boolean val[] = {Boolean.TRUE}; genericLocaleStarterWithOptions(Locale.ENGLISH, basicTestStrings, att, val); genericLocaleStarterWithOptions(Locale.ENGLISH, thirtyTwoBitNumericStrings, att, val); genericLocaleStarterWithOptions(Locale.ENGLISH, foreignDigits, att, val); genericLocaleStarterWithOptions(Locale.ENGLISH, supplementaryDigits, att, val); // Setting up our collator to do digits. coll.setNumericCollation(true); // Testing that prepended zeroes still yield the correct collation // behavior. // We expect that every element in our strings array will be equal. for (int i = 0; i < preZeroTestStrings.length - 1; i ++) { for (int j = i + 1; j < preZeroTestStrings.length; j ++) { CollationTest.doTest(this, coll, preZeroTestStrings[i], preZeroTestStrings[j],0); } } //cover setNumericCollationDefault, getNumericCollation assertTrue("The Numeric Collation setting is on", coll.getNumericCollation()); coll.setNumericCollationDefault(); logln("After set Numeric to default, the setting is: " + coll.getNumericCollation()); } public void Test3249() { String rule = "&x < a &z < a"; try { RuleBasedCollator coll = new RuleBasedCollator(rule); if(coll!=null){ logln("Collator did not throw an exception"); } } catch (Exception e) { warnln("Error creating RuleBasedCollator with " + rule + " failed"); } } public void TestTibetanConformance() { String test[] = {"\u0FB2\u0591\u0F71\u0061", "\u0FB2\u0F71\u0061"}; try { Collator coll = Collator.getInstance(); coll.setDecomposition(Collator.CANONICAL_DECOMPOSITION); if (coll.compare(test[0], test[1]) != 0) { errln("Tibetan comparison error"); } CollationTest.doTest(this, (RuleBasedCollator)coll, test[0], test[1], 0); } catch (Exception e) { warnln("Error creating UCA collator"); } } public void TestJ3347() { try { Collator coll = Collator.getInstance(Locale.FRENCH); ((RuleBasedCollator)coll).setAlternateHandlingShifted(true); if (coll.compare("6", "!6") != 0) { errln("Jitterbug 3347 failed"); } } catch (Exception e) { warnln("Error creating UCA collator"); } } public void TestPinyinProblem() { String test[] = { "\u4E56\u4E56\u7761", "\u4E56\u5B69\u5B50" }; genericLocaleStarter(new Locale("zh", "", "PINYIN"), test); } static final long topByte = 0xFF000000L; static final long bottomByte = 0xFFL; static final long fourBytes = 0xFFFFFFFFL; static final int MAX_INPUT = 0x220001; // 2 * Unicode range + 2 private void show(int i, ImplicitCEGenerator imp) { if (i >= 0 && i <= MAX_INPUT) { logln(Utility.hex(i) + "\t" + Utility.hex(imp.getImplicitFromRaw(i) & fourBytes)); } } private void throwError(String title, int cp, ImplicitCEGenerator imp) { throw new IllegalArgumentException(title + "\t" + Utility.hex(cp, 6) + "\t" + Utility.hex(imp.getImplicitFromRaw(cp) & fourBytes)); } private void throwError(String title, long ce) { errln(title + "\t" + Utility.hex(ce & fourBytes)); } public void TestImplicitGeneration() { logln("Start"); try { ImplicitCEGenerator foo = new ImplicitCEGenerator(0xE0, 0xE4); //int x = foo.getRawImplicit(0xF810); foo.getRawFromImplicit(0xE20303E7); //int gap4 = foo.getGap4(); //logln("Gap4: " + gap4); //int gap3 = foo.getGap3(); //int minTrail = foo.getMinTrail(); //int maxTrail = foo.getMaxTrail(); long last = 0; long current; for (int i = 0; i <= MAX_INPUT; ++i) { current = foo.getImplicitFromRaw(i) & fourBytes; // check that it round-trips AND that all intervening ones are illegal int roundtrip = foo.getRawFromImplicit((int)current); if (roundtrip != i) { throwError("No roundtrip", i, foo); } if (last != 0) { for (long j = last + 1; j < current; ++j) { roundtrip = foo.getRawFromImplicit((int)j); // raise an error if it *doesn't* find an error if (roundtrip != -1) { throwError("Fails to recognize illegal", j); } } } // now do other consistency checks long lastBottom = last & bottomByte; long currentBottom = current & bottomByte; long lastTop = last & topByte; long currentTop = current & topByte; // do some consistency checks /* long gap = current - last; if (currentBottom != 0) { // if we are a 4-byte // gap has to be at least gap4 // and gap from minTrail, maxTrail has to be at least gap4 if (gap <= gap4) foo.throwError("Failed gap4 between", i); if (currentBottom < minTrail + gap4) foo.throwError("Failed gap4 before", i); if (currentBottom > maxTrail - gap4) foo.throwError("Failed gap4 after", i); } else { // we are a three-byte gap = gap >> 8; // move gap down for comparison. long current3Bottom = (current >> 8) & bottomByte; if (gap <= gap3) foo.throwError("Failed gap3 between ", i); if (current3Bottom < minTrail + gap3) foo.throwError("Failed gap3 before", i); if (current3Bottom > maxTrail - gap3) foo.throwError("Failed gap3 after", i); } */ // print out some values for spot-checking if (lastTop != currentTop || i == 0x10000 || i == 0x110000) { show(i-3, foo); show(i-2, foo); show(i-1, foo); if (i == 0) { // do nothing } else if (lastBottom == 0 && currentBottom != 0) { logln("+ primary boundary, 4-byte CE's below"); } else if (lastTop != currentTop) { logln("+ primary boundary"); } show(i, foo); show(i+1, foo); show(i+2, foo); logln("..."); } last = current; if(foo.getCodePointFromRaw(foo.getRawFromCodePoint(i)) != i) { errln("No raw <-> code point roundtrip for "+Utility.hex(i)); } } show(MAX_INPUT-2, foo); show(MAX_INPUT-1, foo); show(MAX_INPUT, foo); } catch (Exception e) { e.printStackTrace(); warnln(e.getMessage()); } finally { logln("End"); } } /* supercedes TestJ784 */ public void TestBeforePinyin() { String rules = "&[before 2]A << \u0101 <<< \u0100 << \u00E1 <<< \u00C1 << \u01CE <<< \u01CD << \u00E0 <<< \u00C0" + "&[before 2]e << \u0113 <<< \u0112 << \u00E9 <<< \u00C9 << \u011B <<< \u011A << \u00E8 <<< \u00C8" + "&[before 2] i << \u012B <<< \u012A << \u00ED <<< \u00CD << \u01D0 <<< \u01CF << \u00EC <<< \u00CC" + "&[before 2] o << \u014D <<< \u014C << \u00F3 <<< \u00D3 << \u01D2 <<< \u01D1 << \u00F2 <<< \u00D2" + "&[before 2]u << \u016B <<< \u016A << \u00FA <<< \u00DA << \u01D4 <<< \u01D3 << \u00F9 <<< \u00D9" + "&U << \u01D6 <<< \u01D5 << \u01D8 <<< \u01D7 << \u01DA <<< \u01D9 << \u01DC <<< \u01DB << \u00FC"; String test[] = { "l\u0101", "la", "l\u0101n", "lan ", "l\u0113", "le", "l\u0113n", "len" }; String test2[] = { "x\u0101", "x\u0100", "X\u0101", "X\u0100", "x\u00E1", "x\u00C1", "X\u00E1", "X\u00C1", "x\u01CE", "x\u01CD", "X\u01CE", "X\u01CD", "x\u00E0", "x\u00C0", "X\u00E0", "X\u00C0", "xa", "xA", "Xa", "XA", "x\u0101x", "x\u0100x", "x\u00E1x", "x\u00C1x", "x\u01CEx", "x\u01CDx", "x\u00E0x", "x\u00C0x", "xax", "xAx" }; /* TODO: port builder fixes to before */ genericRulesStarter(rules, test); genericLocaleStarter(new Locale("zh","",""), test); genericRulesStarter(rules, test2); genericLocaleStarter(new Locale("zh","",""), test2); } public void TestUpperFirstQuaternary() { String tests[] = { "B", "b", "Bb", "bB" }; String[] att = { "strength", "UpperFirst" }; Object attVals[] = { new Integer(Collator.QUATERNARY), Boolean.TRUE }; genericLocaleStarterWithOptions(new Locale("root","",""), tests, att, attVals); } public void TestJ4960() { String tests[] = { "\\u00e2T", "aT" }; String att[] = { "strength", "CaseLevel" }; Object attVals[] = { new Integer(Collator.PRIMARY), Boolean.TRUE }; String tests2[] = { "a", "A" }; String rule = "&[first tertiary ignorable]=A=a"; String att2[] = { "CaseLevel" }; Object attVals2[] = { Boolean.TRUE }; // Test whether we correctly ignore primary ignorables on case level when // we have only primary & case level genericLocaleStarterWithOptionsAndResult(new Locale("root", ""), tests, att, attVals, 0); // Test whether ICU4J will make case level for sortkeys that have primary strength // and case level genericLocaleStarterWithOptions(new Locale("root", ""), tests2, att, attVals); // Test whether completely ignorable letters have case level info (they shouldn't) genericRulesStarterWithOptionsAndResult(rule, tests2, att2, attVals2, 0); } public void TestJB5298(){ ULocale[] locales = Collator.getAvailableULocales(); logln("Number of collator locales returned : " + locales.length); // double-check keywords String[] keywords = Collator.getKeywords(); if (keywords.length != 1 || !keywords[0].equals("collation")) { throw new IllegalArgumentException("internal collation error"); } String[] values = Collator.getKeywordValues("collation"); log("Collator.getKeywordValues returned: "); for(int i=0; i= 0 ? can.substring(idx+11, can.length()) : ""; if(val.length()>0 && !foundValues.contains(val)){ errln("Unknown collation found "+ can); } } } logln(" "); } public void TestJ5367() { String[] test = { "a", "y" }; String rules = "&Ny << Y &[first secondary ignorable] <<< a"; genericRulesStarter(rules, test); } public void TestVI5913() { String rules[] = { "&a < \u00e2 <<< \u00c2", "&a < \u1FF3 ", // OMEGA WITH YPOGEGRAMMENI "&s < \u0161 ", // &s < s with caron "&z < a\u00EA", // &z < a+e with circumflex }; String cases[][] = { { "\u1EAC", "A\u0323\u0302", "\u1EA0\u0302", "\u00C2\u0323", }, { "\u1FA2", "\u03C9\u0313\u0300\u0345", "\u1FF3\u0313\u0300", "\u1F60\u0300\u0345", "\u1f62\u0345", "\u1FA0\u0300", }, { "\u1E63\u030C", "s\u0323\u030C", "s\u030C\u0323"}, { "a\u1EC7", // a+ e with dot below and circumflex "a\u1EB9\u0302", // a + e with dot below + combining circumflex "a\u00EA\u0323", // a + e with circumflex + combining dot below } }; for(int i = 0; i < rules.length; i++) { RuleBasedCollator coll = null; try { coll = new RuleBasedCollator(rules[i]); } catch (Exception e) { warnln("Unable to open collator with rules " + rules[i]); } logln("Test case["+i+"]:"); CollationKey expectingKey = coll.getCollationKey(cases[i][0]); for (int j=1; j=0) { CollationKey key = coll.getCollationKey(firstVariable); logln("Collation key for 0x0009: "+prettify(key)); errln("Error! String \"a\" must be less than 0x0009 - [First Variable]"); } CollationKey keyB = coll.getCollationKey("b"); logln("Key for \"b\":"+ prettify(keyB)); if (keyB.compareTo(coll.getCollationKey(firstPrimIgn))<=0) { CollationKey key = coll.getCollationKey(firstPrimIgn); logln("Collation key for 0x0332: "+prettify(key)); errln("Error! String \"b\" must be greater than 0x0332 -"+ "[First Primary Ignorable]"); } if (keyB.compareTo(coll.getCollationKey(firstVariable))>=0) { CollationKey key = coll.getCollationKey(firstVariable); logln("Collation key for 0x0009: "+prettify(key)); errln("Error! String \"b\" must be less than 0x0009 - [First Variable]"); } } { i=1; RuleBasedCollator coll = null; try { coll = new RuleBasedCollator(rules[i]); } catch (Exception e) { warnln("Unable to open collator with rules " + rules[i]); } logln("Test rule["+i+"]"+rules[i]); CollationKey keyA = coll.getCollationKey("a"); logln("Key for \"a\":"+ prettify(keyA)); byte[] keyAInBytes = keyA.toByteArray(); for (int j=0; j=0) { errln("Error! String \"a\" must be less than 0x0009 - [First Variable]"); CollationKey key = coll.getCollationKey(firstVariable); logln("Collation key for 0x0009: "+prettify(key)); } CollationKey keyB = coll.getCollationKey("b"); logln("Key for \"b\":"+ prettify(keyB)); byte[] keyBInBytes = keyB.toByteArray(); for (int j=0; j=0) { CollationKey key = coll.getCollationKey(firstVariable); logln("Collation key for 0x0009: "+prettify(key)); errln("Error! String \"b\" must be less than 0x0009 - [First Variable]"); } } } public void TestUCAPrecontext() { String rules[] = { "& \u00B70) { CollationKey prevKey = en.getCollationKey(cases[j-1]); if (key.compareTo(prevKey)<0) { errln("Error! EN test["+j+"]:"+"source:" + cases[j]+ "is not greater than previous test."); } } /* if ( key.compareTo(expectingKey)!=0) { errln("Error! Test case["+i+"]:"+"source:" + key.getSourceString()); errln("expecting:"+prettify(expectingKey)+ "got:"+ prettify(key)); } */ logln("String:"+cases[j]+" Key:"+ prettify(key)); } } catch (Exception e) { warnln("Error creating Vietnese collator"); return; } // Test ja sort RuleBasedCollator ja = null; logln("JA sort:"); try { ja = (RuleBasedCollator)Collator.getInstance( new Locale("ja", "")); for (int j=0; j0) { CollationKey prevKey = ja.getCollationKey(cases[j-1]); if (key.compareTo(prevKey)<0) { errln("Error! JA test["+j+"]:"+"source:" + cases[j]+ "is not greater than previous test."); } } logln("String:"+cases[j]+" Key:"+ prettify(key)); } } catch (Exception e) { warnln("Error creating Vietnese collator"); return; } for(int i = 0; i < rules.length; i++) { RuleBasedCollator coll = null; logln("Tailoring rule:"+rules[i]); try { coll = new RuleBasedCollator(rules[i]); } catch (Exception e) { warnln("Unable to open collator with rules " + rules[i]); } for (int j=0; j0) { CollationKey prevKey = coll.getCollationKey(cases[j-1]); if (i==1 && j==3) { if (key.compareTo(prevKey)>0) { errln("Error! Rule:"+rules[i]+" test["+j+"]:"+"source:"+ cases[j]+"is not greater than previous test."); } } else { if (key.compareTo(prevKey)<0) { errln("Error! Rule:"+rules[i]+" test["+j+"]:"+"source:"+ cases[j]+"is not greater than previous test."); } } } logln("String:"+cases[j]+" Key:"+ prettify(key)); } } } public void TestSameStrengthList() { String[] testSourceCases = { "\u0061", "\u0061", "\u006c\u0061", "\u0061\u0061\u0061", "\u0062", }; String[] testTargetCases = { "\u0031", "\u0066", "\u006b\u0062", "\u0031\u0032\u0033", "\u007a", }; int[] results = { 0, -1, -1, 0, -1 }; Collator myCollation; String rules = "&a<*bcd &b<<*klm &k<<<*xyz &a=*123"; try { myCollation = new RuleBasedCollator(rules); } catch (Exception e) { warnln("ERROR: in creation of rule based collator"); return; } // logln("Testing some A letters, for some reason"); myCollation.setDecomposition(Collator.CANONICAL_DECOMPOSITION); myCollation.setStrength(Collator.TERTIARY); for (int i = 0; i < 5 ; i++) { CollationTest.doTest(this, (RuleBasedCollator)myCollation, testSourceCases[i], testTargetCases[i], results[i]); } } /* * Tests the method public boolean equals(Object target) in CollationKey */ public void TestCollationKeyEquals() { CollationKey ck = new CollationKey("", (byte[]) null); // Tests when "if (!(target instanceof CollationKey))" is true if (ck.equals(new Object())) { errln("CollationKey.equals() was not suppose to return false " + "since it is comparing to a non Collation Key object."); } if (ck.equals("")) { errln("CollationKey.equals() was not suppose to return false " + "since it is comparing to a non Collation Key object."); } if (ck.equals(0)) { errln("CollationKey.equals() was not suppose to return false " + "since it is comparing to a non Collation Key object."); } if (ck.equals(0.0)) { errln("CollationKey.equals() was not suppose to return false " + "since it is comparing to a non Collation Key object."); } // Tests when "if (target == null)" is true if (ck.equals((CollationKey) null)) { errln("CollationKey.equals() was not suppose to return false " + "since it is comparing to a null Collation Key object."); } } /* * Tests the method public int hashCode() in CollationKey */ public void TestCollationKeyHashCode() { CollationKey ck = new CollationKey("", (byte[]) null); // Tests when "if (m_key_ == null)" is true if (ck.hashCode() != 1) { errln("CollationKey.hashCode() was suppose to return 1 " + "when m_key is null due a null parameter in the " + "constructor."); } } /* * Tests the method public CollationKey getBound(int boundType, int noOfLevels) */ public void TestGetBound() { CollationKey ck = new CollationKey("", (byte[]) null); // Tests when "if (noOfLevels > Collator.PRIMARY)" is false // Tests when "default: " is true for "switch (boundType)" try { ck.getBound(BoundMode.COUNT, -1); errln("CollationKey.getBound(int,int) was suppose to return an " + "exception for an invalid boundType value."); } catch (Exception e) { } // Tests when "if (noOfLevels > 0)" byte b[] = {}; CollationKey ck1 = new CollationKey("", b); try { ck1.getBound(0, 1); errln("CollationKey.getBound(int,int) was suppose to return an " + "exception a value of noOfLevels that exceeds expected."); } catch (Exception e) { } } /* * Tests the method public CollationKey merge(CollationKey source) */ public void TestMerge() { byte b[] = {}; CollationKey ck = new CollationKey("", b); // Tests when "if (source == null || source.getLength() == 0)" is true try { ck.merge(null); errln("Collationkey.merge(CollationKey) was suppose to return " + "an exception for a null parameter."); } catch (Exception e) { } try { ck.merge(ck); errln("Collationkey.merge(CollationKey) was suppose to return " + "an exception for a null parameter."); } catch (Exception e) { } } /* Test the method public int compareTo(RawCollationKey rhs) */ public void TestRawCollationKeyCompareTo(){ RawCollationKey rck = new RawCollationKey(); byte[] b = {(byte) 10, (byte) 20}; RawCollationKey rck100 = new RawCollationKey(b, 2); if(rck.compareTo(rck) != 0){ errln("RawCollatonKey.compareTo(RawCollationKey) was suppose to return 0 " + "for two idential RawCollationKey objects."); } if(rck.compareTo(rck100) == 0){ errln("RawCollatonKey.compareTo(RawCollationKey) was not suppose to return 0 " + "for two different RawCollationKey objects."); } } }