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