1/* 2 ******************************************************************************* 3 * Copyright (C) 2002-2015, International Business Machines Corporation and 4 * others. All Rights Reserved. 5 ******************************************************************************* 6 */ 7 8/** 9 * Port From: ICU4C v2.1 : cintltest 10 * Source File: $ICU4CRoot/source/test/cintltest/cmsccoll.c 11 */ 12 13package com.ibm.icu.dev.test.collator; 14 15import java.util.Arrays; 16import java.util.Locale; 17import java.util.Set; 18import java.util.TreeSet; 19 20import com.ibm.icu.dev.test.TestFmwk; 21import com.ibm.icu.impl.ICUResourceBundle; 22import com.ibm.icu.impl.Utility; 23import com.ibm.icu.lang.UScript; 24import com.ibm.icu.text.CollationElementIterator; 25import com.ibm.icu.text.CollationKey; 26import com.ibm.icu.text.CollationKey.BoundMode; 27import com.ibm.icu.text.Collator; 28import com.ibm.icu.text.Collator.ReorderCodes; 29import com.ibm.icu.text.Normalizer; 30import com.ibm.icu.text.RawCollationKey; 31import com.ibm.icu.text.RuleBasedCollator; 32import com.ibm.icu.text.UTF16; 33import com.ibm.icu.text.UnicodeSet; 34import com.ibm.icu.text.UnicodeSetIterator; 35import com.ibm.icu.util.ULocale; 36import com.ibm.icu.util.UResourceBundle; 37 38public class CollationMiscTest extends TestFmwk { 39 40 public static void main(String[] args) throws Exception { 41 new CollationMiscTest().run(args); 42 // new CollationMiscTest().TestLocaleRuleBasedCollators(); 43 } 44 45 //private static final int NORM_BUFFER_TEST_LEN_ = 32; 46 private static final class Tester 47 { 48 int u; 49 String NFC; 50 String NFD; 51 } 52 53 private static final boolean hasCollationElements(Locale locale) 54 { 55 ICUResourceBundle rb = (ICUResourceBundle)UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_COLLATION_BASE_NAME,locale); 56 if (rb != null) { 57 try { 58 String collkey = rb.getStringWithFallback("collations/default"); 59 ICUResourceBundle elements = rb.getWithFallback("collations/" + collkey); 60 if (elements != null) { 61 return true; 62 } 63 } catch (Exception e) { 64 } 65 } 66 return false; 67 } 68 69 public void TestComposeDecompose() 70 { 71 Tester t[] = new Tester[0x30000]; 72 t[0] = new Tester(); 73 logln("Testing UCA extensively\n"); 74 RuleBasedCollator coll; 75 try { 76 coll = (RuleBasedCollator)Collator.getInstance(Locale.ENGLISH); 77 } 78 catch (Exception e) { 79 warnln("Error opening collator\n"); 80 return; 81 } 82 83 int noCases = 0; 84 for (int u = 0; u < 0x30000; u ++) { 85 String comp = UTF16.valueOf(u); 86 int len = comp.length(); 87 t[noCases].NFC = Normalizer.normalize(u, Normalizer.NFC); 88 t[noCases].NFD = Normalizer.normalize(u, Normalizer.NFD); 89 90 if (t[noCases].NFC.length() != t[noCases].NFD.length() 91 || (t[noCases].NFC.compareTo(t[noCases].NFD) != 0) 92 || (len != t[noCases].NFD.length()) 93 || (comp.compareTo(t[noCases].NFD) != 0)) { 94 t[noCases].u = u; 95 if (len != t[noCases].NFD.length() 96 || (comp.compareTo(t[noCases].NFD) != 0)) { 97 t[noCases].NFC = comp; 98 } 99 noCases ++; 100 t[noCases] = new Tester(); 101 } 102 } 103 104 for (int u = 0; u < noCases; u ++) { 105 if (!coll.equals(t[u].NFC, t[u].NFD)) { 106 errln("Failure: codePoint \\u" + Integer.toHexString(t[u].u) 107 + " fails TestComposeDecompose in the UCA"); 108 CollationTest.doTest(this, coll, t[u].NFC, t[u].NFD, 0); 109 } 110 } 111 112 logln("Testing locales, number of cases = " + noCases); 113 Locale loc[] = Collator.getAvailableLocales(); 114 for (int i = 0; i < loc.length; i ++) { 115 if (hasCollationElements(loc[i])) { 116 logln("Testing locale " + loc[i].getDisplayName()); 117 coll = (RuleBasedCollator)Collator.getInstance(loc[i]); 118 coll.setStrength(Collator.IDENTICAL); 119 120 for (int u = 0; u < noCases; u ++) { 121 if (!coll.equals(t[u].NFC, t[u].NFD)) { 122 errln("Failure: codePoint \\u" 123 + Integer.toHexString(t[u].u) 124 + " fails TestComposeDecompose for locale " 125 + loc[i].getDisplayName()); 126 // this tests for the iterators too 127 CollationTest.doTest(this, coll, t[u].NFC, t[u].NFD, 128 0); 129 } 130 } 131 } 132 } 133 } 134 135 public void TestRuleOptions() { 136 // values here are hardcoded and are correct for the current UCA when 137 // the UCA changes, one might be forced to change these values. 138 139 /* 140 * These strings contain the last character before [variable top] 141 * and the first and second characters (by primary weights) after it. 142 * See FractionalUCA.txt. For example: 143 [last variable [0C FE, 05, 05]] # U+10A7F OLD SOUTH ARABIAN NUMERIC INDICATOR 144 [variable top = 0C FE] 145 [first regular [0D 0A, 05, 05]] # U+0060 GRAVE ACCENT 146 and 147 00B4; [0D 0C, 05, 05] 148 * 149 * Note: Starting with UCA 6.0, the [variable top] collation element 150 * is not the weight of any character or string, 151 * which means that LAST_VARIABLE_CHAR_STRING sorts before [last variable]. 152 */ 153 String LAST_VARIABLE_CHAR_STRING = "\\U00010A7F"; 154 String FIRST_REGULAR_CHAR_STRING = "\\u0060"; 155 String SECOND_REGULAR_CHAR_STRING = "\\u00B4"; 156 157 /* 158 * This string has to match the character that has the [last regular] weight 159 * which changes with each UCA version. 160 * See the bottom of FractionalUCA.txt which says something like 161 [last regular [7A FE, 05, 05]] # U+1342E EGYPTIAN HIEROGLYPH AA032 162 * 163 * Note: Starting with UCA 6.0, the [last regular] collation element 164 * is not the weight of any character or string, 165 * which means that LAST_REGULAR_CHAR_STRING sorts before [last regular]. 166 */ 167 String LAST_REGULAR_CHAR_STRING = "\\U0001342E"; 168 169 String[] rules = { 170 // cannot test this anymore, as [last primary ignorable] doesn't 171 // have a code point associated to it anymore 172 // "&[before 3][last primary ignorable]<<<k", 173 // - all befores here amount to zero 174 /* "you cannot go before ...": The parser now sets an error for such nonsensical rules. 175 "&[before 3][first tertiary ignorable]<<<a", 176 "&[before 3][last tertiary ignorable]<<<a", */ 177 /* 178 * However, there is a real secondary ignorable (artificial addition in FractionalUCA.txt), 179 * and it *is* possible to "go before" that. 180 */ 181 "&[before 3][first secondary ignorable]<<<a", 182 "&[before 3][last secondary ignorable]<<<a", 183 // 'normal' befores 184 /* 185 * Note: With a "SPACE first primary" boundary CE in FractionalUCA.txt, 186 * it is not possible to tailor &[first primary ignorable]<a or &[last primary ignorable]<a 187 * because there is no tailoring space before that boundary. 188 * Made the tests work by tailoring to a space instead. 189 */ 190 "&[before 3][first primary ignorable]<<<c<<<b &' '<a", /* was &[first primary ignorable]<a */ 191 // we don't have a code point that corresponds to the last primary 192 // ignorable 193 "&[before 3][last primary ignorable]<<<c<<<b &' '<a", /* was &[last primary ignorable]<a */ 194 "&[before 3][first variable]<<<c<<<b &[first variable]<a", 195 "&[last variable]<a &[before 3][last variable]<<<c<<<b ", 196 "&[first regular]<a &[before 1][first regular]<b", 197 "&[before 1][last regular]<b &[last regular]<a", 198 "&[before 1][first implicit]<b &[first implicit]<a", 199 /* The current builder does not support tailoring to unassigned-implicit CEs (seems unnecessary, adds complexity). 200 "&[before 1][last implicit]<b &[last implicit]<a", */ 201 "&[last variable]<z" + 202 "&' '<x" + /* was &[last primary ignorable]<x, see above */ 203 "&[last secondary ignorable]<<y&[last tertiary ignorable]<<<w&[top]<u", 204 }; 205 String[][] data = { 206 // {"k", "\u20e3"}, 207 /* "you cannot go before ...": The parser now sets an error for such nonsensical rules. 208 {"\\u0000", "a"}, // you cannot go before first tertiary ignorable 209 {"\\u0000", "a"}, // you cannot go before last tertiary ignorable */ 210 /* 211 * However, there is a real secondary ignorable (artificial addition in FractionalUCA.txt), 212 * and it *is* possible to "go before" that. 213 */ 214 {"\\u0000", "a"}, 215 {"\\u0000", "a"}, 216 /* 217 * Note: With a "SPACE first primary" boundary CE in FractionalUCA.txt, 218 * it is not possible to tailor &[first primary ignorable]<a or &[last primary ignorable]<a 219 * because there is no tailoring space before that boundary. 220 * Made the tests work by tailoring to a space instead. 221 */ 222 {"c", "b", "\\u0332", "a"}, 223 {"\\u0332", "\\u20e3", "c", "b", "a"}, 224 {"c", "b", "\\u0009", "a", "\\u000a"}, 225 {LAST_VARIABLE_CHAR_STRING, "c", "b", /* [last variable] */ "a", FIRST_REGULAR_CHAR_STRING}, 226 {"b", FIRST_REGULAR_CHAR_STRING, "a", SECOND_REGULAR_CHAR_STRING}, 227 // The character in the second ordering test string 228 // has to match the character that has the [last regular] weight 229 // which changes with each UCA version. 230 // See the bottom of FractionalUCA.txt which says something like 231 // [last regular [CE 27, 05, 05]] # U+1342E EGYPTIAN HIEROGLYPH AA032 232 {LAST_REGULAR_CHAR_STRING, "b", /* [last regular] */ "a", "\\u4e00"}, 233 {"b", "\\u4e00", "a", "\\u4e01"}, 234 /* The current builder does not support tailoring to unassigned-implicit CEs (seems unnecessary, adds complexity). 235 {"b", "\\U0010FFFD", "a"}, */ 236 {"\ufffb", "w", "y", "\u20e3", "x", LAST_VARIABLE_CHAR_STRING, "z", "u"}, 237 }; 238 239 for (int i = 0; i< rules.length; i++) { 240 logln(String.format("rules[%d] = \"%s\"", i, rules[i])); 241 genericRulesStarter(rules[i], data[i]); 242 } 243 } 244 245 void genericRulesStarter(String rules, String[] s) { 246 genericRulesStarterWithResult(rules, s, -1); 247 } 248 249 void genericRulesStarterWithResult(String rules, String[] s, int result) { 250 251 RuleBasedCollator coll = null; 252 try { 253 coll = new RuleBasedCollator(rules); 254 // logln("Rules starter for " + rules); 255 genericOrderingTestWithResult(coll, s, result); 256 } catch (Exception e) { 257 warnln("Unable to open collator with rules " + rules + ": " + e); 258 } 259 } 260 261 void genericRulesStarterWithOptionsAndResult(String rules, String[] s, String[] atts, Object[] attVals, int result) { 262 RuleBasedCollator coll = null; 263 try { 264 coll = new RuleBasedCollator(rules); 265 genericOptionsSetter(coll, atts, attVals); 266 genericOrderingTestWithResult(coll, s, result); 267 } catch (Exception e) { 268 warnln("Unable to open collator with rules " + rules); 269 } 270 } 271 void genericOrderingTestWithResult(Collator coll, String[] s, int result) { 272 String t1 = ""; 273 String t2 = ""; 274 275 for(int i = 0; i < s.length - 1; i++) { 276 for(int j = i+1; j < s.length; j++) { 277 t1 = Utility.unescape(s[i]); 278 t2 = Utility.unescape(s[j]); 279 // System.out.println(i + " " + j); 280 CollationTest.doTest(this, (RuleBasedCollator)coll, t1, t2, 281 result); 282 } 283 } 284 } 285 286 void reportCResult(String source, String target, CollationKey sourceKey, CollationKey targetKey, 287 int compareResult, int keyResult, int incResult, int expectedResult ) { 288 if (expectedResult < -1 || expectedResult > 1) { 289 errln("***** invalid call to reportCResult ****"); 290 return; 291 } 292 boolean ok1 = (compareResult == expectedResult); 293 boolean ok2 = (keyResult == expectedResult); 294 boolean ok3 = (incResult == expectedResult); 295 if (ok1 && ok2 && ok3 /* synwee to undo && !isVerbose()*/) { 296 return; 297 } else { 298 String msg1 = ok1? "Ok: compare(\"" : "FAIL: compare(\""; 299 String msg2 = "\", \""; 300 String msg3 = "\") returned "; 301 String msg4 = "; expected "; 302 String sExpect = new String(""); 303 String sResult = new String(""); 304 sResult = CollationTest.appendCompareResult(compareResult, sResult); 305 sExpect = CollationTest.appendCompareResult(expectedResult, sExpect); 306 if (ok1) { 307 // logln(msg1 + source + msg2 + target + msg3 + sResult); 308 } else { 309 errln(msg1 + source + msg2 + target + msg3 + sResult + msg4 + sExpect); 310 } 311 msg1 = ok2 ? "Ok: key(\"" : "FAIL: key(\""; 312 msg2 = "\").compareTo(key(\""; 313 msg3 = "\")) returned "; 314 sResult = CollationTest.appendCompareResult(keyResult, sResult); 315 if (ok2) { 316 // logln(msg1 + source + msg2 + target + msg3 + sResult); 317 } else { 318 errln(msg1 + source + msg2 + target + msg3 + sResult + msg4 + sExpect); 319 msg1 = " "; 320 msg2 = " vs. "; 321 errln(msg1 + CollationTest.prettify(sourceKey) + msg2 + CollationTest.prettify(targetKey)); 322 } 323 msg1 = ok3 ? "Ok: incCompare(\"" : "FAIL: incCompare(\""; 324 msg2 = "\", \""; 325 msg3 = "\") returned "; 326 sResult = CollationTest.appendCompareResult(incResult, sResult); 327 if (ok3) { 328 // logln(msg1 + source + msg2 + target + msg3 + sResult); 329 } else { 330 errln(msg1 + source + msg2 + target + msg3 + sResult + msg4 + sExpect); 331 } 332 } 333 } 334 335 public void TestBeforePrefixFailure() { 336 String[] rules = { 337 "&g <<< a&[before 3]\uff41 <<< x", 338 "&\u30A7=\u30A7=\u3047=\uff6a&\u30A8=\u30A8=\u3048=\uff74&[before 3]\u30a7<<<\u30a9", 339 "&[before 3]\u30a7<<<\u30a9&\u30A7=\u30A7=\u3047=\uff6a&\u30A8=\u30A8=\u3048=\uff74", 340 }; 341 String[][] data = { 342 {"x", "\uff41"}, 343 {"\u30a9", "\u30a7"}, 344 {"\u30a9", "\u30a7"}, 345 }; 346 347 for(int i = 0; i< rules.length; i++) { 348 genericRulesStarter(rules[i], data[i]); 349 } 350 } 351 352 public void TestContractionClosure() { 353 // Note: This was also ported to the data-driven test, see collationtest.txt. 354 String[] rules = { 355 "&b=\u00e4\u00e4", 356 "&b=\u00C5", 357 }; 358 String[][] data = { 359 { "b", "\u00e4\u00e4", "a\u0308a\u0308", "\u00e4a\u0308", "a\u0308\u00e4" }, 360 { "b", "\u00C5", "A\u030A", "\u212B" }, 361 }; 362 363 for(int i = 0; i< rules.length; i++) { 364 genericRulesStarterWithResult(rules[i], data[i], 0); 365 } 366 } 367 368 public void TestPrefixCompose() { 369 String rule1 = "&\u30a7<<<\u30ab|\u30fc=\u30ac|\u30fc"; 370 371 String string = rule1; 372 try { 373 RuleBasedCollator coll = new RuleBasedCollator(string); 374 logln("rule:" + coll.getRules()); 375 } catch (Exception e) { 376 warnln("Error open RuleBasedCollator rule = " + string); 377 } 378 } 379 380 public void TestStrCollIdenticalPrefix() { 381 String rule = "&\ud9b0\udc70=\ud9b0\udc71"; 382 String test[] = { 383 "ab\ud9b0\udc70", 384 "ab\ud9b0\udc71" 385 }; 386 genericRulesStarterWithResult(rule, test, 0); 387 } 388 389 public void TestPrefix() { 390 String[] rules = { 391 "&z <<< z|a", 392 "&z <<< z| a", 393 "[strength I]&a=\ud900\udc25&z<<<\ud900\udc25|a", 394 }; 395 String[][] data = { 396 {"zz", "za"}, 397 {"zz", "za"}, 398 {"aa", "az", "\ud900\udc25z", "\ud900\udc25a", "zz"}, 399 }; 400 401 for(int i = 0; i<rules.length; i++) { 402 genericRulesStarter(rules[i], data[i]); 403 } 404 } 405 406 public void TestNewJapanese() { 407 408 String test1[] = { 409 "\u30b7\u30e3\u30fc\u30ec", 410 "\u30b7\u30e3\u30a4", 411 "\u30b7\u30e4\u30a3", 412 "\u30b7\u30e3\u30ec", 413 "\u3061\u3087\u3053", 414 "\u3061\u3088\u3053", 415 "\u30c1\u30e7\u30b3\u30ec\u30fc\u30c8", 416 "\u3066\u30fc\u305f", 417 "\u30c6\u30fc\u30bf", 418 "\u30c6\u30a7\u30bf", 419 "\u3066\u3048\u305f", 420 "\u3067\u30fc\u305f", 421 "\u30c7\u30fc\u30bf", 422 "\u30c7\u30a7\u30bf", 423 "\u3067\u3048\u305f", 424 "\u3066\u30fc\u305f\u30fc", 425 "\u30c6\u30fc\u30bf\u30a1", 426 "\u30c6\u30a7\u30bf\u30fc", 427 "\u3066\u3047\u305f\u3041", 428 "\u3066\u3048\u305f\u30fc", 429 "\u3067\u30fc\u305f\u30fc", 430 "\u30c7\u30fc\u30bf\u30a1", 431 "\u3067\u30a7\u305f\u30a1", 432 "\u30c7\u3047\u30bf\u3041", 433 "\u30c7\u30a8\u30bf\u30a2", 434 "\u3072\u3086", 435 "\u3073\u3085\u3042", 436 "\u3074\u3085\u3042", 437 "\u3073\u3085\u3042\u30fc", 438 "\u30d3\u30e5\u30a2\u30fc", 439 "\u3074\u3085\u3042\u30fc", 440 "\u30d4\u30e5\u30a2\u30fc", 441 "\u30d2\u30e5\u30a6", 442 "\u30d2\u30e6\u30a6", 443 "\u30d4\u30e5\u30a6\u30a2", 444 "\u3073\u3085\u30fc\u3042\u30fc", 445 "\u30d3\u30e5\u30fc\u30a2\u30fc", 446 "\u30d3\u30e5\u30a6\u30a2\u30fc", 447 "\u3072\u3085\u3093", 448 "\u3074\u3085\u3093", 449 "\u3075\u30fc\u308a", 450 "\u30d5\u30fc\u30ea", 451 "\u3075\u3045\u308a", 452 "\u3075\u30a5\u308a", 453 "\u3075\u30a5\u30ea", 454 "\u30d5\u30a6\u30ea", 455 "\u3076\u30fc\u308a", 456 "\u30d6\u30fc\u30ea", 457 "\u3076\u3045\u308a", 458 "\u30d6\u30a5\u308a", 459 "\u3077\u3046\u308a", 460 "\u30d7\u30a6\u30ea", 461 "\u3075\u30fc\u308a\u30fc", 462 "\u30d5\u30a5\u30ea\u30fc", 463 "\u3075\u30a5\u308a\u30a3", 464 "\u30d5\u3045\u308a\u3043", 465 "\u30d5\u30a6\u30ea\u30fc", 466 "\u3075\u3046\u308a\u3043", 467 "\u30d6\u30a6\u30ea\u30a4", 468 "\u3077\u30fc\u308a\u30fc", 469 "\u3077\u30a5\u308a\u30a4", 470 "\u3077\u3046\u308a\u30fc", 471 "\u30d7\u30a6\u30ea\u30a4", 472 "\u30d5\u30fd", 473 "\u3075\u309e", 474 "\u3076\u309d", 475 "\u3076\u3075", 476 "\u3076\u30d5", 477 "\u30d6\u3075", 478 "\u30d6\u30d5", 479 "\u3076\u309e", 480 "\u3076\u3077", 481 "\u30d6\u3077", 482 "\u3077\u309d", 483 "\u30d7\u30fd", 484 "\u3077\u3075", 485 }; 486 487 String test2[] = { 488 "\u306f\u309d", // H\u309d 489 "\u30cf\u30fd", // K\u30fd 490 "\u306f\u306f", // HH 491 "\u306f\u30cf", // HK 492 "\u30cf\u30cf", // KK 493 "\u306f\u309e", // H\u309e 494 "\u30cf\u30fe", // K\u30fe 495 "\u306f\u3070", // HH\u309b 496 "\u30cf\u30d0", // KK\u309b 497 "\u306f\u3071", // HH\u309c 498 "\u30cf\u3071", // KH\u309c 499 "\u30cf\u30d1", // KK\u309c 500 "\u3070\u309d", // H\u309b\u309d 501 "\u30d0\u30fd", // K\u309b\u30fd 502 "\u3070\u306f", // H\u309bH 503 "\u30d0\u30cf", // K\u309bK 504 "\u3070\u309e", // H\u309b\u309e 505 "\u30d0\u30fe", // K\u309b\u30fe 506 "\u3070\u3070", // H\u309bH\u309b 507 "\u30d0\u3070", // K\u309bH\u309b 508 "\u30d0\u30d0", // K\u309bK\u309b 509 "\u3070\u3071", // H\u309bH\u309c 510 "\u30d0\u30d1", // K\u309bK\u309c 511 "\u3071\u309d", // H\u309c\u309d 512 "\u30d1\u30fd", // K\u309c\u30fd 513 "\u3071\u306f", // H\u309cH 514 "\u30d1\u30cf", // K\u309cK 515 "\u3071\u3070", // H\u309cH\u309b 516 "\u3071\u30d0", // H\u309cK\u309b 517 "\u30d1\u30d0", // K\u309cK\u309b 518 "\u3071\u3071", // H\u309cH\u309c 519 "\u30d1\u30d1", // K\u309cK\u309c 520 }; 521 522 String[] att = { "strength", }; 523 Object[] val = { new Integer(Collator.QUATERNARY), }; 524 525 String[] attShifted = { "strength", "AlternateHandling"}; 526 Object valShifted[] = { new Integer(Collator.QUATERNARY), 527 Boolean.TRUE }; 528 529 genericLocaleStarterWithOptions(Locale.JAPANESE, test1, att, val); 530 genericLocaleStarterWithOptions(Locale.JAPANESE, test2, att, val); 531 532 genericLocaleStarterWithOptions(Locale.JAPANESE, test1, attShifted, 533 valShifted); 534 genericLocaleStarterWithOptions(Locale.JAPANESE, test2, attShifted, 535 valShifted); 536 } 537 538 void genericLocaleStarter(Locale locale, String s[]) { 539 RuleBasedCollator coll = null; 540 try { 541 coll = (RuleBasedCollator)Collator.getInstance(locale); 542 543 } catch (Exception e) { 544 warnln("Unable to open collator for locale " + locale); 545 return; 546 } 547 // logln("Locale starter for " + locale); 548 genericOrderingTest(coll, s); 549 } 550 551 void genericLocaleStarterWithOptions(Locale locale, String[] s, String[] attrs, Object[] values) { 552 genericLocaleStarterWithOptionsAndResult(locale, s, attrs, values, -1); 553 } 554 555 private void genericOptionsSetter(RuleBasedCollator coll, String[] attrs, Object[] values) { 556 for(int i = 0; i < attrs.length; i++) { 557 if (attrs[i].equals("strength")) { 558 coll.setStrength(((Integer)values[i]).intValue()); 559 } 560 else if (attrs[i].equals("decomp")) { 561 coll.setDecomposition(((Integer)values[i]).intValue()); 562 } 563 else if (attrs[i].equals("AlternateHandling")) { 564 coll.setAlternateHandlingShifted(((Boolean)values[i] 565 ).booleanValue()); 566 } 567 else if (attrs[i].equals("NumericCollation")) { 568 coll.setNumericCollation(((Boolean)values[i]).booleanValue()); 569 } 570 else if (attrs[i].equals("UpperFirst")) { 571 coll.setUpperCaseFirst(((Boolean)values[i]).booleanValue()); 572 } 573 else if (attrs[i].equals("LowerFirst")) { 574 coll.setLowerCaseFirst(((Boolean)values[i]).booleanValue()); 575 } 576 else if (attrs[i].equals("CaseLevel")) { 577 coll.setCaseLevel(((Boolean)values[i]).booleanValue()); 578 } 579 } 580 } 581 582 void genericLocaleStarterWithOptionsAndResult(Locale locale, String[] s, String[] attrs, Object[] values, int result) { 583 RuleBasedCollator coll = null; 584 try { 585 coll = (RuleBasedCollator)Collator.getInstance(locale); 586 } catch (Exception e) { 587 warnln("Unable to open collator for locale " + locale); 588 return; 589 } 590 // logln("Locale starter for " +locale); 591 592 // logln("Setting attributes"); 593 genericOptionsSetter(coll, attrs, values); 594 595 genericOrderingTestWithResult(coll, s, result); 596 } 597 598 void genericOrderingTest(Collator coll, String[] s) { 599 genericOrderingTestWithResult(coll, s, -1); 600 } 601 602 public void TestNonChars() { 603 String test[] = { 604 "\u0000", /* ignorable */ 605 "\uFFFE", /* special merge-sort character with minimum non-ignorable weights */ 606 "\uFDD0", "\uFDEF", 607 "\\U0001FFFE", "\\U0001FFFF", /* UCA 6.0: noncharacters are treated like unassigned, */ 608 "\\U0002FFFE", "\\U0002FFFF", /* not like ignorable. */ 609 "\\U0003FFFE", "\\U0003FFFF", 610 "\\U0004FFFE", "\\U0004FFFF", 611 "\\U0005FFFE", "\\U0005FFFF", 612 "\\U0006FFFE", "\\U0006FFFF", 613 "\\U0007FFFE", "\\U0007FFFF", 614 "\\U0008FFFE", "\\U0008FFFF", 615 "\\U0009FFFE", "\\U0009FFFF", 616 "\\U000AFFFE", "\\U000AFFFF", 617 "\\U000BFFFE", "\\U000BFFFF", 618 "\\U000CFFFE", "\\U000CFFFF", 619 "\\U000DFFFE", "\\U000DFFFF", 620 "\\U000EFFFE", "\\U000EFFFF", 621 "\\U000FFFFE", "\\U000FFFFF", 622 "\\U0010FFFE", "\\U0010FFFF", 623 "\uFFFF" /* special character with maximum primary weight */ 624 }; 625 Collator coll = null; 626 try { 627 coll = Collator.getInstance(new Locale("en", "US")); 628 } catch (Exception e) { 629 warnln("Unable to open collator"); 630 return; 631 } 632 // logln("Test non characters"); 633 634 genericOrderingTestWithResult(coll, test, -1); 635 } 636 637 public void TestExtremeCompression() { 638 String[] test = new String[4]; 639 640 for(int i = 0; i<4; i++) { 641 StringBuffer temp = new StringBuffer(); 642 for (int j = 0; j < 2047; j++) { 643 temp.append('a'); 644 } 645 temp.append((char)('a' + i)); 646 test[i] = temp.toString(); 647 } 648 649 genericLocaleStarter(new Locale("en", "US"), test); 650 } 651 652 /** 653 * Tests surrogate support. 654 */ 655 public void TestSurrogates() { 656 String test[] = {"z","\ud900\udc25", "\ud805\udc50", "\ud800\udc00y", 657 "\ud800\udc00r", "\ud800\udc00f", "\ud800\udc00", 658 "\ud800\udc00c", "\ud800\udc00b", "\ud800\udc00fa", 659 "\ud800\udc00fb", "\ud800\udc00a", "c", "b"}; 660 661 String rule = "&z < \ud900\udc25 < \ud805\udc50 < \ud800\udc00y " 662 + "< \ud800\udc00r < \ud800\udc00f << \ud800\udc00 " 663 + "< \ud800\udc00fa << \ud800\udc00fb < \ud800\udc00a " 664 + "< c < b"; 665 genericRulesStarter(rule, test); 666 } 667 668 public void TestBocsuCoverage() { 669 String test = "\u0041\u0441\u4441\\U00044441\u4441\u0441\u0041"; 670 Collator coll = Collator.getInstance(); 671 coll.setStrength(Collator.IDENTICAL); 672 CollationKey key = coll.getCollationKey(test); 673 logln("source:" + key.getSourceString()); 674 } 675 676 public void TestCyrillicTailoring() { 677 String test[] = { 678 "\u0410b", 679 "\u0410\u0306a", 680 "\u04d0A" 681 }; 682 683 // Most of the following are commented out because UCA 8.0 684 // drops most of the Cyrillic contractions from the default order. 685 // See CLDR ticket #7246 "root collation: remove Cyrillic contractions". 686 687 // genericLocaleStarter(new Locale("en", ""), test); 688 // genericRulesStarter("&\u0410 = \u0410", test); 689 // genericRulesStarter("&Z < \u0410", test); 690 genericRulesStarter("&\u0410 = \u0410 < \u04d0", test); 691 genericRulesStarter("&Z < \u0410 < \u04d0", test); 692 // genericRulesStarter("&\u0410 = \u0410 < \u0410\u0301", test); 693 // genericRulesStarter("&Z < \u0410 < \u0410\u0301", test); 694 } 695 696 public void TestSuppressContractions() { 697 String testNoCont2[] = { 698 "\u0410\u0302a", 699 "\u0410\u0306b", 700 "\u0410c" 701 }; 702 String testNoCont[] = { 703 "a\u0410", 704 "A\u0410\u0306", 705 "\uFF21\u0410\u0302" 706 }; 707 708 genericRulesStarter("[suppressContractions [\u0400-\u047f]]", testNoCont); 709 genericRulesStarter("[suppressContractions [\u0400-\u047f]]", testNoCont2); 710 } 711 712 public void TestCase() { 713 String gRules = "\u0026\u0030\u003C\u0031\u002C\u2460\u003C\u0061\u002C\u0041"; 714 String[] testCase = { 715 "1a", "1A", "\u2460a", "\u2460A" 716 }; 717 int[][] caseTestResults = { 718 { -1, -1, -1, 0, -1, -1, 0, 0, -1 }, 719 { 1, -1, -1, 0, -1, -1, 0, 0, 1 }, 720 { -1, -1, -1, 0, 1, -1, 0, 0, -1 }, 721 { 1, -1, 1, 0, -1, -1, 0, 0, 1 } 722 723 }; 724 boolean[][] caseTestAttributes = { 725 { false, false}, 726 { true, false}, 727 { false, true}, 728 { true, true} 729 }; 730 731 int i,j,k; 732 Collator myCollation; 733 try { 734 myCollation = Collator.getInstance(new Locale("en", "US")); 735 } catch (Exception e) { 736 warnln("ERROR: in creation of rule based collator "); 737 return; 738 } 739 // logln("Testing different case settings"); 740 myCollation.setStrength(Collator.TERTIARY); 741 742 for(k = 0; k <4; k++) { 743 if (caseTestAttributes[k][0] == true) { 744 // upper case first 745 ((RuleBasedCollator)myCollation).setUpperCaseFirst(true); 746 } 747 else { 748 // upper case first 749 ((RuleBasedCollator)myCollation).setLowerCaseFirst(true); 750 } 751 ((RuleBasedCollator)myCollation).setCaseLevel( 752 caseTestAttributes[k][1]); 753 754 // logln("Case first = " + caseTestAttributes[k][0] + ", Case level = " + caseTestAttributes[k][1]); 755 for (i = 0; i < 3 ; i++) { 756 for(j = i+1; j<4; j++) { 757 CollationTest.doTest(this, 758 (RuleBasedCollator)myCollation, 759 testCase[i], testCase[j], 760 caseTestResults[k][3*i+j-1]); 761 } 762 } 763 } 764 try { 765 myCollation = new RuleBasedCollator(gRules); 766 } catch (Exception e) { 767 warnln("ERROR: in creation of rule based collator"); 768 return; 769 } 770 // logln("Testing different case settings with custom rules"); 771 myCollation.setStrength(Collator.TERTIARY); 772 773 for(k = 0; k<4; k++) { 774 if (caseTestAttributes[k][0] == true) { 775 ((RuleBasedCollator)myCollation).setUpperCaseFirst(true); 776 } 777 else { 778 ((RuleBasedCollator)myCollation).setUpperCaseFirst(false); 779 } 780 ((RuleBasedCollator)myCollation).setCaseLevel( 781 caseTestAttributes[k][1]); 782 for (i = 0; i < 3 ; i++) { 783 for(j = i+1; j<4; j++) { 784 CollationTest.doTest(this, 785 (RuleBasedCollator)myCollation, 786 testCase[i], testCase[j], 787 caseTestResults[k][3*i+j-1]); 788 } 789 } 790 } 791 792 { 793 String[] lowerFirst = { 794 "h", 795 "H", 796 "ch", 797 "Ch", 798 "CH", 799 "cha", 800 "chA", 801 "Cha", 802 "ChA", 803 "CHa", 804 "CHA", 805 "i", 806 "I" 807 }; 808 809 String[] upperFirst = { 810 "H", 811 "h", 812 "CH", 813 "Ch", 814 "ch", 815 "CHA", 816 "CHa", 817 "ChA", 818 "Cha", 819 "chA", 820 "cha", 821 "I", 822 "i" 823 }; 824 // logln("mixed case test"); 825 // logln("lower first, case level off"); 826 genericRulesStarter("[caseFirst lower]&H<ch<<<Ch<<<CH", lowerFirst); 827 // logln("upper first, case level off"); 828 genericRulesStarter("[caseFirst upper]&H<ch<<<Ch<<<CH", upperFirst); 829 // logln("lower first, case level on"); 830 genericRulesStarter("[caseFirst lower][caseLevel on]&H<ch<<<Ch<<<CH", lowerFirst); 831 // logln("upper first, case level on"); 832 genericRulesStarter("[caseFirst upper][caseLevel on]&H<ch<<<Ch<<<CH", upperFirst); 833 } 834 } 835 836 public void TestIncompleteCnt() { 837 String[] cnt1 = { 838 "AA", 839 "AC", 840 "AZ", 841 "AQ", 842 "AB", 843 "ABZ", 844 "ABQ", 845 "Z", 846 "ABC", 847 "Q", 848 "B" 849 }; 850 851 String[] cnt2 = { 852 "DA", 853 "DAD", 854 "DAZ", 855 "MAR", 856 "Z", 857 "DAVIS", 858 "MARK", 859 "DAV", 860 "DAVI" 861 }; 862 RuleBasedCollator coll = null; 863 String temp = " & Z < ABC < Q < B"; 864 try { 865 coll = new RuleBasedCollator(temp); 866 } catch (Exception e) { 867 warnln("fail to create RuleBasedCollator"); 868 return; 869 } 870 871 int size = cnt1.length; 872 for(int i = 0; i < size-1; i++) { 873 for(int j = i+1; j < size; j++) { 874 String t1 = cnt1[i]; 875 String t2 = cnt1[j]; 876 CollationTest.doTest(this, coll, t1, t2, -1); 877 } 878 } 879 880 temp = " & Z < DAVIS < MARK <DAV"; 881 try { 882 coll = new RuleBasedCollator(temp); 883 } catch (Exception e) { 884 warnln("fail to create RuleBasedCollator"); 885 return; 886 } 887 888 size = cnt2.length; 889 for(int i = 0; i < size-1; i++) { 890 for(int j = i+1; j < size; j++) { 891 String t1 = cnt2[i]; 892 String t2 = cnt2[j]; 893 CollationTest.doTest(this, coll, t1, t2, -1); 894 } 895 } 896 } 897 898 public void TestBlackBird() { 899 String[] shifted = { 900 "black bird", 901 "black-bird", 902 "blackbird", 903 "black Bird", 904 "black-Bird", 905 "blackBird", 906 "black birds", 907 "black-birds", 908 "blackbirds" 909 }; 910 int[] shiftedTert = { 911 0, 912 0, 913 0, 914 -1, 915 0, 916 0, 917 -1, 918 0, 919 0 920 }; 921 String[] nonignorable = { 922 "black bird", 923 "black Bird", 924 "black birds", 925 "black-bird", 926 "black-Bird", 927 "black-birds", 928 "blackbird", 929 "blackBird", 930 "blackbirds" 931 }; 932 int i = 0, j = 0; 933 int size = 0; 934 Collator coll = Collator.getInstance(new Locale("en", "US")); 935 //ucol_setAttribute(coll, UCOL_NORMALIZATION_MODE, UCOL_OFF, &status); 936 //ucol_setAttribute(coll, UCOL_ALTERNATE_HANDLING, UCOL_NON_IGNORABLE, &status); 937 ((RuleBasedCollator)coll).setAlternateHandlingShifted(false); 938 size = nonignorable.length; 939 for(i = 0; i < size-1; i++) { 940 for(j = i+1; j < size; j++) { 941 String t1 = nonignorable[i]; 942 String t2 = nonignorable[j]; 943 CollationTest.doTest(this, (RuleBasedCollator)coll, t1, t2, -1); 944 } 945 } 946 ((RuleBasedCollator)coll).setAlternateHandlingShifted(true); 947 coll.setStrength(Collator.QUATERNARY); 948 size = shifted.length; 949 for(i = 0; i < size-1; i++) { 950 for(j = i+1; j < size; j++) { 951 String t1 = shifted[i]; 952 String t2 = shifted[j]; 953 CollationTest.doTest(this, (RuleBasedCollator)coll, t1, t2, -1); 954 } 955 } 956 coll.setStrength(Collator.TERTIARY); 957 size = shifted.length; 958 for(i = 1; i < size; i++) { 959 String t1 = shifted[i-1]; 960 String t2 = shifted[i]; 961 CollationTest.doTest(this, (RuleBasedCollator)coll, t1, t2, 962 shiftedTert[i]); 963 } 964 } 965 966 public void TestFunkyA() { 967 String[] testSourceCases = { 968 "\u0041\u0300\u0301", 969 "\u0041\u0300\u0316", 970 "\u0041\u0300", 971 "\u00C0\u0301", 972 // this would work with forced normalization 973 "\u00C0\u0316", 974 }; 975 976 String[] testTargetCases = { 977 "\u0041\u0301\u0300", 978 "\u0041\u0316\u0300", 979 "\u00C0", 980 "\u0041\u0301\u0300", 981 // this would work with forced normalization 982 "\u0041\u0316\u0300", 983 }; 984 985 int[] results = { 986 1, 987 0, 988 0, 989 1, 990 0 991 }; 992 993 Collator myCollation; 994 try { 995 myCollation = Collator.getInstance(new Locale("en", "US")); 996 } catch (Exception e) { 997 warnln("ERROR: in creation of rule based collator"); 998 return; 999 } 1000 // logln("Testing some A letters, for some reason"); 1001 myCollation.setDecomposition(Collator.CANONICAL_DECOMPOSITION); 1002 myCollation.setStrength(Collator.TERTIARY); 1003 for (int i = 0; i < 4 ; i++) 1004 { 1005 CollationTest.doTest(this, (RuleBasedCollator)myCollation, 1006 testSourceCases[i], testTargetCases[i], 1007 results[i]); 1008 } 1009 } 1010 1011 public void TestChMove() { 1012 String[] chTest = { 1013 "c", 1014 "C", 1015 "ca", "cb", "cx", "cy", "CZ", 1016 "c\u030C", "C\u030C", 1017 "h", 1018 "H", 1019 "ha", "Ha", "harly", "hb", "HB", "hx", "HX", "hy", "HY", 1020 "ch", "cH", "Ch", "CH", 1021 "cha", "charly", "che", "chh", "chch", "chr", 1022 "i", "I", "iarly", 1023 "r", "R", 1024 "r\u030C", "R\u030C", 1025 "s", 1026 "S", 1027 "s\u030C", "S\u030C", 1028 "z", "Z", 1029 "z\u030C", "Z\u030C" 1030 }; 1031 Collator coll = null; 1032 try { 1033 coll = Collator.getInstance(new Locale("cs", "")); 1034 } catch (Exception e) { 1035 warnln("Cannot create Collator"); 1036 return; 1037 } 1038 int size = chTest.length; 1039 for(int i = 0; i < size-1; i++) { 1040 for(int j = i+1; j < size; j++) { 1041 String t1 = chTest[i]; 1042 String t2 = chTest[j]; 1043 CollationTest.doTest(this, (RuleBasedCollator)coll, t1, t2, -1); 1044 } 1045 } 1046 } 1047 1048 public void TestImplicitTailoring() { 1049 String rules[] = { 1050 /* Tailor b and c before U+4E00. */ 1051 "&[before 1]\u4e00 < b < c " + 1052 /* Now, before U+4E00 is c; put d and e after that. */ 1053 "&[before 1]\u4e00 < d < e", 1054 "&\u4e00 < a <<< A < b <<< B", 1055 "&[before 1]\u4e00 < \u4e01 < \u4e02", 1056 "&[before 1]\u4e01 < \u4e02 < \u4e03", 1057 }; 1058 String cases[][] = { 1059 { "b", "c", "d", "e", "\u4e00" }, 1060 { "\u4e00", "a", "A", "b", "B", "\u4e01" }, 1061 { "\u4e01", "\u4e02", "\u4e00" }, 1062 { "\u4e02", "\u4e03", "\u4e01" }, 1063 }; 1064 1065 int i = 0; 1066 1067 for(i = 0; i < rules.length; i++) { 1068 genericRulesStarter(rules[i], cases[i]); 1069 } 1070 } 1071 1072 public void TestFCDProblem() { 1073 String s1 = "\u0430\u0306\u0325"; 1074 String s2 = "\u04D1\u0325"; 1075 Collator coll = null; 1076 try { 1077 coll = Collator.getInstance(); 1078 } catch (Exception e) { 1079 warnln("Can't create collator"); 1080 return; 1081 } 1082 1083 coll.setDecomposition(Collator.NO_DECOMPOSITION); 1084 CollationTest.doTest(this, (RuleBasedCollator)coll, s1, s2, 0); 1085 coll.setDecomposition(Collator.CANONICAL_DECOMPOSITION); 1086 CollationTest.doTest(this, (RuleBasedCollator)coll, s1, s2, 0); 1087 } 1088 1089 public void TestEmptyRule() { 1090 String rulez = ""; 1091 try { 1092 RuleBasedCollator coll = new RuleBasedCollator(rulez); 1093 logln("rule:" + coll.getRules()); 1094 } catch (Exception e) { 1095 warnln(e.getMessage()); 1096 } 1097 } 1098 1099 /* superseded by TestBeforePinyin, since Chinese collation rules have changed */ 1100 /* 1101 public void TestJ784() { 1102 String[] data = { 1103 "A", "\u0101", "\u00e1", "\u01ce", "\u00e0", 1104 "E", "\u0113", "\u00e9", "\u011b", "\u00e8", 1105 "I", "\u012b", "\u00ed", "\u01d0", "\u00ec", 1106 "O", "\u014d", "\u00f3", "\u01d2", "\u00f2", 1107 "U", "\u016b", "\u00fa", "\u01d4", "\u00f9", 1108 "\u00fc", "\u01d6", "\u01d8", "\u01da", "\u01dc" 1109 }; 1110 genericLocaleStarter(new Locale("zh", ""), data); 1111 } 1112 */ 1113 1114 public void TestJ815() { 1115 String data[] = { 1116 "aa", 1117 "Aa", 1118 "ab", 1119 "Ab", 1120 "ad", 1121 "Ad", 1122 "ae", 1123 "Ae", 1124 "\u00e6", 1125 "\u00c6", 1126 "af", 1127 "Af", 1128 "b", 1129 "B" 1130 }; 1131 genericLocaleStarter(new Locale("fr", ""), data); 1132 genericRulesStarter("[backwards 2]&A<<\u00e6/e<<<\u00c6/E", data); 1133 } 1134 1135 public void TestJ3087() 1136 { 1137 String rule[] = { 1138 "&h<H&CH=\u0427", 1139 /* 1140 * The ICU 53 builder adheres to the principle that 1141 * a rule is affected by previous rules but not following ones. 1142 * Therefore, setting CH=\u0427 and then re-tailoring H makes CH != \u0427. 1143 "&CH=\u0427&h<H", */ 1144 "&CH=\u0427" 1145 }; 1146 RuleBasedCollator rbc = null; 1147 CollationElementIterator iter1; 1148 CollationElementIterator iter2; 1149 for (int i = 0; i < rule.length; i ++) { 1150 try { 1151 rbc = new RuleBasedCollator(rule[i]); 1152 } catch (Exception e) { 1153 warnln(e.getMessage()); 1154 continue; 1155 } 1156 iter1 = rbc.getCollationElementIterator("CH"); 1157 iter2 = rbc.getCollationElementIterator("\u0427"); 1158 int ce1 = CollationElementIterator.IGNORABLE; 1159 int ce2 = CollationElementIterator.IGNORABLE; 1160 // The ICU 53 builder code sets the uppercase flag only on the first CE. 1161 int mask = ~0; 1162 while (ce1 != CollationElementIterator.NULLORDER 1163 && ce2 != CollationElementIterator.NULLORDER) { 1164 ce1 = iter1.next(); 1165 ce2 = iter2.next(); 1166 if ((ce1 & mask) != (ce2 & mask)) { 1167 errln("Error generating RuleBasedCollator with the rule " 1168 + rule[i]); 1169 errln("CH != \\u0427"); 1170 } 1171 mask = ~0xc0; // mask off case/continuation bits 1172 } 1173 } 1174 } 1175 1176 public void DontTestJ831() { // Latvian does not use upper first 1177 String[] data = { 1178 "I", 1179 "i", 1180 "Y", 1181 "y" 1182 }; 1183 genericLocaleStarter(new Locale("lv", ""), data); 1184 } 1185 1186 public void TestBefore() { 1187 String data[] = { 1188 "\u0101", "\u00e1", "\u01ce", "\u00e0", "A", 1189 "\u0113", "\u00e9", "\u011b", "\u00e8", "E", 1190 "\u012b", "\u00ed", "\u01d0", "\u00ec", "I", 1191 "\u014d", "\u00f3", "\u01d2", "\u00f2", "O", 1192 "\u016b", "\u00fa", "\u01d4", "\u00f9", "U", 1193 "\u01d6", "\u01d8", "\u01da", "\u01dc", "\u00fc" 1194 }; 1195 genericRulesStarter( 1196 "&[before 1]a<\u0101<\u00e1<\u01ce<\u00e0" 1197 + "&[before 1]e<\u0113<\u00e9<\u011b<\u00e8" 1198 + "&[before 1]i<\u012b<\u00ed<\u01d0<\u00ec" 1199 + "&[before 1]o<\u014d<\u00f3<\u01d2<\u00f2" 1200 + "&[before 1]u<\u016b<\u00fa<\u01d4<\u00f9" 1201 + "&u<\u01d6<\u01d8<\u01da<\u01dc<\u00fc", data); 1202 } 1203 1204 public void TestHangulTailoring() { 1205 String[] koreanData = { 1206 "\uac00", "\u4f3d", "\u4f73", "\u5047", "\u50f9", "\u52a0", "\u53ef", "\u5475", 1207 "\u54e5", "\u5609", "\u5ac1", "\u5bb6", "\u6687", "\u67b6", "\u67b7", "\u67ef", 1208 "\u6b4c", "\u73c2", "\u75c2", "\u7a3c", "\u82db", "\u8304", "\u8857", "\u8888", 1209 "\u8a36", "\u8cc8", "\u8dcf", "\u8efb", "\u8fe6", "\u99d5", 1210 "\u4EEE", "\u50A2", "\u5496", "\u54FF", "\u5777", "\u5B8A", "\u659D", "\u698E", 1211 "\u6A9F", "\u73C8", "\u7B33", "\u801E", "\u8238", "\u846D", "\u8B0C" 1212 }; 1213 1214 String rules = 1215 "&\uac00 <<< \u4f3d <<< \u4f73 <<< \u5047 <<< \u50f9 <<< \u52a0 <<< \u53ef <<< \u5475 " 1216 + "<<< \u54e5 <<< \u5609 <<< \u5ac1 <<< \u5bb6 <<< \u6687 <<< \u67b6 <<< \u67b7 <<< \u67ef " 1217 + "<<< \u6b4c <<< \u73c2 <<< \u75c2 <<< \u7a3c <<< \u82db <<< \u8304 <<< \u8857 <<< \u8888 " 1218 + "<<< \u8a36 <<< \u8cc8 <<< \u8dcf <<< \u8efb <<< \u8fe6 <<< \u99d5 " 1219 + "<<< \u4EEE <<< \u50A2 <<< \u5496 <<< \u54FF <<< \u5777 <<< \u5B8A <<< \u659D <<< \u698E " 1220 + "<<< \u6A9F <<< \u73C8 <<< \u7B33 <<< \u801E <<< \u8238 <<< \u846D <<< \u8B0C"; 1221 1222 String rlz = rules; 1223 1224 Collator coll = null; 1225 try { 1226 coll = new RuleBasedCollator(rlz); 1227 } catch (Exception e) { 1228 warnln("Unable to open collator with rules" + rules); 1229 return; 1230 } 1231 // logln("Using start of korean rules\n"); 1232 genericOrderingTest(coll, koreanData); 1233 1234 // no such locale in icu4j 1235 // logln("Using ko__LOTUS locale\n"); 1236 // genericLocaleStarter(new Locale("ko__LOTUS", ""), koreanData); 1237 } 1238 1239 public void TestIncrementalNormalize() { 1240 Collator coll = null; 1241 // logln("Test 1 ...."); 1242 { 1243 /* Test 1. Run very long unnormalized strings, to force overflow of*/ 1244 /* most buffers along the way.*/ 1245 1246 try { 1247 coll = Collator.getInstance(new Locale("en", "US")); 1248 } catch (Exception e) { 1249 warnln("Cannot get default instance!"); 1250 return; 1251 } 1252 char baseA =0x41; 1253 char ccMix[] = {0x316, 0x321, 0x300}; 1254 int sLen; 1255 int i; 1256 StringBuffer strA = new StringBuffer(); 1257 StringBuffer strB = new StringBuffer(); 1258 1259 coll.setDecomposition(Collator.CANONICAL_DECOMPOSITION); 1260 1261 for (sLen = 1000; sLen<1001; sLen++) { 1262 strA.delete(0, strA.length()); 1263 strA.append(baseA); 1264 strB.delete(0, strB.length()); 1265 strB.append(baseA); 1266 for (i=1; i< sLen; i++) { 1267 strA.append(ccMix[i % 3]); 1268 strB.insert(1, ccMix[i % 3]); 1269 } 1270 coll.setStrength(Collator.TERTIARY); // Do test with default strength, which runs 1271 CollationTest.doTest(this, (RuleBasedCollator)coll, 1272 strA.toString(), strB.toString(), 0); // optimized functions in the impl 1273 coll.setStrength(Collator.IDENTICAL); // Do again with the slow, general impl. 1274 CollationTest.doTest(this, (RuleBasedCollator)coll, 1275 strA.toString(), strB.toString(), 0); 1276 } 1277 } 1278 /* Test 2: Non-normal sequence in a string that extends to the last character*/ 1279 /* of the string. Checks a couple of edge cases.*/ 1280 // logln("Test 2 ...."); 1281 { 1282 String strA = "AA\u0300\u0316"; 1283 String strB = "A\u00c0\u0316"; 1284 coll.setStrength(Collator.TERTIARY); 1285 CollationTest.doTest(this, (RuleBasedCollator)coll, strA, strB, 0); 1286 } 1287 /* Test 3: Non-normal sequence is terminated by a surrogate pair.*/ 1288 // logln("Test 3 ...."); 1289 { 1290 String strA = "AA\u0300\u0316\uD800\uDC01"; 1291 String strB = "A\u00c0\u0316\uD800\uDC00"; 1292 coll.setStrength(Collator.TERTIARY); 1293 CollationTest.doTest(this, (RuleBasedCollator)coll, strA, strB, 1); 1294 } 1295 /* Test 4: Imbedded nulls do not terminate a string when length is specified.*/ 1296 // logln("Test 4 ...."); 1297 /* 1298 * not a valid test since string are null-terminated in java{ 1299 char strA[] = {0x41, 0x00, 0x42}; 1300 char strB[] = {0x41, 0x00, 0x00}; 1301 1302 int result = coll.compare(new String(strA), new String(strB)); 1303 if (result != 1) { 1304 errln("ERROR 1 in test 4\n"); 1305 } 1306 1307 result = coll.compare(new String(strA, 0, 1), new String(strB, 0, 1)); 1308 if (result != 0) { 1309 errln("ERROR 1 in test 4\n"); 1310 } 1311 1312 CollationKey sortKeyA = coll.getCollationKey(new String(strA)); 1313 CollationKey sortKeyB = coll.getCollationKey(new String(strB)); 1314 1315 int r = sortKeyA.compareTo(sortKeyB); 1316 if (r <= 0) { 1317 errln("Error 4 in test 4\n"); 1318 } 1319 1320 coll.setStrength(Collator.IDENTICAL); 1321 sortKeyA = coll.getCollationKey(new String(strA)); 1322 sortKeyB = coll.getCollationKey(new String(strB)); 1323 1324 r = sortKeyA.compareTo(sortKeyB); 1325 if (r <= 0) { 1326 errln("Error 7 in test 4\n"); 1327 } 1328 1329 coll.setStrength(Collator.TERTIARY); 1330 } 1331 */ 1332 /* Test 5: Null characters in non-normal source strings.*/ 1333 // logln("Test 5 ...."); 1334 /* 1335 * not a valid test since string are null-terminated in java{ 1336 { 1337 char strA[] = {0x41, 0x41, 0x300, 0x316, 0x00, 0x42,}; 1338 char strB[] = {0x41, 0x41, 0x300, 0x316, 0x00, 0x00,}; 1339 1340 1341 int result = coll.compare(new String(strA, 0, 6), new String(strB, 0, 6)); 1342 if (result < 0) { 1343 errln("ERROR 1 in test 5\n"); 1344 } 1345 result = coll.compare(new String(strA, 0, 4), new String(strB, 0, 4)); 1346 if (result != 0) { 1347 errln("ERROR 2 in test 5\n"); 1348 } 1349 1350 CollationKey sortKeyA = coll.getCollationKey(new String(strA)); 1351 CollationKey sortKeyB = coll.getCollationKey(new String(strB)); 1352 int r = sortKeyA.compareTo(sortKeyB); 1353 if (r <= 0) { 1354 errln("Error 4 in test 5\n"); 1355 } 1356 1357 coll.setStrength(Collator.IDENTICAL); 1358 1359 sortKeyA = coll.getCollationKey(new String(strA)); 1360 sortKeyB = coll.getCollationKey(new String(strB)); 1361 r = sortKeyA.compareTo(sortKeyB); 1362 if (r <= 0) { 1363 errln("Error 7 in test 5\n"); 1364 } 1365 1366 coll.setStrength(Collator.TERTIARY); 1367 } 1368 */ 1369 /* Test 6: Null character as base of a non-normal combining sequence.*/ 1370 // logln("Test 6 ...."); 1371 /* 1372 * not a valid test since string are null-terminated in java{ 1373 { 1374 char strA[] = {0x41, 0x0, 0x300, 0x316, 0x41, 0x302,}; 1375 char strB[] = {0x41, 0x0, 0x302, 0x316, 0x41, 0x300,}; 1376 1377 int result = coll.compare(new String(strA, 0, 5), new String(strB, 0, 5)); 1378 if (result != -1) { 1379 errln("Error 1 in test 6\n"); 1380 } 1381 result = coll.compare(new String(strA, 0, 1), new String(strB, 0, 1)); 1382 if (result != 0) { 1383 errln("Error 2 in test 6\n"); 1384 } 1385 } 1386 */ 1387 } 1388 1389 public void TestContraction() { 1390 String[] testrules = { 1391 "&A = AB / B", 1392 "&A = A\\u0306/\\u0306", 1393 "&c = ch / h", 1394 }; 1395 String[] testdata = { 1396 "AB", "AB", "A\u0306", "ch" 1397 }; 1398 String[] testdata2 = { 1399 "\u0063\u0067", 1400 "\u0063\u0068", 1401 "\u0063\u006C", 1402 }; 1403 /* 1404 * These pairs of rule strings are not guaranteed to yield the very same mappings. 1405 * In fact, LDML 24 recommends an improved way of creating mappings 1406 * which always yields different mappings for such pairs. See 1407 * http://www.unicode.org/reports/tr35/tr35-33/tr35-collation.html#Orderings 1408 String[] testrules3 = { 1409 "&z < xyz &xyzw << B", 1410 "&z < xyz &xyz << B / w", 1411 "&z < ch &achm << B", 1412 "&z < ch &a << B / chm", 1413 "&\ud800\udc00w << B", 1414 "&\ud800\udc00 << B / w", 1415 "&a\ud800\udc00m << B", 1416 "&a << B / \ud800\udc00m", 1417 }; */ 1418 1419 RuleBasedCollator coll = null; 1420 for (int i = 0; i < testrules.length; i ++) { 1421 CollationElementIterator iter1 = null; 1422 int j = 0; 1423 // logln("Rule " + testrules[i] + " for testing\n"); 1424 String rule = testrules[i]; 1425 try { 1426 coll = new RuleBasedCollator(rule); 1427 } catch (Exception e) { 1428 warnln("Collator creation failed " + testrules[i]); 1429 return; 1430 } 1431 try { 1432 iter1 = coll.getCollationElementIterator(testdata[i]); 1433 } catch (Exception e) { 1434 errln("Collation iterator creation failed\n"); 1435 return; 1436 } 1437 while (j < 2) { 1438 CollationElementIterator iter2; 1439 int ce; 1440 try { 1441 iter2 = coll.getCollationElementIterator(String.valueOf(testdata[i].charAt(j))); 1442 1443 }catch (Exception e) { 1444 errln("Collation iterator creation failed\n"); 1445 return; 1446 } 1447 ce = iter2.next(); 1448 while (ce != CollationElementIterator.NULLORDER) { 1449 if (iter1.next() != ce) { 1450 errln("Collation elements in contraction split does not match\n"); 1451 return; 1452 } 1453 ce = iter2.next(); 1454 } 1455 j ++; 1456 } 1457 if (iter1.next() != CollationElementIterator.NULLORDER) { 1458 errln("Collation elements not exhausted\n"); 1459 return; 1460 } 1461 } 1462 String rule = "& a < b < c < ch < d & c = ch / h"; 1463 try { 1464 coll = new RuleBasedCollator(rule); 1465 } catch (Exception e) { 1466 errln("cannot create rulebased collator"); 1467 return; 1468 } 1469 1470 if (coll.compare(testdata2[0], testdata2[1]) != -1) { 1471 errln("Expected " + testdata2[0] + " < " + testdata2[1]); 1472 return; 1473 } 1474 if (coll.compare(testdata2[1], testdata2[2]) != -1) { 1475 errln("Expected " + testdata2[1] + " < " + testdata2[2]); 1476 return; 1477 } 1478 /* see above -- for (int i = 0; i < testrules3.length; i += 2) { 1479 RuleBasedCollator coll1, coll2; 1480 CollationElementIterator iter1, iter2; 1481 char ch = 0x0042; 1482 int ce; 1483 rule = testrules3[i]; 1484 try { 1485 coll1 = new RuleBasedCollator(rule); 1486 } catch (Exception e) { 1487 errln("Fail: cannot create rulebased collator, rule:" + rule); 1488 return; 1489 } 1490 rule = testrules3[i + 1]; 1491 try { 1492 coll2 = new RuleBasedCollator(rule); 1493 } catch (Exception e) { 1494 errln("Collator creation failed " + testrules[i]); 1495 return; 1496 } 1497 try { 1498 iter1 = coll1.getCollationElementIterator(String.valueOf(ch)); 1499 iter2 = coll2.getCollationElementIterator(String.valueOf(ch)); 1500 } catch (Exception e) { 1501 errln("Collation iterator creation failed\n"); 1502 return; 1503 } 1504 ce = iter1.next(); 1505 1506 while (ce != CollationElementIterator.NULLORDER) { 1507 if (ce != iter2.next()) { 1508 errln("CEs does not match\n"); 1509 return; 1510 } 1511 ce = iter1.next(); 1512 } 1513 if (iter2.next() != CollationElementIterator.NULLORDER) { 1514 errln("CEs not exhausted\n"); 1515 return; 1516 } 1517 } */ 1518 } 1519 1520 public void TestExpansion() { 1521 String[] testrules = { 1522 /* 1523 * This seems to have tested that M was not mapped to an expansion. 1524 * I believe the old builder just did that because it computed the extension CEs 1525 * at the very end, which was a bug. 1526 * Among other problems, it violated the core tailoring principle 1527 * by making an earlier rule depend on a later one. 1528 * And, of course, if M did not get an expansion, then it was primary different from K, 1529 * unlike what the rule &K<<M says. 1530 "&J << K / B & K << M", 1531 */ 1532 "&J << K / B << M" 1533 }; 1534 String[] testdata = { 1535 "JA", "MA", "KA", "KC", "JC", "MC", 1536 }; 1537 1538 Collator coll; 1539 for (int i = 0; i < testrules.length; i++) { 1540 // logln("Rule " + testrules[i] + " for testing\n"); 1541 String rule = testrules[i]; 1542 try { 1543 coll = new RuleBasedCollator(rule); 1544 } catch (Exception e) { 1545 warnln("Collator creation failed " + testrules[i]); 1546 return; 1547 } 1548 1549 for (int j = 0; j < 5; j ++) { 1550 CollationTest.doTest(this, (RuleBasedCollator)coll, 1551 testdata[j], testdata[j + 1], -1); 1552 } 1553 } 1554 } 1555 1556 public void TestContractionEndCompare() 1557 { 1558 String rules = "&b=ch"; 1559 String src = "bec"; 1560 String tgt = "bech"; 1561 Collator coll = null; 1562 try { 1563 coll = new RuleBasedCollator(rules); 1564 } catch (Exception e) { 1565 warnln("Collator creation failed " + rules); 1566 return; 1567 } 1568 CollationTest.doTest(this, (RuleBasedCollator)coll, src, tgt, 1); 1569 } 1570 1571 public void TestLocaleRuleBasedCollators() { 1572 if (getInclusion() < 5) { 1573 // not serious enough to run this 1574 return; 1575 } 1576 Locale locale[] = Collator.getAvailableLocales(); 1577 String prevrule = null; 1578 for (int i = 0; i < locale.length; i ++) { 1579 Locale l = locale[i]; 1580 try { 1581 ICUResourceBundle rb = (ICUResourceBundle)UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_COLLATION_BASE_NAME,l); 1582 String collkey = rb.getStringWithFallback("collations/default"); 1583 ICUResourceBundle elements = rb.getWithFallback("collations/" + collkey); 1584 if (elements == null) { 1585 continue; 1586 } 1587 String rule = null; 1588 /* 1589 Object[][] colldata = (Object[][])elements; 1590 // %%CollationBin 1591 if (colldata[0][1] instanceof byte[]){ 1592 rule = (String)colldata[1][1]; 1593 } 1594 else { 1595 rule = (String)colldata[0][1]; 1596 } 1597 */ 1598 rule = elements.getString("Sequence"); 1599 1600 RuleBasedCollator col1 = 1601 (RuleBasedCollator)Collator.getInstance(l); 1602 if (!rule.equals(col1.getRules())) { 1603 errln("Rules should be the same in the RuleBasedCollator and Locale"); 1604 } 1605 if (rule != null && rule.length() > 0 1606 && !rule.equals(prevrule)) { 1607 RuleBasedCollator col2 = new RuleBasedCollator(rule); 1608 if (!col1.equals(col2)) { 1609 errln("Error creating RuleBasedCollator from " + 1610 "locale rules for " + l.toString()); 1611 } 1612 } 1613 prevrule = rule; 1614 } catch (Exception e) { 1615 warnln("Error retrieving resource bundle for testing: " + e.toString()); 1616 } 1617 } 1618 } 1619 1620 public void TestOptimize() { 1621 /* this is not really a test - just trying out 1622 * whether copying of UCA contents will fail 1623 * Cannot really test, since the functionality 1624 * remains the same. 1625 */ 1626 String rules[] = { 1627 "[optimize [\\uAC00-\\uD7FF]]" 1628 }; 1629 String data[][] = { 1630 { "a", "b"} 1631 }; 1632 int i = 0; 1633 1634 for(i = 0; i<rules.length; i++) { 1635 genericRulesStarter(rules[i], data[i]); 1636 } 1637 } 1638 1639 public void TestIdenticalCompare() 1640 { 1641 try { 1642 RuleBasedCollator coll 1643 = new RuleBasedCollator("& \uD800\uDC00 = \uD800\uDC01"); 1644 String strA = "AA\u0300\u0316\uD800\uDC01"; 1645 String strB = "A\u00c0\u0316\uD800\uDC00"; 1646 coll.setStrength(Collator.IDENTICAL); 1647 CollationTest.doTest(this, coll, strA, strB, 1); 1648 } catch (Exception e) { 1649 warnln(e.getMessage()); 1650 } 1651 } 1652 1653 public void TestMergeSortKeys() 1654 { 1655 String cases[] = {"abc", "abcd", "abcde"}; 1656 String prefix = "foo"; 1657 String suffix = "egg"; 1658 CollationKey mergedPrefixKeys[] = new CollationKey[cases.length]; 1659 CollationKey mergedSuffixKeys[] = new CollationKey[cases.length]; 1660 1661 Collator coll = Collator.getInstance(Locale.ENGLISH); 1662 genericLocaleStarter(Locale.ENGLISH, cases); 1663 1664 int strength = Collator.PRIMARY; 1665 while (strength <= Collator.IDENTICAL) { 1666 coll.setStrength(strength); 1667 CollationKey prefixKey = coll.getCollationKey(prefix); 1668 CollationKey suffixKey = coll.getCollationKey(suffix); 1669 for (int i = 0; i < cases.length; i ++) { 1670 CollationKey key = coll.getCollationKey(cases[i]); 1671 mergedPrefixKeys[i] = prefixKey.merge(key); 1672 mergedSuffixKeys[i] = suffixKey.merge(key); 1673 if (mergedPrefixKeys[i].getSourceString() != null 1674 || mergedSuffixKeys[i].getSourceString() != null) { 1675 errln("Merged source string error: expected null"); 1676 } 1677 if (i > 0) { 1678 if (mergedPrefixKeys[i-1].compareTo(mergedPrefixKeys[i]) 1679 >= 0) { 1680 errln("Error while comparing prefixed keys @ strength " 1681 + strength); 1682 errln(CollationTest.prettify(mergedPrefixKeys[i-1])); 1683 errln(CollationTest.prettify(mergedPrefixKeys[i])); 1684 } 1685 if (mergedSuffixKeys[i-1].compareTo(mergedSuffixKeys[i]) 1686 >= 0) { 1687 errln("Error while comparing suffixed keys @ strength " 1688 + strength); 1689 errln(CollationTest.prettify(mergedSuffixKeys[i-1])); 1690 errln(CollationTest.prettify(mergedSuffixKeys[i])); 1691 } 1692 } 1693 } 1694 if (strength == Collator.QUATERNARY) { 1695 strength = Collator.IDENTICAL; 1696 } 1697 else { 1698 strength ++; 1699 } 1700 } 1701 } 1702 1703 public void TestVariableTop() 1704 { 1705 // ICU 53+: The character must be in a supported reordering group, 1706 // and the variable top is pinned to the end of that group. 1707 // parseNextToken is not released as public so i create my own rules 1708 String rules = "& ' ' < b < c < de < fg & hi = j"; 1709 try { 1710 RuleBasedCollator coll = new RuleBasedCollator(rules); 1711 String tokens[] = {" ", "b", "c", "de", "fg", "hi", "j", "ab"}; 1712 coll.setAlternateHandlingShifted(true); 1713 for (int i = 0; i < tokens.length; i ++) { 1714 int varTopOriginal = coll.getVariableTop(); 1715 try { 1716 int varTop = coll.setVariableTop(tokens[i]); 1717 if (i > 4) { 1718 errln("Token " + tokens[i] + " expected to fail"); 1719 } 1720 if (varTop != coll.getVariableTop()) { 1721 errln("Error setting and getting variable top"); 1722 } 1723 CollationKey key1 = coll.getCollationKey(tokens[i]); 1724 for (int j = 0; j < i; j ++) { 1725 CollationKey key2 = coll.getCollationKey(tokens[j]); 1726 if (key2.compareTo(key1) < 0) { 1727 errln("Setting variable top shouldn't change the comparison sequence"); 1728 } 1729 byte sortorder[] = key2.toByteArray(); 1730 if (sortorder.length > 0 1731 && (key2.toByteArray())[0] > 1) { 1732 errln("Primary sort order should be 0"); 1733 } 1734 } 1735 } catch (Exception e) { 1736 CollationElementIterator iter 1737 = coll.getCollationElementIterator(tokens[i]); 1738 /*int ce =*/ iter.next(); 1739 int ce2 = iter.next(); 1740 if (ce2 == CollationElementIterator.NULLORDER) { 1741 errln("Token " + tokens[i] + " not expected to fail"); 1742 } 1743 if (coll.getVariableTop() != varTopOriginal) { 1744 errln("When exception is thrown variable top should " 1745 + "not be changed"); 1746 } 1747 } 1748 coll.setVariableTop(varTopOriginal); 1749 if (varTopOriginal != coll.getVariableTop()) { 1750 errln("Couldn't restore old variable top\n"); 1751 } 1752 } 1753 1754 // Testing calling with error set 1755 try { 1756 coll.setVariableTop(""); 1757 errln("Empty string should throw an IllegalArgumentException"); 1758 } catch (IllegalArgumentException e) { 1759 logln("PASS: Empty string failed as expected"); 1760 } 1761 try { 1762 coll.setVariableTop(null); 1763 errln("Null string should throw an IllegalArgumentException"); 1764 } catch (IllegalArgumentException e) { 1765 logln("PASS: null string failed as expected"); 1766 } 1767 } catch (Exception e) { 1768 warnln("Error creating RuleBasedCollator"); 1769 } 1770 } 1771 1772 // ported from cmsccoll.c 1773 public void TestVariableTopSetting() { 1774 int varTopOriginal = 0, varTop1, varTop2; 1775 Collator coll = Collator.getInstance(ULocale.ROOT); 1776 1777 String empty = ""; 1778 String space = " "; 1779 String dot = "."; /* punctuation */ 1780 String degree = "\u00b0"; /* symbol */ 1781 String dollar = "$"; /* currency symbol */ 1782 String zero = "0"; /* digit */ 1783 1784 varTopOriginal = coll.getVariableTop(); 1785 logln(String.format("coll.getVariableTop(root) -> %08x", varTopOriginal)); 1786 ((RuleBasedCollator)coll).setAlternateHandlingShifted(true); 1787 1788 varTop1 = coll.setVariableTop(space); 1789 varTop2 = coll.getVariableTop(); 1790 logln(String.format("coll.setVariableTop(space) -> %08x", varTop1)); 1791 if(varTop1 != varTop2 || 1792 !coll.equals(empty, space) || 1793 coll.equals(empty, dot) || 1794 coll.equals(empty, degree) || 1795 coll.equals(empty, dollar) || 1796 coll.equals(empty, zero) || 1797 coll.compare(space, dot) >= 0) { 1798 errln("coll.setVariableTop(space) did not work"); 1799 } 1800 1801 varTop1 = coll.setVariableTop(dot); 1802 varTop2 = coll.getVariableTop(); 1803 logln(String.format("coll.setVariableTop(dot) -> %08x", varTop1)); 1804 if(varTop1 != varTop2 || 1805 !coll.equals(empty, space) || 1806 !coll.equals(empty, dot) || 1807 coll.equals(empty, degree) || 1808 coll.equals(empty, dollar) || 1809 coll.equals(empty, zero) || 1810 coll.compare(dot, degree) >= 0) { 1811 errln("coll.setVariableTop(dot) did not work"); 1812 } 1813 1814 varTop1 = coll.setVariableTop(degree); 1815 varTop2 = coll.getVariableTop(); 1816 logln(String.format("coll.setVariableTop(degree) -> %08x", varTop1)); 1817 if(varTop1 != varTop2 || 1818 !coll.equals(empty, space) || 1819 !coll.equals(empty, dot) || 1820 !coll.equals(empty, degree) || 1821 coll.equals(empty, dollar) || 1822 coll.equals(empty, zero) || 1823 coll.compare(degree, dollar) >= 0) { 1824 errln("coll.setVariableTop(degree) did not work"); 1825 } 1826 1827 varTop1 = coll.setVariableTop(dollar); 1828 varTop2 = coll.getVariableTop(); 1829 logln(String.format("coll.setVariableTop(dollar) -> %08x", varTop1)); 1830 if(varTop1 != varTop2 || 1831 !coll.equals(empty, space) || 1832 !coll.equals(empty, dot) || 1833 !coll.equals(empty, degree) || 1834 !coll.equals(empty, dollar) || 1835 coll.equals(empty, zero) || 1836 coll.compare(dollar, zero) >= 0) { 1837 errln("coll.setVariableTop(dollar) did not work"); 1838 } 1839 1840 logln("Testing setting variable top to contractions"); 1841 try { 1842 coll.setVariableTop("@P"); 1843 errln("Invalid contraction succeded in setting variable top!"); 1844 } catch(Exception expected) { 1845 } 1846 1847 logln("Test restoring variable top"); 1848 coll.setVariableTop(varTopOriginal); 1849 if(varTopOriginal != coll.getVariableTop()) { 1850 errln("Couldn't restore old variable top"); 1851 } 1852 } 1853 1854 // ported from cmsccoll.c 1855 public void TestMaxVariable() { 1856 int oldMax, max; 1857 1858 String empty = ""; 1859 String space = " "; 1860 String dot = "."; /* punctuation */ 1861 String degree = "\u00b0"; /* symbol */ 1862 String dollar = "$"; /* currency symbol */ 1863 String zero = "0"; /* digit */ 1864 1865 Collator coll = Collator.getInstance(ULocale.ROOT); 1866 1867 oldMax = coll.getMaxVariable(); 1868 logln(String.format("coll.getMaxVariable(root) -> %04x", oldMax)); 1869 ((RuleBasedCollator)coll).setAlternateHandlingShifted(true); 1870 1871 coll.setMaxVariable(Collator.ReorderCodes.SPACE); 1872 max = coll.getMaxVariable(); 1873 logln(String.format("coll.setMaxVariable(space) -> %04x", max)); 1874 if(max != Collator.ReorderCodes.SPACE || 1875 !coll.equals(empty, space) || 1876 coll.equals(empty, dot) || 1877 coll.equals(empty, degree) || 1878 coll.equals(empty, dollar) || 1879 coll.equals(empty, zero) || 1880 coll.compare(space, dot) >= 0) { 1881 errln("coll.setMaxVariable(space) did not work"); 1882 } 1883 1884 coll.setMaxVariable(Collator.ReorderCodes.PUNCTUATION); 1885 max = coll.getMaxVariable(); 1886 logln(String.format("coll.setMaxVariable(punctuation) -> %04x", max)); 1887 if(max != Collator.ReorderCodes.PUNCTUATION || 1888 !coll.equals(empty, space) || 1889 !coll.equals(empty, dot) || 1890 coll.equals(empty, degree) || 1891 coll.equals(empty, dollar) || 1892 coll.equals(empty, zero) || 1893 coll.compare(dot, degree) >= 0) { 1894 errln("coll.setMaxVariable(punctuation) did not work"); 1895 } 1896 1897 coll.setMaxVariable(Collator.ReorderCodes.SYMBOL); 1898 max = coll.getMaxVariable(); 1899 logln(String.format("coll.setMaxVariable(symbol) -> %04x", max)); 1900 if(max != Collator.ReorderCodes.SYMBOL || 1901 !coll.equals(empty, space) || 1902 !coll.equals(empty, dot) || 1903 !coll.equals(empty, degree) || 1904 coll.equals(empty, dollar) || 1905 coll.equals(empty, zero) || 1906 coll.compare(degree, dollar) >= 0) { 1907 errln("coll.setMaxVariable(symbol) did not work"); 1908 } 1909 1910 coll.setMaxVariable(Collator.ReorderCodes.CURRENCY); 1911 max = coll.getMaxVariable(); 1912 logln(String.format("coll.setMaxVariable(currency) -> %04x", max)); 1913 if(max != Collator.ReorderCodes.CURRENCY || 1914 !coll.equals(empty, space) || 1915 !coll.equals(empty, dot) || 1916 !coll.equals(empty, degree) || 1917 !coll.equals(empty, dollar) || 1918 coll.equals(empty, zero) || 1919 coll.compare(dollar, zero) >= 0) { 1920 errln("coll.setMaxVariable(currency) did not work"); 1921 } 1922 1923 logln("Test restoring maxVariable"); 1924 coll.setMaxVariable(oldMax); 1925 if(oldMax != coll.getMaxVariable()) { 1926 errln("Couldn't restore old maxVariable"); 1927 } 1928 } 1929 1930 public void TestUCARules() 1931 { 1932 try { 1933 // only root locale can have empty tailorings .. not English! 1934 RuleBasedCollator coll 1935 = (RuleBasedCollator)Collator.getInstance(new Locale("","","")); 1936 String rule 1937 = coll.getRules(false); 1938 if (!rule.equals("")) { 1939 errln("Empty rule string should have empty rules " + rule); 1940 } 1941 rule = coll.getRules(true); 1942 if (rule.equals("")) { 1943 errln("UCA rule string should not be empty"); 1944 } 1945 coll = new RuleBasedCollator(rule); 1946 } catch (Exception e) { 1947 warnln(e.getMessage()); 1948 } 1949 } 1950 1951 /** 1952 * Jitterbug 2726 1953 */ 1954 public void TestShifted() 1955 { 1956 RuleBasedCollator collator = (RuleBasedCollator) Collator.getInstance(); 1957 collator.setStrength(Collator.PRIMARY); 1958 collator.setAlternateHandlingShifted(true); 1959 CollationTest.doTest(this, collator, " a", "a", 0); // works properly 1960 CollationTest.doTest(this, collator, "a", "a ", 0); // inconsistent results 1961 } 1962 1963 /** 1964 * Test for CollationElementIterator previous and next for the whole set of 1965 * unicode characters with normalization on. 1966 */ 1967 public void TestNumericCollation() 1968 { 1969 String basicTestStrings[] = {"hello1", "hello2", "hello123456"}; 1970 String preZeroTestStrings[] = {"avery1", 1971 "avery01", 1972 "avery001", 1973 "avery0001"}; 1974 String thirtyTwoBitNumericStrings[] = {"avery42949672960", 1975 "avery42949672961", 1976 "avery42949672962", 1977 "avery429496729610"}; 1978 1979 String supplementaryDigits[] = {"\uD835\uDFCE", // 0 1980 "\uD835\uDFCF", // 1 1981 "\uD835\uDFD0", // 2 1982 "\uD835\uDFD1", // 3 1983 "\uD835\uDFCF\uD835\uDFCE", // 10 1984 "\uD835\uDFCF\uD835\uDFCF", // 11 1985 "\uD835\uDFCF\uD835\uDFD0", // 12 1986 "\uD835\uDFD0\uD835\uDFCE", // 20 1987 "\uD835\uDFD0\uD835\uDFCF", // 21 1988 "\uD835\uDFD0\uD835\uDFD0" // 22 1989 }; 1990 1991 String foreignDigits[] = {"\u0661", 1992 "\u0662", 1993 "\u0663", 1994 "\u0661\u0660", 1995 "\u0661\u0662", 1996 "\u0661\u0663", 1997 "\u0662\u0660", 1998 "\u0662\u0662", 1999 "\u0662\u0663", 2000 "\u0663\u0660", 2001 "\u0663\u0662", 2002 "\u0663\u0663" 2003 }; 2004 2005 //Additional tests to cover bug reported in #9476 2006 String lastDigitDifferent[]={"2004","2005", 2007 "110005", "110006", 2008 "11005", "11006", 2009 "100000000005","100000000006"}; 2010 2011 // Open our collator. 2012 RuleBasedCollator coll 2013 = (RuleBasedCollator)Collator.getInstance(Locale.ENGLISH); 2014 String att[] = {"NumericCollation"}; 2015 Boolean val[] = {Boolean.TRUE}; 2016 genericLocaleStarterWithOptions(Locale.ENGLISH, basicTestStrings, att, 2017 val); 2018 genericLocaleStarterWithOptions(Locale.ENGLISH, 2019 thirtyTwoBitNumericStrings, att, val); 2020 genericLocaleStarterWithOptions(Locale.ENGLISH, foreignDigits, att, 2021 val); 2022 genericLocaleStarterWithOptions(Locale.ENGLISH, supplementaryDigits, 2023 att, val); 2024 2025 // Setting up our collator to do digits. 2026 coll.setNumericCollation(true); 2027 2028 // Testing that prepended zeroes still yield the correct collation 2029 // behavior. 2030 // We expect that every element in our strings array will be equal. 2031 for (int i = 0; i < preZeroTestStrings.length - 1; i ++) { 2032 for (int j = i + 1; j < preZeroTestStrings.length; j ++) { 2033 CollationTest.doTest(this, coll, preZeroTestStrings[i], 2034 preZeroTestStrings[j],0); 2035 } 2036 } 2037 2038 //Testing that the behavior reported in #9476 is fixed 2039 //We expect comparisons between adjacent pairs will result in -1 2040 for (int i=0; i < lastDigitDifferent.length -1; i=i+2 ) { 2041 CollationTest.doTest(this, coll, lastDigitDifferent[i], lastDigitDifferent[i+1], -1); 2042 } 2043 2044 2045 //cover setNumericCollationDefault, getNumericCollation 2046 assertTrue("The Numeric Collation setting is on", coll.getNumericCollation()); 2047 coll.setNumericCollationDefault(); 2048 logln("After set Numeric to default, the setting is: " + coll.getNumericCollation()); 2049 } 2050 2051 public void Test3249() 2052 { 2053 String rule = "&x < a &z < a"; 2054 try { 2055 RuleBasedCollator coll = new RuleBasedCollator(rule); 2056 if(coll!=null){ 2057 logln("Collator did not throw an exception"); 2058 } 2059 } catch (Exception e) { 2060 warnln("Error creating RuleBasedCollator with " + rule + " failed"); 2061 } 2062 } 2063 2064 public void TestTibetanConformance() 2065 { 2066 String test[] = {"\u0FB2\u0591\u0F71\u0061", "\u0FB2\u0F71\u0061"}; 2067 try { 2068 Collator coll = Collator.getInstance(); 2069 coll.setDecomposition(Collator.CANONICAL_DECOMPOSITION); 2070 if (coll.compare(test[0], test[1]) != 0) { 2071 errln("Tibetan comparison error"); 2072 } 2073 CollationTest.doTest(this, (RuleBasedCollator)coll, 2074 test[0], test[1], 0); 2075 } catch (Exception e) { 2076 warnln("Error creating UCA collator"); 2077 } 2078 } 2079 2080 public void TestJ3347() 2081 { 2082 try { 2083 Collator coll = Collator.getInstance(Locale.FRENCH); 2084 ((RuleBasedCollator)coll).setAlternateHandlingShifted(true); 2085 if (coll.compare("6", "!6") != 0) { 2086 errln("Jitterbug 3347 failed"); 2087 } 2088 } catch (Exception e) { 2089 warnln("Error creating UCA collator"); 2090 } 2091 } 2092 2093 public void TestPinyinProblem() 2094 { 2095 String test[] = { "\u4E56\u4E56\u7761", "\u4E56\u5B69\u5B50" }; 2096 genericLocaleStarter(new Locale("zh", "", "PINYIN"), test); 2097 } 2098 2099 /* supercedes TestJ784 */ 2100 public void TestBeforePinyin() { 2101 String rules = 2102 "&[before 2]A << \u0101 <<< \u0100 << \u00E1 <<< \u00C1 << \u01CE <<< \u01CD << \u00E0 <<< \u00C0" + 2103 "&[before 2]e << \u0113 <<< \u0112 << \u00E9 <<< \u00C9 << \u011B <<< \u011A << \u00E8 <<< \u00C8" + 2104 "&[before 2] i << \u012B <<< \u012A << \u00ED <<< \u00CD << \u01D0 <<< \u01CF << \u00EC <<< \u00CC" + 2105 "&[before 2] o << \u014D <<< \u014C << \u00F3 <<< \u00D3 << \u01D2 <<< \u01D1 << \u00F2 <<< \u00D2" + 2106 "&[before 2]u << \u016B <<< \u016A << \u00FA <<< \u00DA << \u01D4 <<< \u01D3 << \u00F9 <<< \u00D9" + 2107 "&U << \u01D6 <<< \u01D5 << \u01D8 <<< \u01D7 << \u01DA <<< \u01D9 << \u01DC <<< \u01DB << \u00FC"; 2108 2109 String test[] = { 2110 "l\u0101", 2111 "la", 2112 "l\u0101n", 2113 "lan ", 2114 "l\u0113", 2115 "le", 2116 "l\u0113n", 2117 "len" 2118 }; 2119 2120 String test2[] = { 2121 "x\u0101", 2122 "x\u0100", 2123 "X\u0101", 2124 "X\u0100", 2125 "x\u00E1", 2126 "x\u00C1", 2127 "X\u00E1", 2128 "X\u00C1", 2129 "x\u01CE", 2130 "x\u01CD", 2131 "X\u01CE", 2132 "X\u01CD", 2133 "x\u00E0", 2134 "x\u00C0", 2135 "X\u00E0", 2136 "X\u00C0", 2137 "xa", 2138 "xA", 2139 "Xa", 2140 "XA", 2141 "x\u0101x", 2142 "x\u0100x", 2143 "x\u00E1x", 2144 "x\u00C1x", 2145 "x\u01CEx", 2146 "x\u01CDx", 2147 "x\u00E0x", 2148 "x\u00C0x", 2149 "xax", 2150 "xAx" 2151 }; 2152 /* TODO: port builder fixes to before */ 2153 genericRulesStarter(rules, test); 2154 genericLocaleStarter(new Locale("zh","",""), test); 2155 genericRulesStarter(rules, test2); 2156 genericLocaleStarter(new Locale("zh","",""), test2); 2157 } 2158 2159 public void TestUpperFirstQuaternary() 2160 { 2161 String tests[] = { "B", "b", "Bb", "bB" }; 2162 String[] att = { "strength", "UpperFirst" }; 2163 Object attVals[] = { new Integer(Collator.QUATERNARY), Boolean.TRUE }; 2164 genericLocaleStarterWithOptions(new Locale("root","",""), tests, att, attVals); 2165 } 2166 2167 public void TestJ4960() 2168 { 2169 String tests[] = { "\\u00e2T", "aT" }; 2170 String att[] = { "strength", "CaseLevel" }; 2171 Object attVals[] = { new Integer(Collator.PRIMARY), Boolean.TRUE }; 2172 String tests2[] = { "a", "A" }; 2173 String rule = "&[first tertiary ignorable]=A=a"; 2174 String att2[] = { "CaseLevel" }; 2175 Object attVals2[] = { Boolean.TRUE }; 2176 // Test whether we correctly ignore primary ignorables on case level when 2177 // we have only primary & case level 2178 genericLocaleStarterWithOptionsAndResult(new Locale("root", ""), tests, att, attVals, 0); 2179 // Test whether ICU4J will make case level for sortkeys that have primary strength 2180 // and case level 2181 genericLocaleStarterWithOptions(new Locale("root", ""), tests2, att, attVals); 2182 // Test whether completely ignorable letters have case level info (they shouldn't) 2183 genericRulesStarterWithOptionsAndResult(rule, tests2, att2, attVals2, 0); 2184 } 2185 2186 public void TestJB5298(){ 2187 ULocale[] locales = Collator.getAvailableULocales(); 2188 logln("Number of collator locales returned : " + locales.length); 2189 // double-check keywords 2190 String[] keywords = Collator.getKeywords(); 2191 if (keywords.length != 1 || !keywords[0].equals("collation")) { 2192 throw new IllegalArgumentException("internal collation error"); 2193 } 2194 2195 String[] values = Collator.getKeywordValues("collation"); 2196 log("Collator.getKeywordValues returned: "); 2197 for(int i=0; i<values.length;i++){ 2198 log(values[i]+", "); 2199 } 2200 logln(""); 2201 logln("Number of collation keyword values returned : " + values.length); 2202 for(int i=0; i<values.length;i++){ 2203 if (values[i].startsWith("private-")) { 2204 errln("Collator.getKeywordValues() returns private collation keyword: " + values[i]); 2205 } 2206 } 2207 2208 Set foundValues = new TreeSet(Arrays.asList(values)); 2209 2210 for (int i = 0; i < locales.length; ++i) { 2211 for (int j = 0; j < values.length; ++j) { 2212 ULocale tryLocale = values[j].equals("standard") 2213 ? locales[i] : new ULocale(locales[i] + "@collation=" + values[j]); 2214 // only append if not standard 2215 ULocale canon = Collator.getFunctionalEquivalent("collation",tryLocale); 2216 if (!canon.equals(tryLocale)) { 2217 continue; // has a different 2218 }else {// functional equivalent, so skip 2219 logln(tryLocale + " : "+canon+", "); 2220 } 2221 String can = canon.toString(); 2222 int idx = can.indexOf("@collation="); 2223 String val = idx >= 0 ? can.substring(idx+11, can.length()) : ""; 2224 if(val.length()>0 && !foundValues.contains(val)){ 2225 errln("Unknown collation found "+ can); 2226 } 2227 } 2228 } 2229 logln(" "); 2230 } 2231 2232 public void 2233 TestJ5367() 2234 { 2235 String[] test = { "a", "y" }; 2236 String rules = "&Ny << Y &[first secondary ignorable] <<< a"; 2237 genericRulesStarter(rules, test); 2238 } 2239 2240 public void 2241 TestVI5913() 2242 { 2243 2244 String rules[] = { 2245 "&a < \u00e2 <<< \u00c2", 2246 "&a < \u1FF3 ", // OMEGA WITH YPOGEGRAMMENI 2247 "&s < \u0161 ", // &s < s with caron 2248 /* 2249 * Note: Just tailoring &z<ae^ does not work as expected: 2250 * The UCA spec requires for discontiguous contractions that they 2251 * extend an *existing match* by one combining mark at a time. 2252 * Therefore, ae must be a contraction so that the builder finds 2253 * discontiguous contractions for ae^, for example with an intervening underdot. 2254 * Only then do we get the expected tail closure with a\u1EC7, a\u1EB9\u0302, etc. 2255 */ 2256 "&x < ae &z < a\u00EA", // &x < ae &z < a+e with circumflex 2257 }; 2258 String cases[][] = { 2259 { "\u1EAC", "A\u0323\u0302", "\u1EA0\u0302", "\u00C2\u0323", }, 2260 { "\u1FA2", "\u03C9\u0313\u0300\u0345", "\u1FF3\u0313\u0300", 2261 "\u1F60\u0300\u0345", "\u1f62\u0345", "\u1FA0\u0300", }, 2262 { "\u1E63\u030C", "s\u0323\u030C", "s\u030C\u0323"}, 2263 { "a\u1EC7", // a+ e with dot below and circumflex 2264 "a\u1EB9\u0302", // a + e with dot below + combining circumflex 2265 "a\u00EA\u0323", // a + e with circumflex + combining dot below 2266 } 2267 }; 2268 2269 2270 for(int i = 0; i < rules.length; i++) { 2271 2272 RuleBasedCollator coll = null; 2273 try { 2274 coll = new RuleBasedCollator(rules[i]); 2275 } catch (Exception e) { 2276 warnln("Unable to open collator with rules " + rules[i]); 2277 } 2278 2279 logln("Test case["+i+"]:"); 2280 CollationKey expectingKey = coll.getCollationKey(cases[i][0]); 2281 for (int j=1; j<cases[i].length; j++) { 2282 CollationKey key = coll.getCollationKey(cases[i][j]); 2283 if ( key.compareTo(expectingKey)!=0) { 2284 errln("Error! Test case["+i+"]:"+"source:" + key.getSourceString()); 2285 errln("expecting:"+CollationTest.prettify(expectingKey)+ "got:"+ CollationTest.prettify(key)); 2286 } 2287 logln(" Key:"+ CollationTest.prettify(key)); 2288 } 2289 } 2290 2291 2292 RuleBasedCollator vi_vi = null; 2293 try { 2294 vi_vi = (RuleBasedCollator)Collator.getInstance( 2295 new Locale("vi", "")); 2296 logln("VI sort:"); 2297 CollationKey expectingKey = vi_vi.getCollationKey(cases[0][0]); 2298 for (int j=1; j<cases[0].length; j++) { 2299 CollationKey key = vi_vi.getCollationKey(cases[0][j]); 2300 if ( key.compareTo(expectingKey)!=0) { 2301 // TODO (claireho): change the logln to errln after vi.res is up-to-date. 2302 // errln("source:" + key.getSourceString()); 2303 // errln("expecting:"+prettify(expectingKey)+ "got:"+ prettify(key)); 2304 logln("Error!! in Vietnese sort - source:" + key.getSourceString()); 2305 logln("expecting:"+CollationTest.prettify(expectingKey)+ "got:"+ CollationTest.prettify(key)); 2306 } 2307 // logln("source:" + key.getSourceString()); 2308 logln(" Key:"+ CollationTest.prettify(key)); 2309 } 2310 } catch (Exception e) { 2311 warnln("Error creating Vietnese collator"); 2312 return; 2313 } 2314 2315 } 2316 2317 2318 public void Test6179() 2319 { 2320 String rules[] = { 2321 "&[last primary ignorable]<< a &[first primary ignorable]<<b ", 2322 "&[last secondary ignorable]<<< a &[first secondary ignorable]<<<b", 2323 }; 2324 // defined in UCA5.1 2325 String firstPrimIgn = "\u0332"; 2326 String lastPrimIgn = "\uD800\uDDFD"; 2327 String firstVariable = "\u0009"; 2328 byte[] secIgnKey = {1,1,4,0}; 2329 2330 int i=0; 2331 { 2332 2333 RuleBasedCollator coll = null; 2334 try { 2335 coll = new RuleBasedCollator(rules[i]); 2336 } catch (Exception e) { 2337 warnln("Unable to open collator with rules " + rules[i] + ": " + e); 2338 return; 2339 } 2340 2341 logln("Test rule["+i+"]"+rules[i]); 2342 2343 CollationKey keyA = coll.getCollationKey("a"); 2344 logln("Key for \"a\":"+ CollationTest.prettify(keyA)); 2345 if (keyA.compareTo(coll.getCollationKey(lastPrimIgn))<=0) { 2346 CollationKey key = coll.getCollationKey(lastPrimIgn); 2347 logln("Collation key for 0xD800 0xDDFD: "+CollationTest.prettify(key)); 2348 errln("Error! String \"a\" must be greater than \uD800\uDDFD -"+ 2349 "[Last Primary Ignorable]"); 2350 } 2351 if (keyA.compareTo(coll.getCollationKey(firstVariable))>=0) { 2352 CollationKey key = coll.getCollationKey(firstVariable); 2353 logln("Collation key for 0x0009: "+CollationTest.prettify(key)); 2354 errln("Error! String \"a\" must be less than 0x0009 - [First Variable]"); 2355 } 2356 CollationKey keyB = coll.getCollationKey("b"); 2357 logln("Key for \"b\":"+ CollationTest.prettify(keyB)); 2358 if (keyB.compareTo(coll.getCollationKey(firstPrimIgn))<=0) { 2359 CollationKey key = coll.getCollationKey(firstPrimIgn); 2360 logln("Collation key for 0x0332: "+CollationTest.prettify(key)); 2361 errln("Error! String \"b\" must be greater than 0x0332 -"+ 2362 "[First Primary Ignorable]"); 2363 } 2364 if (keyB.compareTo(coll.getCollationKey(firstVariable))>=0) { 2365 CollationKey key = coll.getCollationKey(firstVariable); 2366 logln("Collation key for 0x0009: "+CollationTest.prettify(key)); 2367 errln("Error! String \"b\" must be less than 0x0009 - [First Variable]"); 2368 } 2369 } 2370 { 2371 i=1; 2372 RuleBasedCollator coll = null; 2373 try { 2374 coll = new RuleBasedCollator(rules[i]); 2375 } catch (Exception e) { 2376 warnln("Unable to open collator with rules " + rules[i]); 2377 } 2378 2379 logln("Test rule["+i+"]"+rules[i]); 2380 2381 CollationKey keyA = coll.getCollationKey("a"); 2382 logln("Key for \"a\":"+ CollationTest.prettify(keyA)); 2383 byte[] keyAInBytes = keyA.toByteArray(); 2384 for (int j=0; j<keyAInBytes.length && j<secIgnKey.length; j++) { 2385 if (keyAInBytes[j]!=secIgnKey[j]) { 2386 if ((char)keyAInBytes[j]<=(char)secIgnKey[j]) { 2387 logln("Error! String \"a\" must be greater than [Last Secondary Ignorable]"); 2388 } 2389 break; 2390 } 2391 } 2392 if (keyA.compareTo(coll.getCollationKey(firstVariable))>=0) { 2393 errln("Error! String \"a\" must be less than 0x0009 - [First Variable]"); 2394 CollationKey key = coll.getCollationKey(firstVariable); 2395 logln("Collation key for 0x0009: "+CollationTest.prettify(key)); 2396 } 2397 CollationKey keyB = coll.getCollationKey("b"); 2398 logln("Key for \"b\":"+ CollationTest.prettify(keyB)); 2399 byte[] keyBInBytes = keyB.toByteArray(); 2400 for (int j=0; j<keyBInBytes.length && j<secIgnKey.length; j++) { 2401 if (keyBInBytes[j]!=secIgnKey[j]) { 2402 if ((char)keyBInBytes[j]<=(char)secIgnKey[j]) { 2403 errln("Error! String \"b\" must be greater than [Last Secondary Ignorable]"); 2404 } 2405 break; 2406 } 2407 } 2408 if (keyB.compareTo(coll.getCollationKey(firstVariable))>=0) { 2409 CollationKey key = coll.getCollationKey(firstVariable); 2410 logln("Collation key for 0x0009: "+CollationTest.prettify(key)); 2411 errln("Error! String \"b\" must be less than 0x0009 - [First Variable]"); 2412 } 2413 } 2414 } 2415 2416 public void TestUCAPrecontext() 2417 { 2418 String rules[] = { 2419 "& \u00B7<a ", 2420 "& L\u00B7 << a", // 'a' is an expansion. 2421 }; 2422 String cases[] = { 2423 "\u00B7", 2424 "\u0387", 2425 "a", 2426 "l", 2427 "L\u0332", 2428 "l\u00B7", 2429 "l\u0387", 2430 "L\u0387", 2431 "la\u0387", 2432 "La\u00b7", 2433 }; 2434 2435 // Test en sort 2436 RuleBasedCollator en = null; 2437 2438 logln("EN sort:"); 2439 try { 2440 en = (RuleBasedCollator)Collator.getInstance( 2441 new Locale("en", "")); 2442 for (int j=0; j<cases.length; j++) { 2443 CollationKey key = en.getCollationKey(cases[j]); 2444 if (j>0) { 2445 CollationKey prevKey = en.getCollationKey(cases[j-1]); 2446 if (key.compareTo(prevKey)<0) { 2447 errln("Error! EN test["+j+"]:source:" + cases[j]+ 2448 " is not >= previous test string."); 2449 } 2450 } 2451 /* 2452 if ( key.compareTo(expectingKey)!=0) { 2453 errln("Error! Test case["+i+"]:"+"source:" + key.getSourceString()); 2454 errln("expecting:"+prettify(expectingKey)+ "got:"+ prettify(key)); 2455 } 2456 */ 2457 logln("String:"+cases[j]+" Key:"+ CollationTest.prettify(key)); 2458 } 2459 } catch (Exception e) { 2460 warnln("Error creating English collator"); 2461 return; 2462 } 2463 2464 // Test ja sort 2465 RuleBasedCollator ja = null; 2466 logln("JA sort:"); 2467 try { 2468 ja = (RuleBasedCollator)Collator.getInstance( 2469 new Locale("ja", "")); 2470 for (int j=0; j<cases.length; j++) { 2471 CollationKey key = ja.getCollationKey(cases[j]); 2472 if (j>0) { 2473 CollationKey prevKey = ja.getCollationKey(cases[j-1]); 2474 if (key.compareTo(prevKey)<0) { 2475 errln("Error! JA test["+j+"]:source:" + cases[j]+ 2476 " is not >= previous test string."); 2477 } 2478 } 2479 logln("String:"+cases[j]+" Key:"+ CollationTest.prettify(key)); 2480 } 2481 } catch (Exception e) { 2482 warnln("Error creating Japanese collator"); 2483 return; 2484 } 2485 for(int i = 0; i < rules.length; i++) { 2486 2487 RuleBasedCollator coll = null; 2488 logln("Tailoring rule:"+rules[i]); 2489 try { 2490 coll = new RuleBasedCollator(rules[i]); 2491 } catch (Exception e) { 2492 warnln("Unable to open collator with rules " + rules[i]); 2493 continue; 2494 } 2495 2496 for (int j=0; j<cases.length; j++) { 2497 CollationKey key = coll.getCollationKey(cases[j]); 2498 if (j>0) { 2499 CollationKey prevKey = coll.getCollationKey(cases[j-1]); 2500 if (i==1 && j==3) { 2501 if (key.compareTo(prevKey)>0) { 2502 errln("Error! Rule:"+rules[i]+" test["+j+"]:source:"+ 2503 cases[j]+" is not <= previous test string."); 2504 } 2505 } 2506 else { 2507 if (key.compareTo(prevKey)<0) { 2508 errln("Error! Rule:"+rules[i]+" test["+j+"]:source:"+ 2509 cases[j]+" is not >= previous test string."); 2510 } 2511 } 2512 } 2513 logln("String:"+cases[j]+" Key:"+ CollationTest.prettify(key)); 2514 } 2515 } 2516 } 2517 2518 2519 /** 2520 * Stores a test case for collation testing. 2521 */ 2522 private class OneTestCase { 2523 /** The first value to compare. **/ 2524 public String m_source_; 2525 2526 /** The second value to compare. **/ 2527 public String m_target_; 2528 2529 /** 2530 * 0 if the two values sort equal, 2531 * -1 if the first value sorts before the second 2532 * 1 if the first value sorts after the first 2533 */ 2534 public int m_result_; 2535 2536 public OneTestCase(String source, String target, int result) { 2537 m_source_ = source; 2538 m_target_ = target; 2539 m_result_ = result; 2540 } 2541 } 2542 2543 /** 2544 * Convenient function to test collation rules. 2545 * @param testCases 2546 * @param rules Collation rules in ICU format. All the strings in this 2547 * array represent the same rule, expressed in different forms. 2548 */ 2549 private void doTestCollation( 2550 OneTestCase[] testCases, String[] rules) { 2551 2552 Collator myCollation; 2553 for (String rule : rules) { 2554 try { 2555 myCollation = new RuleBasedCollator(rule); 2556 } catch (Exception e) { 2557 warnln("ERROR: in creation of rule based collator: " + e); 2558 return; 2559 } 2560 2561 myCollation.setDecomposition(Collator.CANONICAL_DECOMPOSITION); 2562 myCollation.setStrength(Collator.TERTIARY); 2563 for (OneTestCase testCase : testCases) { 2564 CollationTest.doTest(this, (RuleBasedCollator)myCollation, 2565 testCase.m_source_, 2566 testCase.m_target_, 2567 testCase.m_result_); 2568 } 2569 } 2570 } 2571 2572 // Test cases to check whether the rules equivalent to 2573 // "&a<b<c<d &b<<k<<l<<m &k<<<x<<<y<<<z &a=1=2=3" are working fine. 2574 private OneTestCase[] m_rangeTestCases_ = { 2575 // Left Right Result 2576 new OneTestCase( "\u0061", "\u0062", -1 ), // "a" < "b" 2577 new OneTestCase( "\u0062", "\u0063", -1 ), // "b" < "c" 2578 new OneTestCase( "\u0061", "\u0063", -1 ), // "a" < "c" 2579 2580 new OneTestCase( "\u0062", "\u006b", -1 ), // "b" << "k" 2581 new OneTestCase( "\u006b", "\u006c", -1 ), // "k" << "l" 2582 new OneTestCase( "\u0062", "\u006c", -1 ), // "b" << "l" 2583 new OneTestCase( "\u0061", "\u006c", -1 ), // "a" << "l" 2584 new OneTestCase( "\u0061", "\u006d", -1 ), // "a" << "m" 2585 2586 new OneTestCase( "\u0079", "\u006d", -1 ), // "y" < "f" 2587 new OneTestCase( "\u0079", "\u0067", -1 ), // "y" < "g" 2588 new OneTestCase( "\u0061", "\u0068", -1 ), // "y" < "h" 2589 new OneTestCase( "\u0061", "\u0065", -1 ), // "g" < "e" 2590 2591 new OneTestCase( "\u0061", "\u0031", 0 ), // "a" == "1" 2592 new OneTestCase( "\u0061", "\u0032", 0 ), // "a" == "2" 2593 new OneTestCase( "\u0061", "\u0033", 0 ), // "a" == "3" 2594 new OneTestCase( "\u0061", "\u0066", -1 ), // "a" < "f", 2595 new OneTestCase( "\u006c\u0061", "\u006b\u0062", -1 ), // "la" < "kb" 2596 new OneTestCase( "\u0061\u0061\u0061", "\u0031\u0032\u0033", 0 ), // "aaa" == "123" 2597 new OneTestCase( "\u0062", "\u007a", -1 ), // "b" < "z" 2598 new OneTestCase( "\u0061\u007a\u0062", "\u0032\u0079\u006d", -1 ), // "azm" < "2yc" 2599 }; 2600 2601 // Test cases to check whether the rules equivalent to 2602 // "&\ufffe<\uffff<\U00010000<\U00010001<\U00010002 2603 // &\U00010000<<\U00020001<<\U00020002<<\U00020002 2604 // &\U00020001=\U0003001=\U0004001=\U0004002 2605 // &\U00040008<\U00030008<\UU00020008" 2606 // are working fine. 2607 private OneTestCase[] m_rangeTestCasesSupplemental_ = { 2608 // Left Right Result 2609 new OneTestCase( "\u4e00", "\ufffb", -1 ), 2610 new OneTestCase( "\ufffb", "\ud800\udc00", -1 ), // U+FFFB < U+10000 2611 new OneTestCase( "\ud800\udc00", "\ud800\udc01", -1 ), // U+10000 < U+10001 2612 2613 new OneTestCase( "\u4e00", "\ud800\udc01", -1 ), // U+4E00 < U+10001 2614 new OneTestCase( "\ud800\udc01", "\ud800\udc02", -1 ), // U+10001 < U+10002 2615 new OneTestCase( "\ud800\udc00", "\ud840\udc02", -1 ), // U+10000 < U+10002 2616 new OneTestCase( "\u4e00", "\u0d840\udc02", -1 ), // U+4E00 < U+10002 2617 2618 }; 2619 2620 // Test cases in disjoint random code points. To test only the compact syntax. 2621 // Rule: &q<w<e<r &w<<t<<y<<u &t<<<i<<<o<<<p &o=a=s=d 2622 private OneTestCase[] m_qwertCollationTestCases_ = { 2623 new OneTestCase("q", "w" , -1), 2624 new OneTestCase("w", "e" , -1), 2625 2626 new OneTestCase("y", "u" , -1), 2627 new OneTestCase("q", "u" , -1), 2628 2629 new OneTestCase("t", "i" , -1), 2630 new OneTestCase("o", "p" , -1), 2631 2632 new OneTestCase("y", "e" , -1), 2633 new OneTestCase("i", "u" , -1), 2634 2635 new OneTestCase("quest", "were" , -1), 2636 new OneTestCase("quack", "quest", -1) 2637 }; 2638 2639 // Tests the compact list with ASCII codepoints. 2640 public void TestSameStrengthList() { 2641 String[] rules = new String[] { 2642 // Normal 2643 "&a<b<c<d &b<<k<<l<<m &k<<<x<<<y<<<z &y<f<g<h<e &a=1=2=3", 2644 2645 // Lists 2646 "&a<*bcd &b<<*klm &k<<<*xyz &y<*fghe &a=*123", 2647 2648 // Lists with quoted characters 2649 "&'\u0061'<*bcd &b<<*klm &k<<<*xyz &y<*f'\u0067\u0068'e &a=*123", 2650 }; 2651 doTestCollation(m_rangeTestCases_, rules); 2652 } 2653 2654 public void TestSameStrengthListQuoted() { 2655 String[] rules = new String[] { 2656 "&'\u0061'<*bcd &b<<*klm &k<<<*xyz &y<*f'\u0067\u0068'e &a=1=2=3", 2657 "&'\u0061'<*b'\u0063'd &b<<*klm &k<<<*xyz &'\u0079'<*fgh'\u0065' " + 2658 "&a=*'\u0031\u0032\u0033'", 2659 2660 "&'\u0061'<*'\u0062'c'\u0064' &b<<*klm &k<<<*xyz &y<*fghe " + 2661 "&a=*'\u0031\u0032\u0033'", 2662 }; 2663 doTestCollation(m_rangeTestCases_, rules); 2664 } 2665 2666 // Tests the compact list with ASCII codepoints in non-codepoint order. 2667 public void TestSameStrengthListQwerty() { 2668 String[] rules = new String[] { 2669 "&q<w<e<r &w<<t<<y<<u &t<<<i<<<o<<<p &o=a=s=d", // Normal 2670 "&q<*wer &w<<*tyu &t<<<*iop &o=*asd", // Lists 2671 }; 2672 2673 doTestCollation(m_qwertCollationTestCases_, rules); 2674 } 2675 2676 // Tests the compact list with supplemental codepoints. 2677 public void TestSameStrengthListWithSupplementalCharacters() { 2678 String[] rules = new String[] { 2679 // ** Rule without compact list syntax ** 2680 // \u4e00 < \ufffb < \U00010000 < \U00010001 < \U00010002 2681 "&\u4e00<\ufffb<'\ud800\udc00'<'\ud800\udc01'<'\ud800\udc02' " + 2682 // \U00010000 << \U00020001 << \U00020002 \U00020002 2683 "&'\ud800\udc00'<<'\ud840\udc01'<<'\ud840\udc02'<<'\ud840\udc02' " + 2684 // \U00020001 = \U0003001 = \U0004001 = \U0004002 2685 "&'\ud840\udc01'='\ud880\udc01'='\ud8c0\udc01'='\ud8c0\udc02'", 2686 2687 // ** Rule with compact list syntax ** 2688 // \u4e00 <* \ufffb\U00010000 \U00010001 2689 "&\u4e00<*'\ufffb\ud800\udc00\ud800\udc01\ud800\udc02' " + 2690 // \U00010000 <<* \U00020001 \U00020002 2691 "&'\ud800\udc00'<<*'\ud840\udc01\ud840\udc02\ud840\udc03' " + 2692 // \U00020001 =* \U0003001 \U0003002 \U0003003 \U0004001 2693 "&'\ud840\udc01'=*'\ud880\udc01\ud880\udc02\ud880\udc03\ud8c0\udc01' " 2694 2695 }; 2696 doTestCollation(m_rangeTestCasesSupplemental_, rules); 2697 } 2698 2699 2700 // Tests the compact range syntax with ASCII codepoints. 2701 public void TestSameStrengthListRanges() { 2702 String[] rules = new String[] { 2703 // Ranges 2704 "&a<*b-d &b<<*k-m &k<<<*x-z &y<*f-he &a=*1-3", 2705 2706 // Ranges with quoted characters 2707 "&'\u0061'<*'\u0062'-'\u0064' &b<<*klm &k<<<*xyz " + 2708 "&'\u0079'<*'\u0066'-'\u0068e' &a=*123", 2709 "&'\u0061'<*'\u0062'-'\u0064' " + 2710 "&b<<*'\u006B'-m &k<<<*x-'\u007a' " + 2711 "&'\u0079'<*'\u0066'-h'\u0065' &a=*'\u0031\u0032\u0033'", 2712 }; 2713 2714 doTestCollation(m_rangeTestCases_, rules); 2715 } 2716 2717 // Tests the compact range syntax with supplemental codepoints. 2718 public void TestSameStrengthListRangesWithSupplementalCharacters() { 2719 String[] rules = new String[] { 2720 // \u4e00 <* \ufffb\U00010000 \U00010001 2721 "&\u4e00<*'\ufffb'\ud800\udc00-'\ud800\udc02' " + 2722 // \U00010000 <<* \U00020001 - \U00020003 2723 "&'\ud800\udc00'<<*'\ud840\udc01'-'\ud840\udc03' " + 2724 // \U00020001 =* \U0003001 \U0004001 2725 "&'\ud840\udc01'=*'\ud880\udc01'-'\ud880\udc03\ud8c0\udc01' " 2726 }; 2727 doTestCollation(m_rangeTestCasesSupplemental_, rules); 2728 } 2729 2730 // Tests the compact range syntax with special characters used as syntax characters in rules. 2731 public void TestSpecialCharacters() { 2732 String rules[] = new String[] { 2733 // Normal 2734 "&';'<'+'<','<'-'<'&'<'*'", 2735 2736 // List 2737 "&';'<*'+,-&*'", 2738 2739 // Range 2740 "&';'<*'+'-'-&*'", 2741 2742 "&'\u003b'<'\u002b'<'\u002c'<'\u002d'<'\u0026'<'\u002a'", 2743 2744 "&'\u003b'<*'\u002b\u002c\u002d\u0026\u002a'", 2745 "&'\u003b'<*'\u002b\u002c\u002d\u0026\u002a'", 2746 "&'\u003b'<*'\u002b'-'\u002d\u0026\u002a'", 2747 "&'\u003b'<*'\u002b'-'\u002d\u0026\u002a'", 2748 }; 2749 OneTestCase[] testCases = new OneTestCase[] { 2750 new OneTestCase("\u003b", "\u002b", -1), // ; < + 2751 new OneTestCase("\u002b", "\u002c", -1), // + < , 2752 new OneTestCase("\u002c", "\u002d", -1), // , < - 2753 new OneTestCase("\u002d", "\u0026", -1), // - < & 2754 }; 2755 doTestCollation(testCases, rules); 2756 } 2757 2758 public void TestInvalidListsAndRanges() { 2759 String[] invalidRules = new String[] { 2760 // Range not in starred expression 2761 "&\u4e00<\ufffb-'\ud800\udc02'", 2762 2763 // Range without start 2764 "&a<*-c", 2765 2766 // Range without end 2767 "&a<*b-", 2768 2769 // More than one hyphen 2770 "&a<*b-g-l", 2771 2772 // Range in the wrong order 2773 "&a<*k-b", 2774 }; 2775 for (String rule : invalidRules) { 2776 try { 2777 Collator myCollation = new RuleBasedCollator(rule); 2778 warnln("ERROR: Creation of collator didn't fail for " + rule + " when it should."); 2779 CollationTest.doTest(this, (RuleBasedCollator)myCollation, 2780 "x", 2781 "y", 2782 -1); 2783 2784 } catch (Exception e) { 2785 continue; 2786 } 2787 throw new IllegalArgumentException("ERROR: Invalid collator with rule " + rule + " worked fine."); 2788 } 2789 } 2790 2791 // This is the same example above with ' and space added. 2792 // They work a little different than expected. Desired rules are commented out. 2793 public void TestQuoteAndSpace() { 2794 String rules[] = new String[] { 2795 // These are working as expected. 2796 "&';'<'+'<','<'-'<'&'<''<'*'<' '", 2797 2798 // List. Desired rule is 2799 // "&';'<*'+,-&''* '", 2800 // but it doesn't work. Instead, '' should be outside quotes as below. 2801 "&';'<*'+,-&''''* '", 2802 2803 // Range. Similar issues here as well. The following are working. 2804 //"&';'<*'+'-'-&''* '", 2805 //"&';'<*'+'-'-&'\\u0027'* '", 2806 "&';'<*'+'-'-&''''* '", 2807 //"&';'<*'+'-'-&'\\u0027'* '", 2808 2809 // The following rules are not working. 2810 // "&';'<'+'<','<'-'<'&'<\\u0027<'*'<' '", 2811 //"&'\u003b'<'\u002b'<'\u002c'<'\u002d'<'\u0026'<'\u0027'<\u002a'<'\u0020'", 2812 //"&'\u003b'<'\u002b'<'\u002c'<'\u002d'<'\u0026'<\\u0027<\u002a'<'\u0020'", 2813 }; 2814 2815 OneTestCase[] testCases = new OneTestCase[] { 2816 new OneTestCase("\u003b", "\u002b", -1), // ; < , 2817 new OneTestCase("\u002b", "\u002c", -1), // ; < , 2818 new OneTestCase("\u002c", "\u002d", -1), // , < - 2819 new OneTestCase("\u002d", "\u0026", -1), // - < & 2820 new OneTestCase("\u0026", "\u0027", -1), // & < ' 2821 new OneTestCase("\u0027", "\u002a", -1), // ' < * 2822 // new OneTestCase("\u002a", "\u0020", -1), // * < <space> 2823 }; 2824 doTestCollation(testCases, rules); 2825 } 2826 2827 /* 2828 * Tests the method public boolean equals(Object target) in CollationKey 2829 */ 2830 public void TestCollationKeyEquals() { 2831 CollationKey ck = new CollationKey("", (byte[]) null); 2832 2833 // Tests when "if (!(target instanceof CollationKey))" is true 2834 if (ck.equals(new Object())) { 2835 errln("CollationKey.equals() was not suppose to return false " 2836 + "since it is comparing to a non Collation Key object."); 2837 } 2838 if (ck.equals("")) { 2839 errln("CollationKey.equals() was not suppose to return false " 2840 + "since it is comparing to a non Collation Key object."); 2841 } 2842 if (ck.equals(0)) { 2843 errln("CollationKey.equals() was not suppose to return false " 2844 + "since it is comparing to a non Collation Key object."); 2845 } 2846 if (ck.equals(0.0)) { 2847 errln("CollationKey.equals() was not suppose to return false " 2848 + "since it is comparing to a non Collation Key object."); 2849 } 2850 2851 // Tests when "if (target == null)" is true 2852 if (ck.equals((CollationKey) null)) { 2853 errln("CollationKey.equals() was not suppose to return false " 2854 + "since it is comparing to a null Collation Key object."); 2855 } 2856 } 2857 2858 /* 2859 * Tests the method public int hashCode() in CollationKey 2860 */ 2861 public void TestCollationKeyHashCode() { 2862 CollationKey ck = new CollationKey("", (byte[]) null); 2863 2864 // Tests when "if (m_key_ == null)" is true 2865 if (ck.hashCode() != 1) { 2866 errln("CollationKey.hashCode() was suppose to return 1 " 2867 + "when m_key is null due a null parameter in the " + "constructor."); 2868 } 2869 } 2870 2871 /* 2872 * Tests the method public CollationKey getBound(int boundType, int noOfLevels) 2873 */ 2874 public void TestGetBound() { 2875 CollationKey ck = new CollationKey("", (byte[]) null); 2876 2877 // Tests when "if (noOfLevels > Collator.PRIMARY)" is false 2878 // Tests when "default: " is true for "switch (boundType)" 2879 try { 2880 ck.getBound(BoundMode.COUNT, -1); 2881 errln("CollationKey.getBound(int,int) was suppose to return an " 2882 + "exception for an invalid boundType value."); 2883 } catch (Exception e) { 2884 } 2885 2886 // Tests when "if (noOfLevels > 0)" 2887 byte b[] = {}; 2888 CollationKey ck1 = new CollationKey("", b); 2889 try { 2890 ck1.getBound(0, 1); 2891 errln("CollationKey.getBound(int,int) was suppose to return an " 2892 + "exception a value of noOfLevels that exceeds expected."); 2893 } catch (Exception e) { 2894 } 2895 } 2896 2897 /* 2898 * Tests the method public CollationKey merge(CollationKey source) 2899 */ 2900 public void TestMerge() { 2901 byte b[] = {}; 2902 CollationKey ck = new CollationKey("", b); 2903 2904 // Tests when "if (source == null || source.getLength() == 0)" is true 2905 try { 2906 ck.merge(null); 2907 errln("Collationkey.merge(CollationKey) was suppose to return " + "an exception for a null parameter."); 2908 } catch (Exception e) { 2909 } 2910 try { 2911 ck.merge(ck); 2912 errln("Collationkey.merge(CollationKey) was suppose to return " + "an exception for a null parameter."); 2913 } catch (Exception e) { 2914 } 2915 } 2916 2917 /* Test the method public int compareTo(RawCollationKey rhs) */ 2918 public void TestRawCollationKeyCompareTo(){ 2919 RawCollationKey rck = new RawCollationKey(); 2920 byte[] b = {(byte) 10, (byte) 20}; 2921 RawCollationKey rck100 = new RawCollationKey(b, 2); 2922 2923 if(rck.compareTo(rck) != 0){ 2924 errln("RawCollatonKey.compareTo(RawCollationKey) was suppose to return 0 " + 2925 "for two idential RawCollationKey objects."); 2926 } 2927 2928 if(rck.compareTo(rck100) == 0){ 2929 errln("RawCollatonKey.compareTo(RawCollationKey) was not suppose to return 0 " + 2930 "for two different RawCollationKey objects."); 2931 } 2932 } 2933 2934 /* Track7223: CollationElementIterator does not return correct order for Hungarian */ 2935 public void TestHungarianTailoring(){ 2936 String rules = new String("&DZ<dzs<<<Dzs<<<DZS" + 2937 "&G<gy<<<Gy<<<GY" + 2938 "&L<ly<<<Ly<<<LY" + 2939 "&N<ny<<<Ny<<<NY" + 2940 "&S<sz<<<Sz<<<SZ" + 2941 "&T<ty<<<Ty<<<TY" + 2942 "&Z<zs<<<Zs<<<ZS" + 2943 "&O<\u00f6<<<\u00d6<<\u0151<<<\u0150" + 2944 "&U<\u00fc<<<\u00dc<<\u0171<<<\u0171" + 2945 "&cs<<<ccs/cs" + 2946 "&Cs<<<Ccs/cs" + 2947 "&CS<<<CCS/CS" + 2948 "&dz<<<ddz/dz" + 2949 "&Dz<<<Ddz/dz" + 2950 "&DZ<<<DDZ/DZ" + 2951 "&dzs<<<ddzs/dzs" + 2952 "&Dzs<<<Ddzs/dzs" + 2953 "&DZS<<<DDZS/DZS" + 2954 "&gy<<<ggy/gy" + 2955 "&Gy<<<Ggy/gy" + 2956 "&GY<<<GGY/GY"); 2957 RuleBasedCollator coll; 2958 try { 2959 String str1 = "ggy"; 2960 String str2 = "GGY"; 2961 coll = new RuleBasedCollator(rules); 2962 if (coll.compare("ggy", "GGY") >= 0) { 2963 errln("TestHungarianTailoring.compare(" + str1 + ","+ str2 + 2964 ") was suppose to return -1 "); 2965 } 2966 CollationKey sortKey1 = coll.getCollationKey(str1); 2967 CollationKey sortKey2 = coll.getCollationKey(str2); 2968 if (sortKey1.compareTo(sortKey2) >= 0) { 2969 errln("TestHungarianTailoring getCollationKey(\"" + str1 +"\") was suppose "+ 2970 "less than getCollationKey(\""+ str2 + "\")."); 2971 errln(" getCollationKey(\"ggy\"):" + CollationTest.prettify(sortKey1) + 2972 " getCollationKey(\"GGY\"):" + CollationTest.prettify(sortKey2)); 2973 } 2974 2975 CollationElementIterator iter1 = coll.getCollationElementIterator(str1); 2976 CollationElementIterator iter2 = coll.getCollationElementIterator(str2); 2977 int ce1, ce2; 2978 while((ce1 = iter1.next()) != CollationElementIterator.NULLORDER && 2979 (ce2 = iter2.next()) != CollationElementIterator.NULLORDER) { 2980 if (ce1 > ce2) { 2981 errln("TestHungarianTailoring.CollationElementIterator(" + str1 + 2982 ","+ str2 + ") was suppose to return -1 "); 2983 } 2984 } 2985 } catch (Exception e) { 2986 e.printStackTrace(); 2987 } 2988 } 2989 2990 public void TestImport(){ 2991 try{ 2992 RuleBasedCollator vicoll = (RuleBasedCollator)Collator.getInstance(new ULocale("vi")); 2993 RuleBasedCollator escoll = (RuleBasedCollator)Collator.getInstance(new ULocale("es")); 2994 RuleBasedCollator viescoll = new RuleBasedCollator(vicoll.getRules() + escoll.getRules()); 2995 RuleBasedCollator importviescoll = new RuleBasedCollator("[import vi][import es]"); 2996 2997 UnicodeSet tailoredSet = viescoll.getTailoredSet(); 2998 UnicodeSet importTailoredSet = importviescoll.getTailoredSet(); 2999 3000 if(!tailoredSet.equals(importTailoredSet)){ 3001 warnln("Tailored set not equal"); 3002 } 3003 3004 for (UnicodeSetIterator it = new UnicodeSetIterator(tailoredSet); it.next();) { 3005 String t = it.getString(); 3006 CollationKey sk1 = viescoll.getCollationKey(t); 3007 CollationKey sk2 = importviescoll.getCollationKey(t); 3008 if(!sk1.equals(sk2)){ 3009 warnln("Collation key's not equal for " + t); 3010 } 3011 } 3012 3013 }catch(Exception e){ 3014 warnln("ERROR: in creation of rule based collator"); 3015 } 3016 } 3017 3018 public void TestImportWithType(){ 3019 try{ 3020 RuleBasedCollator vicoll = (RuleBasedCollator)Collator.getInstance(new ULocale("vi")); 3021 RuleBasedCollator decoll = (RuleBasedCollator)Collator.getInstance(ULocale.forLanguageTag("de-u-co-phonebk")); 3022 RuleBasedCollator videcoll = new RuleBasedCollator(vicoll.getRules() + decoll.getRules()); 3023 RuleBasedCollator importvidecoll = new RuleBasedCollator("[import vi][import de-u-co-phonebk]"); 3024 3025 UnicodeSet tailoredSet = videcoll.getTailoredSet(); 3026 UnicodeSet importTailoredSet = importvidecoll.getTailoredSet(); 3027 3028 if(!tailoredSet.equals(importTailoredSet)){ 3029 warnln("Tailored set not equal"); 3030 } 3031 3032 for (UnicodeSetIterator it = new UnicodeSetIterator(tailoredSet); it.next();) { 3033 String t = it.getString(); 3034 CollationKey sk1 = videcoll.getCollationKey(t); 3035 CollationKey sk2 = importvidecoll.getCollationKey(t); 3036 if(!sk1.equals(sk2)){ 3037 warnln("Collation key's not equal for " + t); 3038 } 3039 } 3040 3041 }catch(Exception e){ 3042 warnln("ERROR: in creation of rule based collator"); 3043 } 3044 } 3045 3046 /* 3047 * This test ensures that characters placed before a character in a different script have the same lead byte 3048 * in their collation key before and after script reordering. 3049 */ 3050 public void TestBeforeRuleWithScriptReordering() throws Exception 3051 { 3052 /* build collator */ 3053 String rules = "&[before 1]\u03b1 < \u0e01"; 3054 int[] reorderCodes = {UScript.GREEK}; 3055 int result; 3056 3057 Collator myCollation = new RuleBasedCollator(rules); 3058 myCollation.setDecomposition(Collator.CANONICAL_DECOMPOSITION); 3059 myCollation.setStrength(Collator.TERTIARY); 3060 3061 String base = "\u03b1"; /* base */ 3062 String before = "\u0e01"; /* ko kai */ 3063 3064 /* check collation results - before rule applied but not script reordering */ 3065 result = myCollation.compare(base, before); 3066 if (!(result > 0)) { 3067 errln("Collation result not correct before script reordering."); 3068 } 3069 3070 /* check the lead byte of the collation keys before script reordering */ 3071 CollationKey baseKey = myCollation.getCollationKey(base); 3072 CollationKey beforeKey = myCollation.getCollationKey(before); 3073 byte[] baseKeyBytes = baseKey.toByteArray(); 3074 byte[] beforeKeyBytes = beforeKey.toByteArray(); 3075 if (baseKeyBytes[0] != beforeKeyBytes[0]) { 3076 errln("Different lead byte for sort keys using before rule and before script reordering. base character lead byte = " 3077 + baseKeyBytes[0] + ", before character lead byte = " + beforeKeyBytes[0]); 3078 } 3079 3080 /* reorder the scripts */ 3081 myCollation.setReorderCodes(reorderCodes); 3082 3083 /* check collation results - before rule applied and after script reordering */ 3084 result = myCollation.compare(base, before); 3085 if (!(result > 0)) { 3086 errln("Collation result not correct after script reordering."); 3087 } 3088 3089 /* check the lead byte of the collation keys after script reordering */ 3090 baseKey = myCollation.getCollationKey(base); 3091 beforeKey = myCollation.getCollationKey(before); 3092 baseKeyBytes = baseKey.toByteArray(); 3093 beforeKeyBytes = beforeKey.toByteArray(); 3094 if (baseKeyBytes[0] != beforeKeyBytes[0]) { 3095 errln("Different lead byte for sort keys using before rule and before script reordering. base character lead byte = " 3096 + baseKeyBytes[0] + ", before character lead byte = " + beforeKeyBytes[0]); 3097 } 3098 } 3099 3100 /* 3101 * Test that in a primary-compressed sort key all bytes except the first one are unchanged under script reordering. 3102 */ 3103 public void TestNonLeadBytesDuringCollationReordering() throws Exception 3104 { 3105 Collator myCollation; 3106 byte[] baseKey; 3107 byte[] reorderKey; 3108 int[] reorderCodes = {UScript.GREEK}; 3109 String testString = "\u03b1\u03b2\u03b3"; 3110 3111 /* build collator tertiary */ 3112 myCollation = new RuleBasedCollator(""); 3113 myCollation.setStrength(Collator.TERTIARY); 3114 baseKey = myCollation.getCollationKey(testString).toByteArray(); 3115 3116 myCollation.setReorderCodes(reorderCodes); 3117 reorderKey = myCollation.getCollationKey(testString).toByteArray(); 3118 3119 if (baseKey.length != reorderKey.length) { 3120 errln("Key lengths not the same during reordering.\n"); 3121 } 3122 3123 for (int i = 1; i < baseKey.length; i++) { 3124 if (baseKey[i] != reorderKey[i]) { 3125 errln("Collation key bytes not the same at position " + i); 3126 } 3127 } 3128 3129 /* build collator tertiary */ 3130 myCollation = new RuleBasedCollator(""); 3131 myCollation.setStrength(Collator.QUATERNARY); 3132 baseKey = myCollation.getCollationKey(testString).toByteArray(); 3133 3134 myCollation.setReorderCodes(reorderCodes); 3135 reorderKey = myCollation.getCollationKey(testString).toByteArray(); 3136 3137 if (baseKey.length != reorderKey.length) { 3138 errln("Key lengths not the same during reordering.\n"); 3139 } 3140 3141 for (int i = 1; i < baseKey.length; i++) { 3142 if (baseKey[i] != reorderKey[i]) { 3143 errln("Collation key bytes not the same at position " + i); 3144 } 3145 } 3146 } 3147 3148 /* 3149 * Test reordering API. 3150 */ 3151 public void TestReorderingAPI() throws Exception 3152 { 3153 Collator myCollation; 3154 int[] reorderCodes = {UScript.GREEK, UScript.HAN, ReorderCodes.PUNCTUATION}; 3155 int[] duplicateReorderCodes = {UScript.HIRAGANA, UScript.GREEK, ReorderCodes.CURRENCY, UScript.KATAKANA}; 3156 int[] reorderCodesStartingWithDefault = {ReorderCodes.DEFAULT, UScript.GREEK, UScript.HAN, ReorderCodes.PUNCTUATION}; 3157 int[] retrievedReorderCodes; 3158 String greekString = "\u03b1"; 3159 String punctuationString = "\u203e"; 3160 3161 /* build collator tertiary */ 3162 myCollation = new RuleBasedCollator(""); 3163 myCollation.setStrength(Collator.TERTIARY); 3164 3165 /* set the reorderding */ 3166 myCollation.setReorderCodes(reorderCodes); 3167 3168 retrievedReorderCodes = myCollation.getReorderCodes(); 3169 if (!Arrays.equals(reorderCodes, retrievedReorderCodes)) { 3170 errln("ERROR: retrieved reorder codes do not match set reorder codes."); 3171 } 3172 if (!(myCollation.compare(greekString, punctuationString) < 0)) { 3173 errln("ERROR: collation result should have been less."); 3174 } 3175 3176 /* clear the reordering */ 3177 myCollation.setReorderCodes(null); 3178 retrievedReorderCodes = myCollation.getReorderCodes(); 3179 if (retrievedReorderCodes.length != 0) { 3180 errln("ERROR: retrieved reorder codes was not null."); 3181 } 3182 3183 if (!(myCollation.compare(greekString, punctuationString) > 0)) { 3184 errln("ERROR: collation result should have been greater."); 3185 } 3186 3187 // do it again with an empty but non-null array 3188 3189 /* set the reorderding */ 3190 myCollation.setReorderCodes(reorderCodes); 3191 3192 retrievedReorderCodes = myCollation.getReorderCodes(); 3193 if (!Arrays.equals(reorderCodes, retrievedReorderCodes)) { 3194 errln("ERROR: retrieved reorder codes do not match set reorder codes."); 3195 } 3196 if (!(myCollation.compare(greekString, punctuationString) < 0)) { 3197 errln("ERROR: collation result should have been less."); 3198 } 3199 3200 /* clear the reordering */ 3201 myCollation.setReorderCodes(new int[]{}); 3202 retrievedReorderCodes = myCollation.getReorderCodes(); 3203 if (retrievedReorderCodes.length != 0) { 3204 errln("ERROR: retrieved reorder codes was not null."); 3205 } 3206 3207 if (!(myCollation.compare(greekString, punctuationString) > 0)) { 3208 errln("ERROR: collation result should have been greater."); 3209 } 3210 3211 /* clear the reordering using [NONE] */ 3212 myCollation.setReorderCodes(new int[]{ ReorderCodes.NONE }); 3213 retrievedReorderCodes = myCollation.getReorderCodes(); 3214 if (retrievedReorderCodes.length != 0) { 3215 errln("ERROR: [NONE] retrieved reorder codes was not null."); 3216 } 3217 3218 boolean gotException = false; 3219 /* set duplicates in the reorder codes */ 3220 try { 3221 myCollation.setReorderCodes(duplicateReorderCodes); 3222 } catch (IllegalArgumentException e) { 3223 // expect exception on illegal arguments 3224 gotException = true; 3225 } 3226 if (!gotException) { 3227 errln("ERROR: exception was not thrown for illegal reorder codes argument."); 3228 } 3229 3230 /* set duplicate reorder codes */ 3231 gotException = false; 3232 try { 3233 myCollation.setReorderCodes(reorderCodesStartingWithDefault); 3234 } catch (IllegalArgumentException e) { 3235 gotException = true; 3236 } 3237 if (!gotException) { 3238 errln("ERROR: reorder codes following a 'default' code should have thrown an exception but did not."); 3239 } 3240 } 3241 3242 /* 3243 * Test reordering API. 3244 */ 3245 public void TestReorderingAPIWithRuleCreatedCollator() throws Exception 3246 { 3247 Collator myCollation; 3248 String rules = "[reorder Hani Grek]"; 3249 int[] rulesReorderCodes = {UScript.HAN, UScript.GREEK}; 3250 int[] reorderCodes = {UScript.GREEK, UScript.HAN, ReorderCodes.PUNCTUATION}; 3251 int[] retrievedReorderCodes; 3252 3253 3254 /* build collator tertiary */ 3255 myCollation = new RuleBasedCollator(rules); 3256 myCollation.setStrength(Collator.TERTIARY); 3257 3258 retrievedReorderCodes = myCollation.getReorderCodes(); 3259 if (!Arrays.equals(rulesReorderCodes, retrievedReorderCodes)) { 3260 errln("ERROR: retrieved reorder codes do not match set reorder codes."); 3261 } 3262 3263 /* clear the reordering */ 3264 myCollation.setReorderCodes(null); 3265 retrievedReorderCodes = myCollation.getReorderCodes(); 3266 if (retrievedReorderCodes.length != 0) { 3267 errln("ERROR: retrieved reorder codes was not null."); 3268 } 3269 3270 /* set the reorderding */ 3271 myCollation.setReorderCodes(reorderCodes); 3272 3273 retrievedReorderCodes = myCollation.getReorderCodes(); 3274 if (!Arrays.equals(reorderCodes, retrievedReorderCodes)) { 3275 errln("ERROR: retrieved reorder codes do not match set reorder codes."); 3276 } 3277 3278 /* reset the reordering */ 3279 myCollation.setReorderCodes(ReorderCodes.DEFAULT); 3280 retrievedReorderCodes = myCollation.getReorderCodes(); 3281 if (!Arrays.equals(rulesReorderCodes, retrievedReorderCodes)) { 3282 errln("ERROR: retrieved reorder codes do not match set reorder codes."); 3283 } 3284 } 3285 3286 static boolean containsExpectedScript(int[] scripts, int expectedScript) { 3287 for (int i = 0; i < scripts.length; ++i) { 3288 if (expectedScript == scripts[i]) { return true; } 3289 } 3290 return false; 3291 } 3292 3293 public void TestEquivalentReorderingScripts() { 3294 // Beginning with ICU 55, collation reordering moves single scripts 3295 // rather than groups of scripts, 3296 // except where scripts share a range and sort primary-equal. 3297 final int[] expectedScripts = { 3298 UScript.HIRAGANA, 3299 UScript.KATAKANA, 3300 UScript.KATAKANA_OR_HIRAGANA 3301 }; 3302 3303 int[] equivalentScripts = RuleBasedCollator.getEquivalentReorderCodes(UScript.GOTHIC); 3304 if (equivalentScripts.length != 1 || equivalentScripts[0] != UScript.GOTHIC) { 3305 errln(String.format("ERROR/Gothic: retrieved equivalent scripts wrong: " + 3306 "length expected 1, was = %d; expected [%d] was [%d]", 3307 equivalentScripts.length, UScript.GOTHIC, equivalentScripts[0])); 3308 } 3309 3310 equivalentScripts = RuleBasedCollator.getEquivalentReorderCodes(UScript.HIRAGANA); 3311 if (equivalentScripts.length != expectedScripts.length) { 3312 errln(String.format("ERROR/Hiragana: retrieved equivalent script length wrong: " + 3313 "expected %d, was = %d", 3314 expectedScripts.length, equivalentScripts.length)); 3315 } 3316 int prevScript = -1; 3317 for (int i = 0; i < equivalentScripts.length; ++i) { 3318 int script = equivalentScripts[i]; 3319 if (script <= prevScript) { 3320 errln("ERROR/Hiragana: equivalent scripts out of order at index " + i); 3321 } 3322 prevScript = script; 3323 } 3324 for (int code : expectedScripts) { 3325 if (!containsExpectedScript(equivalentScripts, code)) { 3326 errln("ERROR/Hiragana: equivalent scripts do not contain " + code); 3327 } 3328 } 3329 3330 equivalentScripts = RuleBasedCollator.getEquivalentReorderCodes(UScript.KATAKANA); 3331 if (equivalentScripts.length != expectedScripts.length) { 3332 errln(String.format("ERROR/Katakana: retrieved equivalent script length wrong: " + 3333 "expected %d, was = %d", 3334 expectedScripts.length, equivalentScripts.length)); 3335 } 3336 for (int code : expectedScripts) { 3337 if (!containsExpectedScript(equivalentScripts, code)) { 3338 errln("ERROR/Katakana: equivalent scripts do not contain " + code); 3339 } 3340 } 3341 3342 equivalentScripts = RuleBasedCollator.getEquivalentReorderCodes(UScript.KATAKANA_OR_HIRAGANA); 3343 if (equivalentScripts.length != expectedScripts.length) { 3344 errln(String.format("ERROR/Hrkt: retrieved equivalent script length wrong: " + 3345 "expected %d, was = %d", 3346 expectedScripts.length, equivalentScripts.length)); 3347 } 3348 3349 equivalentScripts = RuleBasedCollator.getEquivalentReorderCodes(UScript.HAN); 3350 if (equivalentScripts.length != 3) { 3351 errln("ERROR/Hani: retrieved equivalent script length wrong: " + 3352 "expected 3, was = " + equivalentScripts.length); 3353 } 3354 equivalentScripts = RuleBasedCollator.getEquivalentReorderCodes(UScript.SIMPLIFIED_HAN); 3355 if (equivalentScripts.length != 3) { 3356 errln("ERROR/Hans: retrieved equivalent script length wrong: " + 3357 "expected 3, was = " + equivalentScripts.length); 3358 } 3359 equivalentScripts = RuleBasedCollator.getEquivalentReorderCodes(UScript.TRADITIONAL_HAN); 3360 if (equivalentScripts.length != 3) { 3361 errln("ERROR/Hant: retrieved equivalent script length wrong: " + 3362 "expected 3, was = " + equivalentScripts.length); 3363 } 3364 3365 equivalentScripts = RuleBasedCollator.getEquivalentReorderCodes(UScript.MEROITIC_CURSIVE); 3366 if (equivalentScripts.length != 2) { 3367 errln("ERROR/Merc: retrieved equivalent script length wrong: " + 3368 "expected 2, was = " + equivalentScripts.length); 3369 } 3370 equivalentScripts = RuleBasedCollator.getEquivalentReorderCodes(UScript.MEROITIC_HIEROGLYPHS); 3371 if (equivalentScripts.length != 2) { 3372 errln("ERROR/Mero: retrieved equivalent script length wrong: " + 3373 "expected 2, was = " + equivalentScripts.length); 3374 } 3375 } 3376 3377 public void TestGreekFirstReorderCloning() { 3378 String[] testSourceCases = { 3379 "\u0041", 3380 "\u03b1\u0041", 3381 "\u0061", 3382 "\u0041\u0061", 3383 "\u0391", 3384 }; 3385 3386 String[] testTargetCases = { 3387 "\u03b1", 3388 "\u0041\u03b1", 3389 "\u0391", 3390 "\u0391\u03b1", 3391 "\u0391", 3392 }; 3393 3394 int[] results = { 3395 1, 3396 -1, 3397 1, 3398 1, 3399 0 3400 }; 3401 3402 Collator originalCollation; 3403 Collator myCollation; 3404 String rules = "[reorder Grek]"; 3405 try { 3406 originalCollation = new RuleBasedCollator(rules); 3407 } catch (Exception e) { 3408 warnln("ERROR: in creation of rule based collator"); 3409 return; 3410 } 3411 try { 3412 myCollation = (Collator) originalCollation.clone(); 3413 } catch (Exception e) { 3414 warnln("ERROR: in creation of rule based collator"); 3415 return; 3416 } 3417 myCollation.setDecomposition(Collator.CANONICAL_DECOMPOSITION); 3418 myCollation.setStrength(Collator.TERTIARY); 3419 for (int i = 0; i < testSourceCases.length ; i++) 3420 { 3421 CollationTest.doTest(this, (RuleBasedCollator)myCollation, 3422 testSourceCases[i], testTargetCases[i], 3423 results[i]); 3424 } 3425 } 3426 3427 /* 3428 * Utility function to test one collation reordering test case. 3429 * @param testcases Array of test cases. 3430 * @param n_testcases Size of the array testcases. 3431 * @param str_rules Array of rules. These rules should be specifying the same rule in different formats. 3432 * @param n_rules Size of the array str_rules. 3433 */ 3434 private void doTestOneReorderingAPITestCase(OneTestCase testCases[], int reorderTokens[]) 3435 { 3436 Collator myCollation = Collator.getInstance(ULocale.ENGLISH); 3437 myCollation.setReorderCodes(reorderTokens); 3438 3439 for (OneTestCase testCase : testCases) { 3440 CollationTest.doTest(this, (RuleBasedCollator)myCollation, 3441 testCase.m_source_, 3442 testCase.m_target_, 3443 testCase.m_result_); 3444 } 3445 } 3446 3447 public void TestGreekFirstReorder() 3448 { 3449 String[] strRules = { 3450 "[reorder Grek]" 3451 }; 3452 3453 int[] apiRules = { 3454 UScript.GREEK 3455 }; 3456 3457 OneTestCase[] privateUseCharacterStrings = { 3458 new OneTestCase("\u0391", "\u0391", 0), 3459 new OneTestCase("\u0041", "\u0391", 1), 3460 new OneTestCase("\u03B1\u0041", "\u03B1\u0391", 1), 3461 new OneTestCase("\u0060", "\u0391", -1), 3462 new OneTestCase("\u0391", "\ue2dc", -1), 3463 new OneTestCase("\u0391", "\u0060", 1), 3464 }; 3465 3466 /* Test rules creation */ 3467 doTestCollation(privateUseCharacterStrings, strRules); 3468 3469 /* Test collation reordering API */ 3470 doTestOneReorderingAPITestCase(privateUseCharacterStrings, apiRules); 3471 } 3472 3473 public void TestGreekLastReorder() 3474 { 3475 String[] strRules = { 3476 "[reorder Zzzz Grek]" 3477 }; 3478 3479 int[] apiRules = { 3480 UScript.UNKNOWN, UScript.GREEK 3481 }; 3482 3483 OneTestCase[] privateUseCharacterStrings = { 3484 new OneTestCase("\u0391", "\u0391", 0), 3485 new OneTestCase("\u0041", "\u0391", -1), 3486 new OneTestCase("\u03B1\u0041", "\u03B1\u0391", -1), 3487 new OneTestCase("\u0060", "\u0391", -1), 3488 new OneTestCase("\u0391", "\ue2dc", 1), 3489 }; 3490 3491 /* Test rules creation */ 3492 doTestCollation(privateUseCharacterStrings, strRules); 3493 3494 /* Test collation reordering API */ 3495 doTestOneReorderingAPITestCase(privateUseCharacterStrings, apiRules); 3496 } 3497 3498 public void TestNonScriptReorder() 3499 { 3500 String[] strRules = { 3501 "[reorder Grek Symbol DIGIT Latn Punct space Zzzz cURRENCy]" 3502 }; 3503 3504 int[] apiRules = { 3505 UScript.GREEK, ReorderCodes.SYMBOL, ReorderCodes.DIGIT, UScript.LATIN, 3506 ReorderCodes.PUNCTUATION, ReorderCodes.SPACE, UScript.UNKNOWN, 3507 ReorderCodes.CURRENCY 3508 }; 3509 3510 OneTestCase[] privateUseCharacterStrings = { 3511 new OneTestCase("\u0391", "\u0041", -1), 3512 new OneTestCase("\u0041", "\u0391", 1), 3513 new OneTestCase("\u0060", "\u0041", -1), 3514 new OneTestCase("\u0060", "\u0391", 1), 3515 new OneTestCase("\u0024", "\u0041", 1), 3516 }; 3517 3518 /* Test rules creation */ 3519 doTestCollation(privateUseCharacterStrings, strRules); 3520 3521 /* Test collation reordering API */ 3522 doTestOneReorderingAPITestCase(privateUseCharacterStrings, apiRules); 3523 } 3524 3525 public void TestHaniReorder() 3526 { 3527 String[] strRules = { 3528 "[reorder Hani]" 3529 }; 3530 int[] apiRules = { 3531 UScript.HAN 3532 }; 3533 3534 OneTestCase[] privateUseCharacterStrings = { 3535 new OneTestCase("\u4e00", "\u0041", -1), 3536 new OneTestCase("\u4e00", "\u0060", 1), 3537 new OneTestCase("\uD86D\uDF40", "\u0041", -1), 3538 new OneTestCase("\uD86D\uDF40", "\u0060", 1), 3539 new OneTestCase("\u4e00", "\uD86D\uDF40", -1), 3540 new OneTestCase("\ufa27", "\u0041", -1), 3541 new OneTestCase("\uD869\uDF00", "\u0041", -1), 3542 }; 3543 3544 /* Test rules creation */ 3545 doTestCollation(privateUseCharacterStrings, strRules); 3546 3547 /* Test collation reordering API */ 3548 doTestOneReorderingAPITestCase(privateUseCharacterStrings, apiRules); 3549 } 3550 3551 public void TestHaniReorderWithOtherRules() 3552 { 3553 String[] strRules = { 3554 "[reorder Hani] &b<a" 3555 }; 3556 3557 OneTestCase[] privateUseCharacterStrings = { 3558 new OneTestCase("\u4e00", "\u0041", -1), 3559 new OneTestCase("\u4e00", "\u0060", 1), 3560 new OneTestCase("\uD86D\uDF40", "\u0041", -1), 3561 new OneTestCase("\uD86D\uDF40", "\u0060", 1), 3562 new OneTestCase("\u4e00", "\uD86D\uDF40", -1), 3563 new OneTestCase("\ufa27", "\u0041", -1), 3564 new OneTestCase("\uD869\uDF00", "\u0041", -1), 3565 new OneTestCase("b", "a", -1), 3566 }; 3567 3568 /* Test rules creation */ 3569 doTestCollation(privateUseCharacterStrings, strRules); 3570 } 3571 3572 public void TestMultipleReorder() 3573 { 3574 String[] strRules = { 3575 "[reorder Grek Zzzz DIGIT Latn Hani]" 3576 }; 3577 3578 int[] apiRules = { 3579 UScript.GREEK, UScript.UNKNOWN, ReorderCodes.DIGIT, UScript.LATIN, UScript.HAN 3580 }; 3581 3582 OneTestCase[] collationTestCases = { 3583 new OneTestCase("\u0391", "\u0041", -1), 3584 new OneTestCase("\u0031", "\u0041", -1), 3585 new OneTestCase("u0041", "\u4e00", -1), 3586 }; 3587 3588 /* Test rules creation */ 3589 doTestCollation(collationTestCases, strRules); 3590 3591 /* Test collation reordering API */ 3592 doTestOneReorderingAPITestCase(collationTestCases, apiRules); 3593 } 3594 3595 public void TestFrozeness() 3596 { 3597 Collator myCollation = Collator.getInstance(ULocale.CANADA); 3598 boolean exceptionCaught = false; 3599 3600 myCollation.freeze(); 3601 assertTrue("Collator not frozen.", myCollation.isFrozen()); 3602 3603 try { 3604 myCollation.setStrength(Collator.SECONDARY); 3605 } catch (UnsupportedOperationException e) { 3606 // expected 3607 exceptionCaught = true; 3608 } 3609 assertTrue("Frozen collator allowed change.", exceptionCaught); 3610 exceptionCaught = false; 3611 3612 try { 3613 myCollation.setReorderCodes(ReorderCodes.DEFAULT); 3614 } catch (UnsupportedOperationException e) { 3615 // expected 3616 exceptionCaught = true; 3617 } 3618 assertTrue("Frozen collator allowed change.", exceptionCaught); 3619 exceptionCaught = false; 3620 3621 try { 3622 myCollation.setVariableTop(12); 3623 } catch (UnsupportedOperationException e) { 3624 // expected 3625 exceptionCaught = true; 3626 } 3627 assertTrue("Frozen collator allowed change.", exceptionCaught); 3628 exceptionCaught = false; 3629 3630 Collator myClone = null; 3631 try { 3632 myClone = (Collator) myCollation.clone(); 3633 } catch (CloneNotSupportedException e) { 3634 // should not happen - clone is implemented in Collator 3635 errln("ERROR: unable to clone collator."); 3636 } 3637 assertTrue("Clone not frozen as expected.", myClone.isFrozen()); 3638 3639 myClone = myClone.cloneAsThawed(); 3640 assertFalse("Clone not thawed as expected.", myClone.isFrozen()); 3641 } 3642 3643 // Test case for Ticket#9409 3644 // Unknown collation type should be ignored, without printing stack trace 3645 public void TestUnknownCollationKeyword() { 3646 Collator coll1 = Collator.getInstance(new ULocale("en_US@collation=bogus")); 3647 Collator coll2 = Collator.getInstance(new ULocale("en_US")); 3648 assertEquals("Unknown collation keyword 'bogus' should be ignored", coll1, coll2); 3649 } 3650} 3651