blob: 2e47cdc71d7825f8f2f3f1606e77997fd46d22bb [file] [log] [blame]
/*
*******************************************************************************
* Copyright (C) 2002-2006, 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 com.ibm.icu.dev.test.TestFmwk;
import com.ibm.icu.util.UResourceBundle;
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.RuleBasedCollator;
import com.ibm.icu.text.UTF16;
import java.util.Locale;
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]<<<k",
// - all befores here amount to zero
"&[before 3][first tertiary ignorable]<<<a",
"&[before 3][last tertiary ignorable]<<<a",
"&[before 3][first secondary ignorable]<<<a",
"&[before 3][last secondary ignorable]<<<a",
// 'normal' befores
"&[before 3][first primary ignorable]<<<c<<<b &[first primary ignorable]<a",
// we don't have a code point that corresponds to the last primary
// ignorable
"&[before 3][last primary ignorable]<<<c<<<b &[last primary ignorable]<a",
"&[before 3][first variable]<<<c<<<b &[first variable]<a",
"&[last variable]<a &[before 3][last variable]<<<c<<<b ",
"&[first regular]<a &[before 1][first regular]<b",
"&[before 1][last regular]<b &[last regular]<a",
"&[before 1][first implicit]<b &[first implicit]<a",
"&[before 1][last implicit]<b &[last implicit]<a",
"&[last variable]<z&[last primary ignorable]<x&[last secondary ignorable]<<y&[last tertiary ignorable]<<<w&[top]<u",
};
String[][] data = {
// {"k", "\u20e3"},
{"\\u0000", "a"}, // you cannot go before first tertiary ignorable
{"\\u0000", "a"}, // you cannot go before last tertiary ignorable
{"\\u0000", "a"}, // you cannot go before first secondary ignorable
{"\\u0000", "a"}, // you cannot go before first secondary ignorable
{"c", "b", "\\u0332", "a"},
{"\\u0332", "\\u20e3", "c", "b", "a"},
{"c", "b", "\\u0009", "a", "\\u000a"},
{"c", "b", "\\uD802\\uDE47", "a", "\\u02d0"},
{"b", "\\u02d0", "a", "\\u02d1"},
{"b", "\\ud800\\udfcf", "a", "\\u4e00"},
{"b", "\\u4e00", "a", "\\u4e01"},
{"b", "\\U0010FFFD", "a"},
{"\ufffb", "w", "y", "\u20e3", "x", "\u137c", "z", "u"},
};
for (int i = 0; i< rules.length; i++) {
genericRulesStarter(rules[i], data[i]);
}
}
void genericRulesStarter(String rules, String[] s) {
genericRulesTestWithResult(rules, s, -1);
}
void genericRulesTestWithResult(String rules, String[] s, int result) {
RuleBasedCollator coll = null;
try {
coll = new RuleBasedCollator(rules);
// logln("Rules starter for " + rules);
genericOrderingTestWithResult(coll, s, result);
} catch (Exception e) {
warnln("Unable to open collator with rules " + rules);
}
}
void genericOrderingTestWithResult(Collator coll, String[] s, int result) {
String t1 = "";
String t2 = "";
for(int i = 0; i < s.length - 1; i++) {
for(int j = i+1; j < s.length; j++) {
t1 = Utility.unescape(s[i]);
t2 = Utility.unescape(s[j]);
// System.out.println(i + " " + j);
CollationTest.doTest(this, (RuleBasedCollator)coll, t1, t2,
result);
}
}
}
void reportCResult(String source, String target, CollationKey sourceKey, CollationKey targetKey,
int compareResult, int keyResult, int incResult, int expectedResult ) {
if (expectedResult < -1 || expectedResult > 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++) {
target += Integer.toHexString(bytes[i]);
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++) {
genericRulesTestWithResult(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"
};
genericRulesTestWithResult(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; i<rules.length; i++) {
genericRulesStarter(rules[i], data[i]);
}
}
public void TestNewJapanese() {
String test1[] = {
"\u30b7\u30e3\u30fc\u30ec",
"\u30b7\u30e3\u30a4",
"\u30b7\u30e4\u30a3",
"\u30b7\u30e3\u30ec",
"\u3061\u3087\u3053",
"\u3061\u3088\u3053",
"\u30c1\u30e7\u30b3\u30ec\u30fc\u30c8",
"\u3066\u30fc\u305f",
"\u30c6\u30fc\u30bf",
"\u30c6\u30a7\u30bf",
"\u3066\u3048\u305f",
"\u3067\u30fc\u305f",
"\u30c7\u30fc\u30bf",
"\u30c7\u30a7\u30bf",
"\u3067\u3048\u305f",
"\u3066\u30fc\u305f\u30fc",
"\u30c6\u30fc\u30bf\u30a1",
"\u30c6\u30a7\u30bf\u30fc",
"\u3066\u3047\u305f\u3041",
"\u3066\u3048\u305f\u30fc",
"\u3067\u30fc\u305f\u30fc",
"\u30c7\u30fc\u30bf\u30a1",
"\u3067\u30a7\u305f\u30a1",
"\u30c7\u3047\u30bf\u3041",
"\u30c7\u30a8\u30bf\u30a2",
"\u3072\u3086",
"\u3073\u3085\u3042",
"\u3074\u3085\u3042",
"\u3073\u3085\u3042\u30fc",
"\u30d3\u30e5\u30a2\u30fc",
"\u3074\u3085\u3042\u30fc",
"\u30d4\u30e5\u30a2\u30fc",
"\u30d2\u30e5\u30a6",
"\u30d2\u30e6\u30a6",
"\u30d4\u30e5\u30a6\u30a2",
"\u3073\u3085\u30fc\u3042\u30fc",
"\u30d3\u30e5\u30fc\u30a2\u30fc",
"\u30d3\u30e5\u30a6\u30a2\u30fc",
"\u3072\u3085\u3093",
"\u3074\u3085\u3093",
"\u3075\u30fc\u308a",
"\u30d5\u30fc\u30ea",
"\u3075\u3045\u308a",
"\u3075\u30a5\u308a",
"\u3075\u30a5\u30ea",
"\u30d5\u30a6\u30ea",
"\u3076\u30fc\u308a",
"\u30d6\u30fc\u30ea",
"\u3076\u3045\u308a",
"\u30d6\u30a5\u308a",
"\u3077\u3046\u308a",
"\u30d7\u30a6\u30ea",
"\u3075\u30fc\u308a\u30fc",
"\u30d5\u30a5\u30ea\u30fc",
"\u3075\u30a5\u308a\u30a3",
"\u30d5\u3045\u308a\u3043",
"\u30d5\u30a6\u30ea\u30fc",
"\u3075\u3046\u308a\u3043",
"\u30d6\u30a6\u30ea\u30a4",
"\u3077\u30fc\u308a\u30fc",
"\u3077\u30a5\u308a\u30a4",
"\u3077\u3046\u308a\u30fc",
"\u30d7\u30a6\u30ea\u30a4",
"\u30d5\u30fd",
"\u3075\u309e",
"\u3076\u309d",
"\u3076\u3075",
"\u3076\u30d5",
"\u30d6\u3075",
"\u30d6\u30d5",
"\u3076\u309e",
"\u3076\u3077",
"\u30d6\u3077",
"\u3077\u309d",
"\u30d7\u30fd",
"\u3077\u3075",
};
String test2[] = {
"\u306f\u309d", // H\u309d
"\u30cf\u30fd", // K\u30fd
"\u306f\u306f", // HH
"\u306f\u30cf", // HK
"\u30cf\u30cf", // KK
"\u306f\u309e", // H\u309e
"\u30cf\u30fe", // K\u30fe
"\u306f\u3070", // HH\u309b
"\u30cf\u30d0", // KK\u309b
"\u306f\u3071", // HH\u309c
"\u30cf\u3071", // KH\u309c
"\u30cf\u30d1", // KK\u309c
"\u3070\u309d", // H\u309b\u309d
"\u30d0\u30fd", // K\u309b\u30fd
"\u3070\u306f", // H\u309bH
"\u30d0\u30cf", // K\u309bK
"\u3070\u309e", // H\u309b\u309e
"\u30d0\u30fe", // K\u309b\u30fe
"\u3070\u3070", // H\u309bH\u309b
"\u30d0\u3070", // K\u309bH\u309b
"\u30d0\u30d0", // K\u309bK\u309b
"\u3070\u3071", // H\u309bH\u309c
"\u30d0\u30d1", // K\u309bK\u309c
"\u3071\u309d", // H\u309c\u309d
"\u30d1\u30fd", // K\u309c\u30fd
"\u3071\u306f", // H\u309cH
"\u30d1\u30cf", // K\u309cK
"\u3071\u3070", // H\u309cH\u309b
"\u3071\u30d0", // H\u309cK\u309b
"\u30d1\u30d0", // K\u309cK\u309b
"\u3071\u3071", // H\u309cH\u309c
"\u30d1\u30d1", // K\u309cK\u309c
};
String[] att = { "strength", };
Object[] val = { new Integer(Collator.QUATERNARY), };
String[] attShifted = { "strength", "AlternateHandling"};
Object valShifted[] = { new Integer(Collator.QUATERNARY),
new Boolean(true) };
genericLocaleStarterWithOptions(Locale.JAPANESE, test1, att, val);
genericLocaleStarterWithOptions(Locale.JAPANESE, test2, att, val);
genericLocaleStarterWithOptions(Locale.JAPANESE, test1, attShifted,
valShifted);
genericLocaleStarterWithOptions(Locale.JAPANESE, test2, attShifted,
valShifted);
}
void genericLocaleStarter(Locale locale, String s[]) {
RuleBasedCollator coll = null;
try {
coll = (RuleBasedCollator)Collator.getInstance(locale);
} catch (Exception e) {
warnln("Unable to open collator for locale " + locale);
return;
}
// logln("Locale starter for " + locale);
genericOrderingTest(coll, s);
}
void genericLocaleStarterWithOptions(Locale locale, String[] s, String[] attrs, Object[] values) {
RuleBasedCollator coll = null;
try {
coll = (RuleBasedCollator)Collator.getInstance(locale);
} catch (Exception e) {
warnln("Unable to open collator for locale " + locale);
return;
}
// logln("Locale starter for " +locale);
// logln("Setting attributes");
for(int i = 0; i < attrs.length; i++) {
if (attrs[i].equals("strength")) {
coll.setStrength(((Integer)values[i]).intValue());
}
else if (attrs[i].equals("decomp")) {
coll.setDecomposition(((Integer)values[i]).intValue());
}
else if (attrs[i].equals("AlternateHandling")) {
coll.setAlternateHandlingShifted(((Boolean)values[i]
).booleanValue());
}
else if (attrs[i].equals("NumericCollation")) {
coll.setNumericCollation(((Boolean)values[i]).booleanValue());
}
else if (attrs[i].equals("UpperFirst")) {
coll.setUpperCaseFirst(((Boolean)values[i]).booleanValue());
}
else if (attrs[i].equals("LowerFirst")) {
coll.setLowerCaseFirst(((Boolean)values[i]).booleanValue());
}
}
genericOrderingTest(coll, s);
}
void genericOrderingTest(Collator coll, String[] s) {
genericOrderingTestWithResult(coll, s, -1);
}
public void TestNonChars() {
String test[] = {
"\u0000",
"\uFFFE", "\uFFFF",
"\\U0001FFFE", "\\U0001FFFF",
"\\U0002FFFE", "\\U0002FFFF",
"\\U0003FFFE", "\\U0003FFFF",
"\\U0004FFFE", "\\U0004FFFF",
"\\U0005FFFE", "\\U0005FFFF",
"\\U0006FFFE", "\\U0006FFFF",
"\\U0007FFFE", "\\U0007FFFF",
"\\U0008FFFE", "\\U0008FFFF",
"\\U0009FFFE", "\\U0009FFFF",
"\\U000AFFFE", "\\U000AFFFF",
"\\U000BFFFE", "\\U000BFFFF",
"\\U000CFFFE", "\\U000CFFFF",
"\\U000DFFFE", "\\U000DFFFF",
"\\U000EFFFE", "\\U000EFFFF",
"\\U000FFFFE", "\\U000FFFFF",
"\\U0010FFFE", "\\U0010FFFF"
};
Collator coll = null;
try {
coll = Collator.getInstance(new Locale("en", "US"));
} catch (Exception e) {
warnln("Unable to open collator");
return;
}
// logln("Test non characters");
genericOrderingTestWithResult(coll, test, 0);
}
public void TestExtremeCompression() {
String[] test = new String[4];
for(int i = 0; i<4; i++) {
StringBuffer temp = new StringBuffer();
for (int j = 0; j < 2047; j++) {
temp.append('a');
}
temp.append((char)('a' + i));
test[i] = temp.toString();
}
genericLocaleStarter(new Locale("en", "US"), test);
}
/**
* Tests surrogate support.
*/
public void TestSurrogates() {
String test[] = {"z","\ud900\udc25", "\ud805\udc50", "\ud800\udc00y",
"\ud800\udc00r", "\ud800\udc00f", "\ud800\udc00",
"\ud800\udc00c", "\ud800\udc00b", "\ud800\udc00fa",
"\ud800\udc00fb", "\ud800\udc00a", "c", "b"};
String rule = "&z < \ud900\udc25 < \ud805\udc50 < \ud800\udc00y "
+ "< \ud800\udc00r < \ud800\udc00f << \ud800\udc00 "
+ "< \ud800\udc00fa << \ud800\udc00fb < \ud800\udc00a "
+ "< c < b";
genericRulesStarter(rule, test);
}
public void TestBocsuCoverage() {
String test = "\u0041\u0441\u4441\\U00044441\u4441\u0441\u0041";
Collator coll = Collator.getInstance();
coll.setStrength(Collator.IDENTICAL);
CollationKey key = coll.getCollationKey(test);
logln("source:" + key.getSourceString());
}
public void TestCyrillicTailoring() {
String test[] = {
"\u0410b",
"\u0410\u0306a",
"\u04d0A"
};
genericLocaleStarter(new Locale("en", ""), test);
genericRulesStarter("&\u0410 = \u0410", test);
genericRulesStarter("&Z < \u0410", test);
genericRulesStarter("&\u0410 = \u0410 < \u04d0", test);
genericRulesStarter("&Z < \u0410 < \u04d0", test);
genericRulesStarter("&\u0410 = \u0410 < \u0410\u0301", test);
genericRulesStarter("&Z < \u0410 < \u0410\u0301", test);
}
public void TestSuppressContractions() {
String testNoCont2[] = {
"\u0410\u0302a",
"\u0410\u0306b",
"\u0410c"
};
String testNoCont[] = {
"a\u0410",
"A\u0410\u0306",
"\uFF21\u0410\u0302"
};
genericRulesStarter("[suppressContractions [\u0400-\u047f]]", testNoCont);
genericRulesStarter("[suppressContractions [\u0400-\u047f]]", testNoCont2);
}
public void TestCase() {
String gRules = "\u0026\u0030\u003C\u0031\u002C\u2460\u003C\u0061\u002C\u0041";
String[] testCase = {
"1a", "1A", "\u2460a", "\u2460A"
};
int[][] caseTestResults = {
{ -1, -1, -1, 0, -1, -1, 0, 0, -1 },
{ 1, -1, -1, 0, -1, -1, 0, 0, 1 },
{ -1, -1, -1, 0, 1, -1, 0, 0, -1 },
{ 1, -1, 1, 0, -1, -1, 0, 0, 1 }
};
boolean[][] caseTestAttributes = {
{ false, false},
{ true, false},
{ false, true},
{ true, true}
};
int i,j,k;
Collator myCollation;
try {
myCollation = Collator.getInstance(new Locale("en", "US"));
} catch (Exception e) {
warnln("ERROR: in creation of rule based collator ");
return;
}
// logln("Testing different case settings");
myCollation.setStrength(Collator.TERTIARY);
for(k = 0; k <4; k++) {
if (caseTestAttributes[k][0] == true) {
// upper case first
((RuleBasedCollator)myCollation).setUpperCaseFirst(true);
}
else {
// upper case first
((RuleBasedCollator)myCollation).setLowerCaseFirst(true);
}
((RuleBasedCollator)myCollation).setCaseLevel(
caseTestAttributes[k][1]);
// logln("Case first = " + caseTestAttributes[k][0] + ", Case level = " + caseTestAttributes[k][1]);
for (i = 0; i < 3 ; i++) {
for(j = i+1; j<4; j++) {
CollationTest.doTest(this,
(RuleBasedCollator)myCollation,
testCase[i], testCase[j],
caseTestResults[k][3*i+j-1]);
}
}
}
try {
myCollation = new RuleBasedCollator(gRules);
} catch (Exception e) {
warnln("ERROR: in creation of rule based collator");
return;
}
// logln("Testing different case settings with custom rules");
myCollation.setStrength(Collator.TERTIARY);
for(k = 0; k<4; k++) {
if (caseTestAttributes[k][0] == true) {
((RuleBasedCollator)myCollation).setUpperCaseFirst(true);
}
else {
((RuleBasedCollator)myCollation).setUpperCaseFirst(false);
}
((RuleBasedCollator)myCollation).setCaseLevel(
caseTestAttributes[k][1]);
for (i = 0; i < 3 ; i++) {
for(j = i+1; j<4; j++) {
CollationTest.doTest(this,
(RuleBasedCollator)myCollation,
testCase[i], testCase[j],
caseTestResults[k][3*i+j-1]);
}
}
}
{
String[] lowerFirst = {
"h",
"H",
"ch",
"Ch",
"CH",
"cha",
"chA",
"Cha",
"ChA",
"CHa",
"CHA",
"i",
"I"
};
String[] upperFirst = {
"H",
"h",
"CH",
"Ch",
"ch",
"CHA",
"CHa",
"ChA",
"Cha",
"chA",
"cha",
"I",
"i"
};
// logln("mixed case test");
// logln("lower first, case level off");
genericRulesStarter("[casefirst lower]&H<ch<<<Ch<<<CH", lowerFirst);
// logln("upper first, case level off");
genericRulesStarter("[casefirst upper]&H<ch<<<Ch<<<CH", upperFirst);
// logln("lower first, case level on");
genericRulesStarter("[casefirst lower][caselevel on]&H<ch<<<Ch<<<CH", lowerFirst);
// logln("upper first, case level on");
genericRulesStarter("[casefirst upper][caselevel on]&H<ch<<<Ch<<<CH", upperFirst);
}
}
public void TestIncompleteCnt() {
String[] cnt1 = {
"AA",
"AC",
"AZ",
"AQ",
"AB",
"ABZ",
"ABQ",
"Z",
"ABC",
"Q",
"B"
};
String[] cnt2 = {
"DA",
"DAD",
"DAZ",
"MAR",
"Z",
"DAVIS",
"MARK",
"DAV",
"DAVI"
};
RuleBasedCollator coll = null;
String temp = " & Z < ABC < Q < B";
try {
coll = new RuleBasedCollator(temp);
} catch (Exception e) {
warnln("fail to create RuleBasedCollator");
return;
}
int size = cnt1.length;
for(int i = 0; i < size-1; i++) {
for(int j = i+1; j < size; j++) {
String t1 = cnt1[i];
String t2 = cnt1[j];
CollationTest.doTest(this, coll, t1, t2, -1);
}
}
temp = " & Z < DAVIS < MARK <DAV";
try {
coll = new RuleBasedCollator(temp);
} catch (Exception e) {
warnln("fail to create RuleBasedCollator");
return;
}
size = cnt2.length;
for(int i = 0; i < size-1; i++) {
for(int j = i+1; j < size; j++) {
String t1 = cnt2[i];
String t2 = cnt2[j];
CollationTest.doTest(this, coll, t1, t2, -1);
}
}
}
public void TestBlackBird() {
String[] shifted = {
"black bird",
"black-bird",
"blackbird",
"black Bird",
"black-Bird",
"blackBird",
"black birds",
"black-birds",
"blackbirds"
};
int[] shiftedTert = {
0,
0,
0,
-1,
0,
0,
-1,
0,
0
};
String[] nonignorable = {
"black bird",
"black Bird",
"black birds",
"black-bird",
"black-Bird",
"black-birds",
"blackbird",
"blackBird",
"blackbirds"
};
int i = 0, j = 0;
int size = 0;
Collator coll = Collator.getInstance(new Locale("en", "US"));
//ucol_setAttribute(coll, UCOL_NORMALIZATION_MODE, UCOL_OFF, &status);
//ucol_setAttribute(coll, UCOL_ALTERNATE_HANDLING, UCOL_NON_IGNORABLE, &status);
((RuleBasedCollator)coll).setAlternateHandlingShifted(false);
size = nonignorable.length;
for(i = 0; i < size-1; i++) {
for(j = i+1; j < size; j++) {
String t1 = nonignorable[i];
String t2 = nonignorable[j];
CollationTest.doTest(this, (RuleBasedCollator)coll, t1, t2, -1);
}
}
((RuleBasedCollator)coll).setAlternateHandlingShifted(true);
coll.setStrength(Collator.QUATERNARY);
size = shifted.length;
for(i = 0; i < size-1; i++) {
for(j = i+1; j < size; j++) {
String t1 = shifted[i];
String t2 = shifted[j];
CollationTest.doTest(this, (RuleBasedCollator)coll, t1, t2, -1);
}
}
coll.setStrength(Collator.TERTIARY);
size = shifted.length;
for(i = 1; i < size; i++) {
String t1 = shifted[i-1];
String t2 = shifted[i];
CollationTest.doTest(this, (RuleBasedCollator)coll, t1, t2,
shiftedTert[i]);
}
}
public void TestFunkyA() {
String[] testSourceCases = {
"\u0041\u0300\u0301",
"\u0041\u0300\u0316",
"\u0041\u0300",
"\u00C0\u0301",
// this would work with forced normalization
"\u00C0\u0316",
};
String[] testTargetCases = {
"\u0041\u0301\u0300",
"\u0041\u0316\u0300",
"\u00C0",
"\u0041\u0301\u0300",
// this would work with forced normalization
"\u0041\u0316\u0300",
};
int[] results = {
1,
0,
0,
1,
0
};
Collator myCollation;
try {
myCollation = Collator.getInstance(new Locale("en", "US"));
} 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 < 4 ; i++)
{
CollationTest.doTest(this, (RuleBasedCollator)myCollation,
testSourceCases[i], testTargetCases[i],
results[i]);
}
}
public void TestChMove() {
String[] chTest = {
"c",
"C",
"ca", "cb", "cx", "cy", "CZ",
"c\u030C", "C\u030C",
"h",
"H",
"ha", "Ha", "harly", "hb", "HB", "hx", "HX", "hy", "HY",
"ch", "cH", "Ch", "CH",
"cha", "charly", "che", "chh", "chch", "chr",
"i", "I", "iarly",
"r", "R",
"r\u030C", "R\u030C",
"s",
"S",
"s\u030C", "S\u030C",
"z", "Z",
"z\u030C", "Z\u030C"
};
Collator coll = null;
try {
coll = Collator.getInstance(new Locale("cs", ""));
} catch (Exception e) {
warnln("Cannot create Collator");
return;
}
int size = chTest.length;
for(int i = 0; i < size-1; i++) {
for(int j = i+1; j < size; j++) {
String t1 = chTest[i];
String t2 = chTest[j];
CollationTest.doTest(this, (RuleBasedCollator)coll, t1, t2, -1);
}
}
}
public void TestImplicitTailoring() {
String rules[] = { "&[before 1]\u4e00 < b < c &[before 1]\u4e00 < d < e",
"&\u4e00 < a <<< A < b <<< B",
"&[before 1]\u4e00 < \u4e01 < \u4e02",
"&[before 1]\u4e01 < \u4e02 < \u4e03",
};
String cases[][] = {
{ "d", "e", "b", "c", "\u4e00"},
{ "\u4e00", "a", "A", "b", "B", "\u4e01"},
{ "\u4e01", "\u4e02", "\u4e00"},
{ "\u4e02", "\u4e03", "\u4e01"},
};
int i = 0;
for(i = 0; i < rules.length; i++) {
genericRulesStarter(rules[i], cases[i]);
}
}
public void TestFCDProblem() {
String s1 = "\u0430\u0306\u0325";
String s2 = "\u04D1\u0325";
Collator coll = null;
try {
coll = Collator.getInstance();
} catch (Exception e) {
warnln("Can't create collator");
return;
}
coll.setDecomposition(Collator.NO_DECOMPOSITION);
CollationTest.doTest(this, (RuleBasedCollator)coll, s1, s2, 0);
coll.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
CollationTest.doTest(this, (RuleBasedCollator)coll, s1, s2, 0);
}
public void TestEmptyRule() {
String rulez = "";
try {
RuleBasedCollator coll = new RuleBasedCollator(rulez);
logln("rule:" + coll.getRules());
} catch (Exception e) {
warnln(e.getMessage());
}
}
/* superseded by TestBeforePinyin, since Chinese collation rules have changed */
/*
public void TestJ784() {
String[] data = {
"A", "\u0101", "\u00e1", "\u01ce", "\u00e0",
"E", "\u0113", "\u00e9", "\u011b", "\u00e8",
"I", "\u012b", "\u00ed", "\u01d0", "\u00ec",
"O", "\u014d", "\u00f3", "\u01d2", "\u00f2",
"U", "\u016b", "\u00fa", "\u01d4", "\u00f9",
"\u00fc", "\u01d6", "\u01d8", "\u01da", "\u01dc"
};
genericLocaleStarter(new Locale("zh", ""), data);
}
*/
public void TestJ815() {
String data[] = {
"aa",
"Aa",
"ab",
"Ab",
"ad",
"Ad",
"ae",
"Ae",
"\u00e6",
"\u00c6",
"af",
"Af",
"b",
"B"
};
genericLocaleStarter(new Locale("fr", ""), data);
genericRulesStarter("[backwards 2]&A<<\u00e6/e<<<\u00c6/E", data);
}
public void TestJ3087()
{
String rule[] = {"&h<H&CH=\u0427",
"&CH=\u0427&h<H",
"&CH=\u0427"};
RuleBasedCollator rbc = null;
CollationElementIterator iter1;
CollationElementIterator iter2;
for (int i = 0; i < rule.length; i ++) {
try {
rbc = new RuleBasedCollator(rule[i]);
} catch (Exception e) {
warnln(e.getMessage());
return;
}
iter1 = rbc.getCollationElementIterator("CH");
iter2 = rbc.getCollationElementIterator("\u0427");
int ce1 = CollationElementIterator.IGNORABLE;
int ce2 = CollationElementIterator.IGNORABLE;
while (ce1 != CollationElementIterator.NULLORDER
&& ce2 != CollationElementIterator.NULLORDER) {
ce1 = iter1.next();
ce2 = iter2.next();
if (ce1 != ce2) {
errln("Error generating RuleBasedCollator with the rule "
+ rule[i]);
errln("CH != \\u0427");
}
}
}
}
public void DontTestJ831() { // Latvian does not use upper first
String[] data = {
"I",
"i",
"Y",
"y"
};
genericLocaleStarter(new Locale("lv", ""), data);
}
public void TestBefore() {
String data[] = {
"\u0101", "\u00e1", "\u01ce", "\u00e0", "A",
"\u0113", "\u00e9", "\u011b", "\u00e8", "E",
"\u012b", "\u00ed", "\u01d0", "\u00ec", "I",
"\u014d", "\u00f3", "\u01d2", "\u00f2", "O",
"\u016b", "\u00fa", "\u01d4", "\u00f9", "U",
"\u01d6", "\u01d8", "\u01da", "\u01dc", "\u00fc"
};
genericRulesStarter(
"&[before 1]a<\u0101<\u00e1<\u01ce<\u00e0"
+ "&[before 1]e<\u0113<\u00e9<\u011b<\u00e8"
+ "&[before 1]i<\u012b<\u00ed<\u01d0<\u00ec"
+ "&[before 1]o<\u014d<\u00f3<\u01d2<\u00f2"
+ "&[before 1]u<\u016b<\u00fa<\u01d4<\u00f9"
+ "&u<\u01d6<\u01d8<\u01da<\u01dc<\u00fc", data);
}
public void TestRedundantRules() {
String[] rules = {
//"& a <<< b <<< c << d <<< e& [before 1] e <<< x",
"& b <<< c <<< d << e <<< f& [before 3] f <<< x",
"& a < b <<< c << d <<< e& [before 1] e <<< x",
"& a < b < c < d& [before 1] c < m",
"& a < b <<< c << d <<< e& [before 3] e <<< x",
"& a < b <<< c << d <<< e& [before 2] e <<< x",
"& a < b <<< c << d <<< e <<< f < g& [before 1] g < x",
"& a <<< b << c < d& a < m",
"&a<b<<b\u0301 &z<b",
"&z<m<<<q<<<m",
"&z<<<m<q<<<m",
"& a < b < c < d& r < c",
"& a < b < c < d& r < c",
"& a < b < c < d& c < m",
"& a < b < c < d& a < m"
};
String[] expectedRules = {
//"&\u2089<<<x",
"&\u0252<<<x",
"& a <<< x < b <<< c << d <<< e",
"& a < b < m < c < d",
"& a < b <<< c << d <<< x <<< e",
"& a < b <<< c <<< x << d <<< e",
"& a < b <<< c << d <<< e <<< f < x < g",
"& a <<< b << c < m < d",
"&a<b\u0301 &z<b",
"&z<q<<<m",
"&z<q<<<m",
"& a < b < d& r < c",
"& a < b < d& r < c",
"& a < b < c < m < d",
"& a < m < b < c < d"
};
String[][] testdata = {
// {"\u2089", "x"},
{"\u0252", "x"},
{"a", "x", "b", "c", "d", "e"},
{"a", "b", "m", "c", "d"},
{"a", "b", "c", "d", "x", "e"},
{"a", "b", "c", "x", "d", "e"},
{"a", "b", "c", "d", "e", "f", "x", "g"},
{"a", "b", "c", "m", "d"},
{"a", "b\u0301", "z", "b"},
{"z", "q", "m"},
{"z", "q", "m"},
{"a", "b", "d"},
{"r", "c"},
{"a", "b", "c", "m", "d"},
{"a", "m", "b", "c", "d"}
};
String rlz = "";
for(int i = 0; i<rules.length; i++) {
logln("testing rule " + rules[i] + ", expected to be" + expectedRules[i]);
try {
rlz = rules[i];
Collator credundant = new RuleBasedCollator(rlz);
rlz = expectedRules[i];
Collator cresulting = new RuleBasedCollator(rlz);
logln(" credundant Rule:" + ((RuleBasedCollator)credundant).getRules());
logln(" cresulting Rule:" + ((RuleBasedCollator)cresulting).getRules());
} catch (Exception e) {
warnln("Cannot create RuleBasedCollator");
}
//testAgainstUCA(cresulting, credundant, "expected", TRUE, &status);
// logln("testing using data\n");
genericRulesStarter(rules[i], testdata[i]);
}
}
public void TestExpansionSyntax() {
String[] rules = {
"&AE <<< a << b <<< c &d <<< f",
"&AE <<< a <<< b << c << d < e < f <<< g",
"&AE <<< B <<< C / D <<< F"
};
String[] expectedRules = {
"&A <<< a / E << b / E <<< c /E &d <<< f",
"&A <<< a / E <<< b / E << c / E << d / E < e < f <<< g",
"&A <<< B / E <<< C / ED <<< F / E"
};
String[][] testdata = {
{"AE", "a", "b", "c"},
{"AE", "a", "b", "c", "d", "e", "f", "g"},
{"AE", "B", "C"} // / ED <<< F / E"},
};
for(int i = 0; i<rules.length; i++) {
// logln("testing rule " + rules[i] + ", expected to be " + expectedRules[i]);
try {
String rlz = rules[i];
Collator credundant = new RuleBasedCollator(rlz);
rlz = expectedRules[i];
Collator cresulting = new RuleBasedCollator(rlz);
logln(" credundant Rule:" + ((RuleBasedCollator)credundant).getRules());
logln(" cresulting Rule:" + ((RuleBasedCollator)cresulting).getRules());
} catch (Exception e) {
warnln(e.getMessage());
}
// testAgainstUCA still doesn't handle expansions correctly, so this is not run
// as a hard error test, but only in information mode
//testAgainstUCA(cresulting, credundant, "expected", FALSE, &status);
// logln("testing using data");
genericRulesStarter(rules[i], testdata[i]);
}
}
public void TestHangulTailoring() {
String[] koreanData = {
"\uac00", "\u4f3d", "\u4f73", "\u5047", "\u50f9", "\u52a0", "\u53ef", "\u5475",
"\u54e5", "\u5609", "\u5ac1", "\u5bb6", "\u6687", "\u67b6", "\u67b7", "\u67ef",
"\u6b4c", "\u73c2", "\u75c2", "\u7a3c", "\u82db", "\u8304", "\u8857", "\u8888",
"\u8a36", "\u8cc8", "\u8dcf", "\u8efb", "\u8fe6", "\u99d5",
"\u4EEE", "\u50A2", "\u5496", "\u54FF", "\u5777", "\u5B8A", "\u659D", "\u698E",
"\u6A9F", "\u73C8", "\u7B33", "\u801E", "\u8238", "\u846D", "\u8B0C"
};
String rules =
"&\uac00 <<< \u4f3d <<< \u4f73 <<< \u5047 <<< \u50f9 <<< \u52a0 <<< \u53ef <<< \u5475 "
+ "<<< \u54e5 <<< \u5609 <<< \u5ac1 <<< \u5bb6 <<< \u6687 <<< \u67b6 <<< \u67b7 <<< \u67ef "
+ "<<< \u6b4c <<< \u73c2 <<< \u75c2 <<< \u7a3c <<< \u82db <<< \u8304 <<< \u8857 <<< \u8888 "
+ "<<< \u8a36 <<< \u8cc8 <<< \u8dcf <<< \u8efb <<< \u8fe6 <<< \u99d5 "
+ "<<< \u4EEE <<< \u50A2 <<< \u5496 <<< \u54FF <<< \u5777 <<< \u5B8A <<< \u659D <<< \u698E "
+ "<<< \u6A9F <<< \u73C8 <<< \u7B33 <<< \u801E <<< \u8238 <<< \u846D <<< \u8B0C";
String rlz = rules;
Collator coll = null;
try {
coll = new RuleBasedCollator(rlz);
} catch (Exception e) {
warnln("Unable to open collator with rules" + rules);
return;
}
// logln("Using start of korean rules\n");
genericOrderingTest(coll, koreanData);
// logln("Setting jamoSpecial to TRUE and testing once more\n");
// can't set jamo in icu4j
// ((UCATableHeader *)coll->image)->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<rules.length; i++) {
genericRulesStarter(rules[i], data[i]);
}
}
public void TestIdenticalCompare()
{
try {
RuleBasedCollator coll
= new RuleBasedCollator("& \uD800\uDC00 = \uD800\uDC01");
String strA = "AA\u0300\u0316\uD800\uDC01";
String strB = "A\u00c0\u0316\uD800\uDC00";
coll.setStrength(Collator.IDENTICAL);
CollationTest.doTest(this, coll, strA, strB, 1);
} catch (Exception e) {
warnln(e.getMessage());
}
}
public void TestMergeSortKeys()
{
String cases[] = {"abc", "abcd", "abcde"};
String prefix = "foo";
String suffix = "egg";
CollationKey mergedPrefixKeys[] = new CollationKey[cases.length];
CollationKey mergedSuffixKeys[] = new CollationKey[cases.length];
Collator coll = Collator.getInstance(Locale.ENGLISH);
genericLocaleStarter(Locale.ENGLISH, cases);
int strength = Collator.PRIMARY;
while (strength <= Collator.IDENTICAL) {
coll.setStrength(strength);
CollationKey prefixKey = coll.getCollationKey(prefix);
CollationKey suffixKey = coll.getCollationKey(suffix);
for (int i = 0; i < cases.length; i ++) {
CollationKey key = coll.getCollationKey(cases[i]);
mergedPrefixKeys[i] = prefixKey.merge(key);
mergedSuffixKeys[i] = suffixKey.merge(key);
if (mergedPrefixKeys[i].getSourceString() != null
|| mergedSuffixKeys[i].getSourceString() != null) {
errln("Merged source string error: expected null");
}
if (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[] = {new 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), new Boolean(true) };
genericLocaleStarterWithOptions(new Locale("root","",""), tests, att, attVals);
}
}