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-2014, International Business Machines Corporation and 7 * others. All Rights Reserved. 8 ******************************************************************************* 9 */ 10 11 /** 12 * Port From: ICU4C v2.1 : collate/CollationAPITest 13 * Source File: $ICU4CRoot/source/test/intltest/apicoll.cpp 14 **/ 15 16 package android.icu.dev.test.collator; 17 18 import java.text.CharacterIterator; 19 import java.text.StringCharacterIterator; 20 import java.util.Arrays; 21 import java.util.HashSet; 22 import java.util.Locale; 23 import java.util.MissingResourceException; 24 import java.util.Set; 25 26 import org.junit.Test; 27 import org.junit.runner.RunWith; 28 import org.junit.runners.JUnit4; 29 30 import android.icu.dev.test.TestFmwk; 31 import android.icu.impl.Utility; 32 import android.icu.lang.UCharacter; 33 import android.icu.text.CollationElementIterator; 34 import android.icu.text.CollationKey; 35 import android.icu.text.Collator; 36 import android.icu.text.Collator.CollatorFactory; 37 import android.icu.text.RawCollationKey; 38 import android.icu.text.RuleBasedCollator; 39 import android.icu.text.UCharacterIterator; 40 import android.icu.text.UnicodeSet; 41 import android.icu.util.ULocale; 42 import android.icu.util.VersionInfo; 43 import android.icu.testsharding.MainTestShard; 44 45 @MainTestShard 46 @RunWith(JUnit4.class) 47 public class CollationAPITest extends TestFmwk { 48 /** 49 * This tests the collation key related APIs. 50 * - constructor/destructor 51 * - Collator.getCollationKey 52 * - == and != operators 53 * - comparison between collation keys 54 * - creating collation key with a byte array and vice versa 55 */ 56 @Test 57 public void TestCollationKey() { 58 logln("testing CollationKey begins..."); 59 Collator col = Collator.getInstance(); 60 col.setStrength(Collator.TERTIARY); 61 62 String test1 = "Abcda"; 63 String test2 = "abcda"; 64 65 logln("Testing weird arguments"); 66 CollationKey sortk1 = col.getCollationKey(""); 67 // key gets reset here 68 byte[] bytes = sortk1.toByteArray(); 69 doAssert(bytes.length == 3 && bytes[0] == 1 && bytes[1] == 1 70 && bytes[2] == 0, 71 "Empty string should return a collation key with empty levels"); 72 73 // Most control codes and CGJ are completely ignorable. 74 // A string with only completely ignorables must compare equal to an empty string. 75 CollationKey sortkIgnorable = col.getCollationKey("\u0001\u034f"); 76 doAssert(sortkIgnorable != null && sortkIgnorable.toByteArray().length == 3, 77 "Completely ignorable string should return a collation key with empty levels"); 78 doAssert(sortkIgnorable.compareTo(sortk1) == 0, 79 "Completely ignorable string should compare equal to empty string"); 80 81 // bogus key returned here 82 sortk1 = col.getCollationKey(null); 83 doAssert(sortk1 == null, "Error code should return bogus collation key"); 84 85 logln("Use tertiary comparison level testing ...."); 86 sortk1 = col.getCollationKey(test1); 87 CollationKey sortk2 = col.getCollationKey(test2); 88 doAssert((sortk1.compareTo(sortk2)) > 0, "Result should be \"Abcda\" >>> \"abcda\""); 89 90 CollationKey sortkNew; 91 sortkNew = sortk1; 92 doAssert(!(sortk1.equals(sortk2)), "The sort keys should be different"); 93 doAssert((sortk1.hashCode() != sortk2.hashCode()), "sort key hashCode() failed"); 94 doAssert((sortk1.equals(sortkNew)), "The sort keys assignment failed"); 95 doAssert((sortk1.hashCode() == sortkNew.hashCode()), "sort key hashCode() failed"); 96 97 // port from apicoll 98 try { 99 col = Collator.getInstance(); 100 } catch (Exception e) { 101 errln("Collator.getInstance() failed"); 102 } 103 if (col.getStrength() != Collator.TERTIARY){ 104 errln("Default collation did not have tertiary strength"); 105 } 106 107 // Need to use identical strength 108 col.setStrength(Collator.IDENTICAL); 109 110 CollationKey key1 = col.getCollationKey(test1); 111 CollationKey key2 = col.getCollationKey(test2); 112 CollationKey key3 = col.getCollationKey(test2); 113 114 doAssert(key1.compareTo(key2) > 0, 115 "Result should be \"Abcda\" > \"abcda\""); 116 doAssert(key2.compareTo(key1) < 0, 117 "Result should be \"abcda\" < \"Abcda\""); 118 doAssert(key2.compareTo(key3) == 0, 119 "Result should be \"abcda\" == \"abcda\""); 120 121 byte key2identical[] = key2.toByteArray(); 122 123 logln("Use secondary comparision level testing ..."); 124 col.setStrength(Collator.SECONDARY); 125 126 key1 = col.getCollationKey(test1); 127 key2 = col.getCollationKey(test2); 128 key3 = col.getCollationKey(test2); 129 130 doAssert(key1.compareTo(key2) == 0, 131 "Result should be \"Abcda\" == \"abcda\""); 132 doAssert(key2.compareTo(key3) == 0, 133 "Result should be \"abcda\" == \"abcda\""); 134 135 byte tempkey[] = key2.toByteArray(); 136 byte subkey2compat[] = new byte[tempkey.length]; 137 System.arraycopy(key2identical, 0, subkey2compat, 0, tempkey.length); 138 subkey2compat[subkey2compat.length - 1] = 0; 139 doAssert(Arrays.equals(tempkey, subkey2compat), 140 "Binary format for 'abcda' sortkey different for secondary strength!"); 141 142 logln("testing sortkey ends..."); 143 } 144 145 @Test 146 public void TestRawCollationKey() 147 { 148 // testing constructors 149 RawCollationKey key = new RawCollationKey(); 150 if (key.bytes != null || key.size != 0) { 151 errln("Empty default constructor expected to leave the bytes null " 152 + "and size 0"); 153 } 154 byte array[] = new byte[128]; 155 key = new RawCollationKey(array); 156 if (key.bytes != array || key.size != 0) { 157 errln("Constructor taking an array expected to adopt it and " 158 + "retaining its size 0"); 159 } 160 try { 161 key = new RawCollationKey(array, 129); 162 errln("Constructor taking an array and a size > array.length " 163 + "expected to throw an exception"); 164 } catch (IndexOutOfBoundsException e) { 165 logln("PASS: Constructor failed as expected"); 166 } 167 try { 168 key = new RawCollationKey(array, -1); 169 errln("Constructor taking an array and a size < 0 " 170 + "expected to throw an exception"); 171 } catch (IndexOutOfBoundsException e) { 172 logln("PASS: Constructor failed as expected"); 173 } 174 key = new RawCollationKey(array, array.length >> 1); 175 if (key.bytes != array || key.size != (array.length >> 1)) { 176 errln("Constructor taking an array and a size, " 177 + "expected to adopt it and take the size specified"); 178 } 179 key = new RawCollationKey(10); 180 if (key.bytes == null || key.bytes.length != 10 || key.size != 0) { 181 errln("Constructor taking a specified capacity expected to " 182 + "create a new internal byte array with length 10 and " 183 + "retain size 0"); 184 } 185 } 186 187 void doAssert(boolean conditions, String message) { 188 if (!conditions) { 189 errln(message); 190 } 191 } 192 193 /** 194 * This tests the comparison convenience methods of a collator object. 195 * - greater than 196 * - greater than or equal to 197 * - equal to 198 */ 199 @Test 200 public void TestCompare() { 201 logln("The compare tests begin : "); 202 Collator col = Collator.getInstance(Locale.ENGLISH); 203 204 String test1 = "Abcda"; 205 String test2 = "abcda"; 206 logln("Use tertiary comparison level testing ...."); 207 208 doAssert((!col.equals(test1, test2) ), "Result should be \"Abcda\" != \"abcda\""); 209 doAssert((col.compare(test1, test2) > 0 ), "Result should be \"Abcda\" >>> \"abcda\""); 210 211 col.setStrength(Collator.SECONDARY); 212 logln("Use secondary comparison level testing ...."); 213 214 doAssert((col.equals(test1, test2) ), "Result should be \"Abcda\" == \"abcda\""); 215 doAssert((col.compare(test1, test2) == 0), "Result should be \"Abcda\" == \"abcda\""); 216 217 col.setStrength(Collator.PRIMARY); 218 logln("Use primary comparison level testing ...."); 219 220 doAssert((col.equals(test1, test2) ), "Result should be \"Abcda\" == \"abcda\""); 221 doAssert((col.compare(test1, test2) == 0 ), "Result should be \"Abcda\" == \"abcda\""); 222 logln("The compare tests end."); 223 } 224 225 /** 226 * Tests decomposition setting 227 */ 228 @Test 229 public void TestDecomposition() { 230 Collator en_US = null, el_GR = null, vi_VN = null; 231 232 en_US = Collator.getInstance(new Locale("en", "US")); 233 el_GR = Collator.getInstance(new Locale("el", "GR")); 234 vi_VN = Collator.getInstance(new Locale("vi", "VN")); 235 236 237 // there is no reason to have canonical decomposition in en_US OR default locale */ 238 if (vi_VN.getDecomposition() != Collator.CANONICAL_DECOMPOSITION) 239 { 240 errln("vi_VN collation did not have cannonical decomposition for normalization!"); 241 } 242 243 if (el_GR.getDecomposition() != Collator.CANONICAL_DECOMPOSITION) 244 { 245 errln("el_GR collation did not have cannonical decomposition for normalization!"); 246 } 247 248 if (en_US.getDecomposition() != Collator.NO_DECOMPOSITION) 249 { 250 errln("en_US collation had cannonical decomposition for normalization!"); 251 } 252 } 253 254 /** 255 * This tests the duplication of a collator object. 256 */ 257 @Test 258 public void TestDuplicate() { 259 //Clone does not be implemented 260 Collator col1 = Collator.getInstance(Locale.ENGLISH); 261 262 // Collator col2 = (Collator)col1.clone(); 263 // doAssert(col1.equals(col2), "Cloned object is not equal to the orginal"); 264 String ruleset = "&9 < a, A < b, B < c, C < d, D, e, E"; 265 RuleBasedCollator col3 = null; 266 try { 267 col3 = new RuleBasedCollator(ruleset); 268 } catch (Exception e) { 269 errln("Failure creating RuleBasedCollator with rule: \"" + ruleset + "\"\n" + e); 270 return; 271 } 272 doAssert(!col1.equals(col3), "Cloned object is equal to some dummy"); 273 col3 = (RuleBasedCollator)col1; 274 doAssert(col1.equals(col3), "Copied object is not equal to the orginal"); 275 276 } 277 278 /** 279 * This tests the CollationElementIterator related APIs. 280 * - creation of a CollationElementIterator object 281 * - == and != operators 282 * - iterating forward 283 * - reseting the iterator index 284 * - requesting the order properties(primary, secondary or tertiary) 285 */ 286 @Test 287 public void TestElemIter() { 288 // logln("testing sortkey begins..."); 289 Collator col = Collator.getInstance(Locale.ENGLISH); 290 291 292 String testString1 = "XFILE What subset of all possible test cases has the highest probability of detecting the most errors?"; 293 String testString2 = "Xf_ile What subset of all possible test cases has the lowest probability of detecting the least errors?"; 294 // logln("Constructors and comparison testing...."); 295 CollationElementIterator iterator1 = ((RuleBasedCollator)col).getCollationElementIterator(testString1); 296 297 CharacterIterator chariter=new StringCharacterIterator(testString1); 298 // copy ctor 299 CollationElementIterator iterator2 = ((RuleBasedCollator)col).getCollationElementIterator(chariter); 300 UCharacterIterator uchariter=UCharacterIterator.getInstance(testString2); 301 CollationElementIterator iterator3 = ((RuleBasedCollator)col).getCollationElementIterator(uchariter); 302 303 int offset = 0; 304 offset = iterator1.getOffset(); 305 if (offset != 0) { 306 errln("Error in getOffset for collation element iterator"); 307 return; 308 } 309 iterator1.setOffset(6); 310 iterator1.setOffset(0); 311 int order1, order2, order3; 312 313 order1 = iterator1.next(); 314 doAssert(!(iterator1.equals(iterator2)), "The first iterator advance failed"); 315 order2 = iterator2.next(); 316 317 // Code coverage for dummy "not designed" hashCode() which does "assert false". 318 try { 319 iterator1.hashCode(); // We don't expect any particular value. 320 } catch (AssertionError ignored) { 321 // Expected to be thrown if assertions are enabled. 322 } 323 324 // In ICU 52 and earlier we had iterator1.equals(iterator2) 325 // but in ICU 53 this fails because the iterators differ (String vs. CharacterIterator). 326 // doAssert((iterator1.equals(iterator2)), "The second iterator advance failed"); 327 doAssert(iterator1.getOffset() == iterator2.getOffset(), "The second iterator advance failed"); 328 doAssert((order1 == order2), "The order result should be the same"); 329 order3 = iterator3.next(); 330 331 doAssert((CollationElementIterator.primaryOrder(order1) == 332 CollationElementIterator.primaryOrder(order3)), "The primary orders should be the same"); 333 doAssert((CollationElementIterator.secondaryOrder(order1) == 334 CollationElementIterator.secondaryOrder(order3)), "The secondary orders should be the same"); 335 doAssert((CollationElementIterator.tertiaryOrder(order1) == 336 CollationElementIterator.tertiaryOrder(order3)), "The tertiary orders should be the same"); 337 338 order1 = iterator1.next(); 339 order3 = iterator3.next(); 340 341 doAssert((CollationElementIterator.primaryOrder(order1) == 342 CollationElementIterator.primaryOrder(order3)), "The primary orders should be identical"); 343 doAssert((CollationElementIterator.tertiaryOrder(order1) != 344 CollationElementIterator.tertiaryOrder(order3)), "The tertiary orders should be different"); 345 346 order1 = iterator1.next(); 347 order3 = iterator3.next(); 348 // invalid test wrong in UCA 349 // doAssert((CollationElementIterator.secondaryOrder(order1) != 350 // CollationElementIterator.secondaryOrder(order3)), "The secondary orders should not be the same"); 351 352 doAssert((order1 != CollationElementIterator.NULLORDER), "Unexpected end of iterator reached"); 353 354 iterator1.reset(); 355 iterator2.reset(); 356 iterator3.reset(); 357 order1 = iterator1.next(); 358 359 doAssert(!(iterator1.equals(iterator2)), "The first iterator advance failed"); 360 361 order2 = iterator2.next(); 362 363 // In ICU 52 and earlier we had iterator1.equals(iterator2) 364 // but in ICU 53 this fails because the iterators differ (String vs. CharacterIterator). 365 // doAssert((iterator1.equals(iterator2)), "The second iterator advance failed"); 366 doAssert(iterator1.getOffset() == iterator2.getOffset(), "The second iterator advance failed"); 367 doAssert((order1 == order2), "The order result should be the same"); 368 369 order3 = iterator3.next(); 370 371 doAssert((CollationElementIterator.primaryOrder(order1) == 372 CollationElementIterator.primaryOrder(order3)), "The primary orders should be the same"); 373 doAssert((CollationElementIterator.secondaryOrder(order1) == 374 CollationElementIterator.secondaryOrder(order3)), "The secondary orders should be the same"); 375 doAssert((CollationElementIterator.tertiaryOrder(order1) == 376 CollationElementIterator.tertiaryOrder(order3)), "The tertiary orders should be the same"); 377 378 order1 = iterator1.next(); 379 order2 = iterator2.next(); 380 order3 = iterator3.next(); 381 382 doAssert((CollationElementIterator.primaryOrder(order1) == 383 CollationElementIterator.primaryOrder(order3)), "The primary orders should be identical"); 384 doAssert((CollationElementIterator.tertiaryOrder(order1) != 385 CollationElementIterator.tertiaryOrder(order3)), "The tertiary orders should be different"); 386 387 order1 = iterator1.next(); 388 order3 = iterator3.next(); 389 390 // obsolete invalid test, removed 391 // doAssert((CollationElementIterator.secondaryOrder(order1) != 392 // CollationElementIterator.secondaryOrder(order3)), "The secondary orders should not be the same"); 393 doAssert((order1 != CollationElementIterator.NULLORDER), "Unexpected end of iterator reached"); 394 doAssert(!(iterator2.equals(iterator3)), "The iterators should be different"); 395 logln("testing CollationElementIterator ends..."); 396 } 397 398 /** 399 * This tests the hashCode method of a collator object. 400 */ 401 @Test 402 public void TestHashCode() { 403 logln("hashCode tests begin."); 404 Collator col1 = Collator.getInstance(Locale.ENGLISH); 405 406 Collator col2 = null; 407 Locale dk = new Locale("da", "DK", ""); 408 try { 409 col2 = Collator.getInstance(dk); 410 } catch (Exception e) { 411 errln("Danish collation creation failed."); 412 return; 413 } 414 415 Collator col3 = null; 416 try { 417 col3 = Collator.getInstance(Locale.ENGLISH); 418 } catch (Exception e) { 419 errln("2nd default collation creation failed."); 420 return; 421 } 422 423 logln("Collator.hashCode() testing ..."); 424 425 doAssert(col1.hashCode() != col2.hashCode(), "Hash test1 result incorrect" ); 426 doAssert(!(col1.hashCode() == col2.hashCode()), "Hash test2 result incorrect" ); 427 doAssert(col1.hashCode() == col3.hashCode(), "Hash result not equal" ); 428 429 logln("hashCode tests end."); 430 431 String test1 = "Abcda"; 432 String test2 = "abcda"; 433 434 CollationKey sortk1, sortk2, sortk3; 435 436 sortk1 = col3.getCollationKey(test1); 437 sortk2 = col3.getCollationKey(test2); 438 sortk3 = col3.getCollationKey(test2); 439 440 doAssert(sortk1.hashCode() != sortk2.hashCode(), "Hash test1 result incorrect"); 441 doAssert(sortk2.hashCode() == sortk3.hashCode(), "Hash result not equal" ); 442 } 443 444 /** 445 * This tests the properties of a collator object. 446 * - constructor 447 * - factory method getInstance 448 * - compare and getCollationKey 449 * - get/set decomposition mode and comparison level 450 */ 451 @Test 452 public void TestProperty() { 453 /* 454 All the collations have the same version in an ICU 455 version. 456 ICU 2.0 currVersionArray = {0x18, 0xC0, 0x02, 0x02}; 457 ICU 2.1 currVersionArray = {0x19, 0x00, 0x03, 0x03}; 458 ICU 2.8 currVersionArray = {0x29, 0x80, 0x00, 0x04}; 459 */ 460 logln("The property tests begin : "); 461 logln("Test ctors : "); 462 Collator col = Collator.getInstance(Locale.ENGLISH); 463 464 logln("Test getVersion"); 465 // Check for a version greater than some value rather than equality 466 // so that we need not update the expected version each time. 467 VersionInfo expectedVersion = VersionInfo.getInstance(0x31, 0xC0, 0x00, 0x05); // from ICU 4.4/UCA 5.2 468 doAssert(col.getVersion().compareTo(expectedVersion) >= 0, "Expected minimum version "+expectedVersion.toString()+" got "+col.getVersion().toString()); 469 470 logln("Test getUCAVersion"); 471 // Assume that the UCD and UCA versions are the same, 472 // rather than hardcoding (and updating each time) a particular UCA version. 473 VersionInfo ucdVersion = UCharacter.getUnicodeVersion(); 474 VersionInfo ucaVersion = col.getUCAVersion(); 475 doAssert(ucaVersion.equals(ucdVersion), 476 "Expected UCA version "+ucdVersion.toString()+" got "+col.getUCAVersion().toString()); 477 478 doAssert((col.compare("ab", "abc") < 0), "ab < abc comparison failed"); 479 doAssert((col.compare("ab", "AB") < 0), "ab < AB comparison failed"); 480 doAssert((col.compare("blackbird", "black-bird") > 0), "black-bird > blackbird comparison failed"); 481 doAssert((col.compare("black bird", "black-bird") < 0), "black bird > black-bird comparison failed"); 482 doAssert((col.compare("Hello", "hello") > 0), "Hello > hello comparison failed"); 483 484 logln("Test ctors ends."); 485 486 logln("testing Collator.getStrength() method ..."); 487 doAssert((col.getStrength() == Collator.TERTIARY), "collation object has the wrong strength"); 488 doAssert((col.getStrength() != Collator.PRIMARY), "collation object's strength is primary difference"); 489 490 logln("testing Collator.setStrength() method ..."); 491 col.setStrength(Collator.SECONDARY); 492 doAssert((col.getStrength() != Collator.TERTIARY), "collation object's strength is secondary difference"); 493 doAssert((col.getStrength() != Collator.PRIMARY), "collation object's strength is primary difference"); 494 doAssert((col.getStrength() == Collator.SECONDARY), "collation object has the wrong strength"); 495 496 logln("testing Collator.setDecomposition() method ..."); 497 col.setDecomposition(Collator.NO_DECOMPOSITION); 498 doAssert((col.getDecomposition() != Collator.CANONICAL_DECOMPOSITION), "Decomposition mode != Collator.CANONICAL_DECOMPOSITION"); 499 doAssert((col.getDecomposition() == Collator.NO_DECOMPOSITION), "Decomposition mode = Collator.NO_DECOMPOSITION"); 500 501 502 // Android patch: Add --omitCollationRules to genrb. 503 // RuleBasedCollator rcol = (RuleBasedCollator)Collator.getInstance(new Locale("da", "DK")); 504 // doAssert(rcol.getRules().length() != 0, "da_DK rules does not have length 0"); 505 // Android patch end. 506 507 try { 508 col = Collator.getInstance(Locale.FRENCH); 509 } catch (Exception e) { 510 errln("Creating French collation failed."); 511 return; 512 } 513 514 col.setStrength(Collator.PRIMARY); 515 logln("testing Collator.getStrength() method again ..."); 516 doAssert((col.getStrength() != Collator.TERTIARY), "collation object has the wrong strength"); 517 doAssert((col.getStrength() == Collator.PRIMARY), "collation object's strength is not primary difference"); 518 519 logln("testing French Collator.setStrength() method ..."); 520 col.setStrength(Collator.TERTIARY); 521 doAssert((col.getStrength() == Collator.TERTIARY), "collation object's strength is not tertiary difference"); 522 doAssert((col.getStrength() != Collator.PRIMARY), "collation object's strength is primary difference"); 523 doAssert((col.getStrength() != Collator.SECONDARY), "collation object's strength is secondary difference"); 524 525 } 526 527 @Test 528 public void TestJunkCollator(){ 529 logln("Create junk collation: "); 530 Locale abcd = new Locale("ab", "CD", ""); 531 532 Collator junk = Collator.getInstance(abcd); 533 Collator col = Collator.getInstance(); 534 535 536 String colrules = ((RuleBasedCollator)col).getRules(); 537 String junkrules = ((RuleBasedCollator)junk).getRules(); 538 doAssert(colrules == junkrules || colrules.equals(junkrules), 539 "The default collation should be returned."); 540 Collator frCol = null; 541 try { 542 frCol = Collator.getInstance(Locale.CANADA_FRENCH); 543 } catch (Exception e) { 544 errln("Creating fr_CA collator failed."); 545 return; 546 } 547 548 doAssert(!(frCol.equals(junk)), "The junk is the same as the fr_CA collator."); 549 logln("Collator property test ended."); 550 551 } 552 553 /** 554 * This tests the RuleBasedCollator 555 * - constructor/destructor 556 * - getRules 557 */ 558 @Test 559 public void TestRuleBasedColl() { 560 RuleBasedCollator col1 = null, col2 = null, col3 = null, col4 = null; 561 562 String ruleset1 = "&9 < a, A < b, B < c, C; ch, cH, Ch, CH < d, D, e, E"; 563 String ruleset2 = "&9 < a, A < b, B < c, C < d, D, e, E"; 564 String ruleset3 = "&"; 565 566 try { 567 col1 = new RuleBasedCollator(ruleset1); 568 } catch (Exception e) { 569 // only first error needs to be a warning since we exit function 570 warnln("RuleBased Collator creation failed."); 571 return; 572 } 573 574 try { 575 col2 = new RuleBasedCollator(ruleset2); 576 } catch (Exception e) { 577 errln("RuleBased Collator creation failed."); 578 return; 579 } 580 581 try { 582 // empty rules fail 583 col3 = new RuleBasedCollator(ruleset3); 584 errln("Failure: Empty rules for the collator should fail"); 585 return; 586 } catch (MissingResourceException e) { 587 warnln(e.getMessage()); 588 } catch (Exception e) { 589 logln("PASS: Empty rules for the collator failed as expected"); 590 } 591 592 Locale locale = new Locale("aa", "AA"); 593 try { 594 col3 = (RuleBasedCollator)Collator.getInstance(locale); 595 } catch (Exception e) { 596 errln("Fallback Collator creation failed.: %s"); 597 return; 598 } 599 600 try { 601 col3 = (RuleBasedCollator)Collator.getInstance(); 602 } catch (Exception e) { 603 errln("Default Collator creation failed.: %s"); 604 return; 605 } 606 607 String rule1 = col1.getRules(); 608 String rule2 = col2.getRules(); 609 String rule3 = col3.getRules(); 610 611 doAssert(!rule1.equals(rule2), "Default collator getRules failed"); 612 doAssert(!rule2.equals(rule3), "Default collator getRules failed"); 613 doAssert(!rule1.equals(rule3), "Default collator getRules failed"); 614 615 try { 616 col4 = new RuleBasedCollator(rule2); 617 } catch (Exception e) { 618 errln("RuleBased Collator creation failed."); 619 return; 620 } 621 622 String rule4 = col4.getRules(); 623 doAssert(rule2.equals(rule4), "Default collator getRules failed"); 624 // tests that modifier ! is always ignored 625 String exclamationrules = "!&a<b"; 626 // java does not allow ! to be the start of the rule 627 String thaistr = "\u0e40\u0e01\u0e2d"; 628 try { 629 RuleBasedCollator col5 = new RuleBasedCollator(exclamationrules); 630 RuleBasedCollator encol = (RuleBasedCollator) 631 Collator.getInstance(Locale.ENGLISH); 632 CollationElementIterator col5iter 633 = col5.getCollationElementIterator(thaistr); 634 CollationElementIterator encoliter 635 = encol.getCollationElementIterator( 636 thaistr); 637 while (true) { 638 // testing with en since thai has its own tailoring 639 int ce = col5iter.next(); 640 int ce2 = encoliter.next(); 641 if (ce2 != ce) { 642 errln("! modifier test failed"); 643 } 644 if (ce == CollationElementIterator.NULLORDER) { 645 break; 646 } 647 } 648 } catch (Exception e) { 649 errln("RuleBased Collator creation failed for ! modifier."); 650 return; 651 } 652 } 653 654 /** 655 * This tests the RuleBasedCollator 656 * - getRules 657 */ 658 @Test 659 public void TestRules() { 660 RuleBasedCollator coll = (RuleBasedCollator)Collator.getInstance(new Locale("","","")); //root 661 // logln("PASS: RuleBased Collator creation passed"); 662 663 664 String rules = coll.getRules(); 665 if (rules != null && rules.length() != 0) { 666 errln("Root tailored rules failed"); 667 } 668 } 669 670 @Test 671 public void TestSafeClone() { 672 String test1 = "abCda"; 673 String test2 = "abcda"; 674 675 // one default collator & two complex ones 676 RuleBasedCollator someCollators[] = { 677 (RuleBasedCollator)Collator.getInstance(Locale.ENGLISH), 678 (RuleBasedCollator)Collator.getInstance(Locale.KOREA), 679 (RuleBasedCollator)Collator.getInstance(Locale.JAPAN) 680 }; 681 RuleBasedCollator someClonedCollators[] = new RuleBasedCollator[3]; 682 683 // change orig & clone & make sure they are independent 684 685 for (int index = 0; index < someCollators.length; index ++) 686 { 687 try { 688 someClonedCollators[index] 689 = (RuleBasedCollator)someCollators[index].clone(); 690 } catch (CloneNotSupportedException e) { 691 errln("Error cloning collator"); 692 } 693 694 someClonedCollators[index].setStrength(Collator.TERTIARY); 695 someCollators[index].setStrength(Collator.PRIMARY); 696 someClonedCollators[index].setCaseLevel(false); 697 someCollators[index].setCaseLevel(false); 698 699 doAssert(someClonedCollators[index].compare(test1, test2) > 0, 700 "Result should be \"abCda\" >>> \"abcda\" "); 701 doAssert(someCollators[index].compare(test1, test2) == 0, 702 "Result should be \"abCda\" == \"abcda\" "); 703 } 704 } 705 706 @Test 707 public void TestGetTailoredSet() 708 { 709 logln("testing getTailoredSet..."); 710 String rules[] = { 711 "&a < \u212b", 712 "& S < \u0161 <<< \u0160", 713 }; 714 String data[][] = { 715 { "\u212b", "A\u030a", "\u00c5" }, 716 { "\u0161", "s\u030C", "\u0160", "S\u030C" } 717 }; 718 719 int i = 0, j = 0; 720 721 RuleBasedCollator coll; 722 UnicodeSet set; 723 724 for(i = 0; i < rules.length; i++) { 725 try { 726 logln("Instantiating a collator from "+rules[i]); 727 coll = new RuleBasedCollator(rules[i]); 728 set = coll.getTailoredSet(); 729 logln("Got set: "+set.toPattern(true)); 730 if(set.size() < data[i].length) { 731 errln("Tailored set size smaller ("+set.size()+") than expected ("+data[i].length+")"); 732 } 733 for(j = 0; j < data[i].length; j++) { 734 logln("Checking to see whether "+data[i][j]+" is in set"); 735 if(!set.contains(data[i][j])) { 736 errln("Tailored set doesn't contain "+data[i][j]+"... It should"); 737 } 738 } 739 } catch (Exception e) { 740 warnln("Couldn't open collator with rules "+ rules[i]); 741 } 742 } 743 } 744 745 /** 746 * Simple test to see if Collator is subclassable. 747 * Also test coverage of base class methods that are overridden by RuleBasedCollator. 748 */ 749 @Test 750 public void TestSubClass() 751 { 752 class TestCollator extends Collator 753 { 754 @Override 755 public boolean equals(Object that) { 756 return this == that; 757 } 758 759 @Override 760 public int hashCode() { 761 return 0; 762 } 763 764 @Override 765 public int compare(String source, String target) { 766 return source.compareTo(target); 767 } 768 769 @Override 770 public CollationKey getCollationKey(String source) 771 { return new CollationKey(source, 772 getRawCollationKey(source, new RawCollationKey())); 773 } 774 775 @Override 776 public RawCollationKey getRawCollationKey(String source, 777 RawCollationKey key) 778 { 779 byte temp1[] = source.getBytes(); 780 byte temp2[] = new byte[temp1.length + 1]; 781 System.arraycopy(temp1, 0, temp2, 0, temp1.length); 782 temp2[temp1.length] = 0; 783 if (key == null) { 784 key = new RawCollationKey(); 785 } 786 key.bytes = temp2; 787 key.size = temp2.length; 788 return key; 789 } 790 791 @Override 792 public void setVariableTop(int ce) 793 { 794 if (isFrozen()) { 795 throw new UnsupportedOperationException("Attempt to modify frozen object"); 796 } 797 } 798 799 @Override 800 public int setVariableTop(String str) 801 { 802 if (isFrozen()) { 803 throw new UnsupportedOperationException("Attempt to modify frozen object"); 804 } 805 806 return 0; 807 } 808 809 @Override 810 public int getVariableTop() 811 { 812 return 0; 813 } 814 @Override 815 public VersionInfo getVersion() 816 { 817 return VersionInfo.getInstance(0); 818 } 819 @Override 820 public VersionInfo getUCAVersion() 821 { 822 return VersionInfo.getInstance(0); 823 } 824 } 825 826 Collator col1 = new TestCollator(); 827 Collator col2 = new TestCollator(); 828 if (col1.equals(col2)) { 829 errln("2 different instance of TestCollator should fail"); 830 } 831 if (col1.hashCode() != col2.hashCode()) { 832 errln("Every TestCollator has the same hashcode"); 833 } 834 String abc = "abc"; 835 String bcd = "bcd"; 836 if (col1.compare(abc, bcd) != abc.compareTo(bcd)) { 837 errln("TestCollator compare should be the same as the default " + 838 "string comparison"); 839 } 840 CollationKey key = col1.getCollationKey(abc); 841 byte temp1[] = abc.getBytes(); 842 byte temp2[] = new byte[temp1.length + 1]; 843 System.arraycopy(temp1, 0, temp2, 0, temp1.length); 844 temp2[temp1.length] = 0; 845 if (!java.util.Arrays.equals(key.toByteArray(), temp2) 846 || !key.getSourceString().equals(abc)) { 847 errln("TestCollator collationkey API is returning wrong values"); 848 } 849 UnicodeSet set = col1.getTailoredSet(); 850 if (!set.equals(new UnicodeSet(0, 0x10FFFF))) { 851 errln("Error getting default tailored set"); 852 } 853 854 // Base class code coverage. 855 // Most of these methods are dummies; 856 // they are overridden by any subclass that supports their features. 857 858 assertEquals("compare(strings as Object)", 0, 859 col1.compare(new StringBuilder("abc"), new StringBuffer("abc"))); 860 861 col1.setStrength(Collator.SECONDARY); 862 assertNotEquals("getStrength()", Collator.PRIMARY, col1.getStrength()); 863 864 // setStrength2() is @internal and returns this. 865 // The base class getStrength() always returns the same value, 866 // since the base class does not have a field to store the strength. 867 assertNotEquals("setStrength2().getStrength()", Collator.PRIMARY, 868 col1.setStrength2(Collator.IDENTICAL).getStrength()); 869 870 // (base class).setDecomposition() may or may not be implemented. 871 try { 872 col1.setDecomposition(Collator.CANONICAL_DECOMPOSITION); 873 } catch (UnsupportedOperationException expected) { 874 } 875 assertNotEquals("getDecomposition()", -1, col1.getDecomposition()); // don't care about the value 876 877 // (base class).setMaxVariable() may or may not be implemented. 878 try { 879 col1.setMaxVariable(Collator.ReorderCodes.CURRENCY); 880 } catch (UnsupportedOperationException expected) { 881 } 882 assertNotEquals("getMaxVariable()", -1, col1.getMaxVariable()); // don't care about the value 883 884 // (base class).setReorderCodes() may or may not be implemented. 885 try { 886 col1.setReorderCodes(0, 1, 2); 887 } catch (UnsupportedOperationException expected) { 888 } 889 try { 890 col1.getReorderCodes(); 891 } catch (UnsupportedOperationException expected) { 892 } 893 894 assertFalse("getDisplayName()", Collator.getDisplayName(Locale.GERMAN).isEmpty()); 895 assertFalse("getDisplayName()", Collator.getDisplayName(Locale.GERMAN, Locale.ITALIAN).isEmpty()); 896 897 assertNotEquals("getLocale()", ULocale.GERMAN, col1.getLocale(ULocale.ACTUAL_LOCALE)); 898 899 // Cover Collator.setLocale() which is only package-visible. 900 Object token = Collator.registerInstance(new TestCollator(), new ULocale("de-Japn-419")); 901 Collator.unregister(token); 902 903 // Freezable default implementations. freeze() may or may not be implemented. 904 assertFalse("not yet frozen", col2.isFrozen()); 905 try { 906 col2.freeze(); 907 assertTrue("now frozen", col2.isFrozen()); 908 } catch (UnsupportedOperationException expected) { 909 } 910 try { 911 col2.setStrength(Collator.PRIMARY); 912 if (col2.isFrozen()) { 913 fail("(frozen Collator).setStrength() should throw an exception"); 914 } 915 } catch (UnsupportedOperationException expected) { 916 } 917 try { 918 Collator col3 = col2.cloneAsThawed(); 919 assertFalse("!cloneAsThawed().isFrozen()", col3.isFrozen()); 920 } catch (UnsupportedOperationException expected) { 921 } 922 } 923 924 /** 925 * Simple test the collator setter and getters. 926 * Similar to C++ apicoll.cpp TestAttribute(). 927 */ 928 @Test 929 public void TestSetGet() 930 { 931 RuleBasedCollator collator = (RuleBasedCollator)Collator.getInstance(); 932 int decomp = collator.getDecomposition(); 933 int strength = collator.getStrength(); 934 boolean alt = collator.isAlternateHandlingShifted(); 935 boolean caselevel = collator.isCaseLevel(); 936 boolean french = collator.isFrenchCollation(); 937 boolean hquart = collator.isHiraganaQuaternary(); 938 boolean lowercase = collator.isLowerCaseFirst(); 939 boolean uppercase = collator.isUpperCaseFirst(); 940 941 collator.setDecomposition(Collator.CANONICAL_DECOMPOSITION); 942 if (collator.getDecomposition() != Collator.CANONICAL_DECOMPOSITION) { 943 errln("Setting decomposition failed"); 944 } 945 collator.setStrength(Collator.QUATERNARY); 946 if (collator.getStrength() != Collator.QUATERNARY) { 947 errln("Setting strength failed"); 948 } 949 collator.setAlternateHandlingShifted(!alt); 950 if (collator.isAlternateHandlingShifted() == alt) { 951 errln("Setting alternate handling failed"); 952 } 953 collator.setCaseLevel(!caselevel); 954 if (collator.isCaseLevel() == caselevel) { 955 errln("Setting case level failed"); 956 } 957 collator.setFrenchCollation(!french); 958 if (collator.isFrenchCollation() == french) { 959 errln("Setting french collation failed"); 960 } 961 collator.setHiraganaQuaternary(!hquart); 962 if (collator.isHiraganaQuaternary() != hquart) { 963 errln("Setting hiragana quartenary worked but should be a no-op since ICU 50"); 964 } 965 collator.setLowerCaseFirst(!lowercase); 966 if (collator.isLowerCaseFirst() == lowercase) { 967 errln("Setting lower case first failed"); 968 } 969 collator.setUpperCaseFirst(!uppercase); 970 if (collator.isUpperCaseFirst() == uppercase) { 971 errln("Setting upper case first failed"); 972 } 973 collator.setDecompositionDefault(); 974 if (collator.getDecomposition() != decomp) { 975 errln("Setting decomposition default failed"); 976 } 977 collator.setStrengthDefault(); 978 if (collator.getStrength() != strength) { 979 errln("Setting strength default failed"); 980 } 981 collator.setAlternateHandlingDefault(); 982 if (collator.isAlternateHandlingShifted() != alt) { 983 errln("Setting alternate handling default failed"); 984 } 985 collator.setCaseLevelDefault(); 986 if (collator.isCaseLevel() != caselevel) { 987 errln("Setting case level default failed"); 988 } 989 collator.setFrenchCollationDefault(); 990 if (collator.isFrenchCollation() != french) { 991 errln("Setting french handling default failed"); 992 } 993 collator.setHiraganaQuaternaryDefault(); 994 if (collator.isHiraganaQuaternary() != hquart) { 995 errln("Setting Hiragana Quartenary default failed"); 996 } 997 collator.setCaseFirstDefault(); 998 if (collator.isLowerCaseFirst() != lowercase 999 || collator.isUpperCaseFirst() != uppercase) { 1000 errln("Setting case first handling default failed"); 1001 } 1002 } 1003 1004 @Test 1005 public void TestVariableTopSetting() { 1006 // Use the root collator, not the default collator. 1007 // This test fails with en_US_POSIX which tailors the dollar sign after 'A'. 1008 RuleBasedCollator coll = (RuleBasedCollator)Collator.getInstance(ULocale.ROOT); 1009 1010 int oldVarTop = coll.getVariableTop(); 1011 1012 // ICU 53+: The character must be in a supported reordering group, 1013 // and the variable top is pinned to the end of that group. 1014 try { 1015 coll.setVariableTop("A"); 1016 errln("setVariableTop(letter) did not detect illegal argument"); 1017 } catch(IllegalArgumentException expected) { 1018 } 1019 1020 // dollar sign (currency symbol) 1021 int newVarTop = coll.setVariableTop("$"); 1022 1023 if(newVarTop != coll.getVariableTop()) { 1024 errln("setVariableTop(dollar sign) != following getVariableTop()"); 1025 } 1026 1027 String dollar = "$"; 1028 String euro = "\u20AC"; 1029 int newVarTop2 = coll.setVariableTop(euro); 1030 assertEquals("setVariableTop(Euro sign) == following getVariableTop()", 1031 newVarTop2, coll.getVariableTop()); 1032 assertEquals("setVariableTop(Euro sign) == setVariableTop(dollar sign) (should pin to top of currency group)", 1033 newVarTop2, newVarTop); 1034 1035 coll.setAlternateHandlingShifted(true); 1036 assertEquals("empty==dollar", 0, coll.compare("", dollar)); // UCOL_EQUAL 1037 assertEquals("empty==euro", 0, coll.compare("", euro)); // UCOL_EQUAL 1038 assertEquals("dollar<zero", -1, coll.compare(dollar, "0")); // UCOL_LESS 1039 1040 coll.setVariableTop(oldVarTop); 1041 1042 int newerVarTop = coll.setVariableTop("$"); 1043 1044 if(newVarTop != newerVarTop) { 1045 errln("Didn't set vartop properly from String!\n"); 1046 } 1047 } 1048 1049 @Test 1050 public void TestMaxVariable() { 1051 RuleBasedCollator coll = (RuleBasedCollator)Collator.getInstance(ULocale.ROOT); 1052 1053 try { 1054 coll.setMaxVariable(Collator.ReorderCodes.OTHERS); 1055 errln("setMaxVariable(others) did not detect illegal argument"); 1056 } catch(IllegalArgumentException expected) { 1057 } 1058 1059 coll.setMaxVariable(Collator.ReorderCodes.CURRENCY); 1060 1061 if(Collator.ReorderCodes.CURRENCY != coll.getMaxVariable()) { 1062 errln("setMaxVariable(currency) != following getMaxVariable()"); 1063 } 1064 1065 coll.setAlternateHandlingShifted(true); 1066 assertEquals("empty==dollar", 0, coll.compare("", "$")); // UCOL_EQUAL 1067 assertEquals("empty==euro", 0, coll.compare("", "\u20AC")); // UCOL_EQUAL 1068 assertEquals("dollar<zero", -1, coll.compare("$", "0")); // UCOL_LESS 1069 } 1070 1071 @Test 1072 public void TestGetLocale() { 1073 String rules = "&a<x<y<z"; 1074 1075 Collator coll = Collator.getInstance(new ULocale("root")); 1076 ULocale locale = coll.getLocale(ULocale.ACTUAL_LOCALE); 1077 if(!locale.equals(ULocale.ROOT)) { 1078 errln("Collator.getInstance(\"root\").getLocale(actual) != ULocale.ROOT; " + 1079 "getLocale().getName() = \"" + locale.getName() + "\""); 1080 } 1081 1082 coll = Collator.getInstance(new ULocale("")); 1083 locale = coll.getLocale(ULocale.ACTUAL_LOCALE); 1084 if(!locale.equals(ULocale.ROOT)) { 1085 errln("Collator.getInstance(\"\").getLocale(actual) != ULocale.ROOT; " + 1086 "getLocale().getName() = \"" + locale.getName() + "\""); 1087 } 1088 1089 int i = 0; 1090 1091 String[][] testStruct = { 1092 // requestedLocale, validLocale, actualLocale 1093 // Note: ULocale.ROOT.getName() == "" not "root". 1094 { "de_DE", "de", "" }, 1095 { "sr_RS", "sr_Cyrl_RS", "sr" }, 1096 { "en_US_CALIFORNIA", "en_US", "" }, 1097 { "fr_FR_NONEXISTANT", "fr", "" }, 1098 // pinyin is the default, therefore suppressed. 1099 { "zh_CN", "zh_Hans_CN", "zh" }, 1100 // zh_Hant has default=stroke but the data is in zh. 1101 { "zh_TW", "zh_Hant_TW", "zh@collation=stroke" }, 1102 { "zh_TW@collation=pinyin", "zh_Hant_TW@collation=pinyin", "zh" }, 1103 { "zh_CN@collation=stroke", "zh_Hans_CN@collation=stroke", "zh@collation=stroke" }, 1104 // yue/yue_Hant aliased to zh_Hant, yue_Hans aliased to zh_Hans. 1105 { "yue", "zh_Hant", "zh@collation=stroke" }, 1106 { "yue_HK", "zh_Hant", "zh@collation=stroke" }, 1107 { "yue_Hant", "zh_Hant", "zh@collation=stroke" }, 1108 { "yue_Hant_HK", "zh_Hant", "zh@collation=stroke" }, 1109 { "yue@collation=pinyin", "zh_Hant@collation=pinyin", "zh" }, 1110 { "yue_HK@collation=pinyin", "zh_Hant@collation=pinyin", "zh" }, 1111 { "yue_CN", "zh_Hans", "zh" }, 1112 { "yue_Hans", "zh_Hans", "zh" }, 1113 { "yue_Hans_CN", "zh_Hans", "zh" }, 1114 { "yue_Hans@collation=stroke", "zh_Hans@collation=stroke", "zh@collation=stroke" }, 1115 { "yue_CN@collation=stroke", "zh_Hans@collation=stroke", "zh@collation=stroke" } 1116 }; 1117 1118 /* test opening collators for different locales */ 1119 for(i = 0; i<testStruct.length; i++) { 1120 String requestedLocale = testStruct[i][0]; 1121 String validLocale = testStruct[i][1]; 1122 String actualLocale = testStruct[i][2]; 1123 try { 1124 coll = Collator.getInstance(new ULocale(requestedLocale)); 1125 } catch(Exception e) { 1126 errln(String.format("Failed to open collator for %s with %s", requestedLocale, e)); 1127 continue; 1128 } 1129 // Note: C++ getLocale() recognizes ULOC_REQUESTED_LOCALE 1130 // which does not exist in Java. 1131 locale = coll.getLocale(ULocale.VALID_LOCALE); 1132 if(!locale.equals(new ULocale(validLocale))) { 1133 errln(String.format("[Coll %s]: Error in valid locale, expected %s, got %s", 1134 requestedLocale, validLocale, locale.getName())); 1135 } 1136 locale = coll.getLocale(ULocale.ACTUAL_LOCALE); 1137 if(!locale.equals(new ULocale(actualLocale))) { 1138 errln(String.format("[Coll %s]: Error in actual locale, expected %s, got %s", 1139 requestedLocale, actualLocale, locale.getName())); 1140 } 1141 // If we open a collator for the actual locale, we should get an equivalent one again. 1142 Collator coll2; 1143 try { 1144 coll2 = Collator.getInstance(locale); 1145 } catch(Exception e) { 1146 errln(String.format("Failed to open collator for actual locale \"%s\" with %s", 1147 locale.getName(), e)); 1148 continue; 1149 } 1150 ULocale actual2 = coll2.getLocale(ULocale.ACTUAL_LOCALE); 1151 if(!actual2.equals(locale)) { 1152 errln(String.format("[Coll actual \"%s\"]: Error in actual locale, got different one: \"%s\"", 1153 locale.getName(), actual2.getName())); 1154 } 1155 if(!coll2.equals(coll)) { 1156 errln(String.format("[Coll actual \"%s\"]: Got different collator than before", 1157 locale.getName())); 1158 } 1159 } 1160 1161 /* completely non-existent locale for collator should get a root collator */ 1162 { 1163 try { 1164 coll = Collator.getInstance(new ULocale("blahaha")); 1165 } catch(Exception e) { 1166 errln("Failed to open collator with " + e); 1167 return; 1168 } 1169 ULocale valid = coll.getLocale(ULocale.VALID_LOCALE); 1170 String name = valid.getName(); 1171 if(name.length() != 0 && !name.equals("root")) { 1172 errln("Valid locale for nonexisting locale collator is \"" + name + "\" not root"); 1173 } 1174 ULocale actual = coll.getLocale(ULocale.ACTUAL_LOCALE); 1175 name = actual.getName(); 1176 if(name.length() != 0 && !name.equals("root")) { 1177 errln("Actual locale for nonexisting locale collator is \"" + name + "\" not root"); 1178 } 1179 } 1180 1181 /* collator instantiated from rules should have all locales null */ 1182 try { 1183 coll = new RuleBasedCollator(rules); 1184 } catch (Exception e) { 1185 errln("RuleBasedCollator(" + rules + ") failed: " + e); 1186 return; 1187 } 1188 locale = coll.getLocale(ULocale.VALID_LOCALE); 1189 if(locale != null) { 1190 errln(String.format("For collator instantiated from rules, valid locale %s is not bogus", 1191 locale.getName())); 1192 } 1193 locale = coll.getLocale(ULocale.ACTUAL_LOCALE); 1194 if(locale != null) { 1195 errln(String.format("For collator instantiated from rules, actual locale %s is not bogus", 1196 locale.getName())); 1197 } 1198 } 1199 1200 @Test 1201 public void TestBounds() 1202 { 1203 Collator coll = Collator.getInstance(new Locale("sh", "")); 1204 1205 String test[] = { "John Smith", "JOHN SMITH", 1206 "john SMITH", "j\u00F6hn sm\u00EFth", 1207 "J\u00F6hn Sm\u00EFth", "J\u00D6HN SM\u00CFTH", 1208 "john smithsonian", "John Smithsonian", 1209 }; 1210 1211 String testStr[] = { 1212 "\u010CAKI MIHALJ", 1213 "\u010CAKI MIHALJ", 1214 "\u010CAKI PIRO\u0160KA", 1215 "\u010CABAI ANDRIJA", 1216 "\u010CABAI LAJO\u0160", 1217 "\u010CABAI MARIJA", 1218 "\u010CABAI STEVAN", 1219 "\u010CABAI STEVAN", 1220 "\u010CABARKAPA BRANKO", 1221 "\u010CABARKAPA MILENKO", 1222 "\u010CABARKAPA MIROSLAV", 1223 "\u010CABARKAPA SIMO", 1224 "\u010CABARKAPA STANKO", 1225 "\u010CABARKAPA TAMARA", 1226 "\u010CABARKAPA TOMA\u0160", 1227 "\u010CABDARI\u0106 NIKOLA", 1228 "\u010CABDARI\u0106 ZORICA", 1229 "\u010CABI NANDOR", 1230 "\u010CABOVI\u0106 MILAN", 1231 "\u010CABRADI AGNEZIJA", 1232 "\u010CABRADI IVAN", 1233 "\u010CABRADI JELENA", 1234 "\u010CABRADI LJUBICA", 1235 "\u010CABRADI STEVAN", 1236 "\u010CABRDA MARTIN", 1237 "\u010CABRILO BOGDAN", 1238 "\u010CABRILO BRANISLAV", 1239 "\u010CABRILO LAZAR", 1240 "\u010CABRILO LJUBICA", 1241 "\u010CABRILO SPASOJA", 1242 "\u010CADE\u0160 ZDENKA", 1243 "\u010CADESKI BLAGOJE", 1244 "\u010CADOVSKI VLADIMIR", 1245 "\u010CAGLJEVI\u0106 TOMA", 1246 "\u010CAGOROVI\u0106 VLADIMIR", 1247 "\u010CAJA VANKA", 1248 "\u010CAJI\u0106 BOGOLJUB", 1249 "\u010CAJI\u0106 BORISLAV", 1250 "\u010CAJI\u0106 RADOSLAV", 1251 "\u010CAK\u0160IRAN MILADIN", 1252 "\u010CAKAN EUGEN", 1253 "\u010CAKAN EVGENIJE", 1254 "\u010CAKAN IVAN", 1255 "\u010CAKAN JULIJAN", 1256 "\u010CAKAN MIHAJLO", 1257 "\u010CAKAN STEVAN", 1258 "\u010CAKAN VLADIMIR", 1259 "\u010CAKAN VLADIMIR", 1260 "\u010CAKAN VLADIMIR", 1261 "\u010CAKARA ANA", 1262 "\u010CAKAREVI\u0106 MOMIR", 1263 "\u010CAKAREVI\u0106 NEDELJKO", 1264 "\u010CAKI \u0160ANDOR", 1265 "\u010CAKI AMALIJA", 1266 "\u010CAKI ANDRA\u0160", 1267 "\u010CAKI LADISLAV", 1268 "\u010CAKI LAJO\u0160", 1269 "\u010CAKI LASLO" }; 1270 1271 CollationKey testKey[] = new CollationKey[testStr.length]; 1272 for (int i = 0; i < testStr.length; i ++) { 1273 testKey[i] = coll.getCollationKey(testStr[i]); 1274 } 1275 1276 Arrays.sort(testKey); 1277 for(int i = 0; i < testKey.length - 1; i ++) { 1278 CollationKey lower 1279 = testKey[i].getBound(CollationKey.BoundMode.LOWER, 1280 Collator.SECONDARY); 1281 for (int j = i + 1; j < testKey.length; j ++) { 1282 CollationKey upper 1283 = testKey[j].getBound(CollationKey.BoundMode.UPPER, 1284 Collator.SECONDARY); 1285 for (int k = i; k <= j; k ++) { 1286 if (lower.compareTo(testKey[k]) > 0) { 1287 errln("Problem with lower bound at i = " + i + " j = " 1288 + j + " k = " + k); 1289 } 1290 if (upper.compareTo(testKey[k]) <= 0) { 1291 errln("Problem with upper bound at i = " + i + " j = " 1292 + j + " k = " + k); 1293 } 1294 } 1295 } 1296 } 1297 1298 for (int i = 0; i < test.length; i ++) 1299 { 1300 CollationKey key = coll.getCollationKey(test[i]); 1301 CollationKey lower = key.getBound(CollationKey.BoundMode.LOWER, 1302 Collator.SECONDARY); 1303 CollationKey upper = key.getBound(CollationKey.BoundMode.UPPER_LONG, 1304 Collator.SECONDARY); 1305 for (int j = i + 1; j < test.length; j ++) { 1306 key = coll.getCollationKey(test[j]); 1307 if (lower.compareTo(key) > 0) { 1308 errln("Problem with lower bound i = " + i + " j = " + j); 1309 } 1310 if (upper.compareTo(key) <= 0) { 1311 errln("Problem with upper bound i = " + i + " j = " + j); 1312 } 1313 } 1314 } 1315 } 1316 1317 @Test 1318 public final void TestGetAll() { 1319 Locale[] list = Collator.getAvailableLocales(); 1320 int errorCount = 0; 1321 for (int i = 0; i < list.length; ++i) { 1322 log("Locale name: "); 1323 log(list[i].toString()); 1324 log(" , the display name is : "); 1325 logln(list[i].getDisplayName()); 1326 try{ 1327 logln(" ...... Or display as: " + Collator.getDisplayName(list[i])); 1328 logln(" ...... and display in Chinese: " + 1329 Collator.getDisplayName(list[i],Locale.CHINA)); 1330 }catch(MissingResourceException ex){ 1331 errorCount++; 1332 logln("could not get displayName for " + list[i]); 1333 } 1334 } 1335 if(errorCount>0){ 1336 warnln("Could not load the locale data."); 1337 } 1338 } 1339 1340 private boolean 1341 doSetsTest(UnicodeSet ref, UnicodeSet set, String inSet, String outSet) { 1342 boolean ok = true; 1343 set.clear(); 1344 set.applyPattern(inSet); 1345 1346 if(!ref.containsAll(set)) { 1347 err("Some stuff from "+inSet+" is not present in the set.\nMissing:"+ 1348 set.removeAll(ref).toPattern(true)+"\n"); 1349 ok = false; 1350 } 1351 1352 set.clear(); 1353 set.applyPattern(outSet); 1354 if(!ref.containsNone(set)) { 1355 err("Some stuff from "+outSet+" is present in the set.\nUnexpected:"+ 1356 set.retainAll(ref).toPattern(true)+"\n"); 1357 ok = false; 1358 } 1359 return ok; 1360 } 1361 1362 // capitst.c/TestGetContractionsAndUnsafes() 1363 @Test 1364 public void TestGetContractions() throws Exception { 1365 /* static struct { 1366 const char* locale; 1367 const char* inConts; 1368 const char* outConts; 1369 const char* inExp; 1370 const char* outExp; 1371 const char* unsafeCodeUnits; 1372 const char* safeCodeUnits; 1373 } 1374 */ 1375 String tests[][] = { 1376 { "ru", 1377 "[{\u0418\u0306}{\u0438\u0306}]", 1378 "[\u0439\u0457]", 1379 "[\u00e6]", 1380 "[ae]", 1381 "[\u0418\u0438]", 1382 "[aAbBxv]" 1383 }, 1384 { "uk", 1385 "[{\u0406\u0308}{\u0456\u0308}{\u0418\u0306}{\u0438\u0306}]", 1386 "[\u0407\u0419\u0439\u0457]", 1387 "[\u00e6]", 1388 "[ae]", 1389 "[\u0406\u0456\u0418\u0438]", 1390 "[aAbBxv]" 1391 }, 1392 { "sh", 1393 "[{C\u0301}{C\u030C}{C\u0341}{DZ\u030C}{Dz\u030C}{D\u017D}{D\u017E}{lj}{nj}]", 1394 "[{\u309d\u3099}{\u30fd\u3099}]", 1395 "[\u00e6]", 1396 "[a]", 1397 "[nlcdzNLCDZ]", 1398 "[jabv]" 1399 }, 1400 { "ja", 1401 /* 1402 * The "collv2" builder omits mappings if the collator maps their 1403 * character sequences to the same CEs. 1404 * For example, it omits Japanese contractions for NFD forms 1405 * of the voiced iteration mark (U+309E = U+309D + U+3099), such as 1406 * {\u3053\u3099\u309D\u3099}{\u3053\u309D\u3099} 1407 * {\u30B3\u3099\u30FD\u3099}{\u30B3\u30FD\u3099}. 1408 * It does add mappings for the precomposed forms. 1409 */ 1410 "[{\u3053\u3099\u309D}{\u3053\u3099\u309E}{\u3053\u3099\u30FC}" + 1411 "{\u3053\u309D}{\u3053\u309E}{\u3053\u30FC}" + 1412 "{\u30B3\u3099\u30FC}{\u30B3\u3099\u30FD}{\u30B3\u3099\u30FE}" + 1413 "{\u30B3\u30FC}{\u30B3\u30FD}{\u30B3\u30FE}]", 1414 "[{\u30FD\u3099}{\u309D\u3099}{\u3053\u3099}{\u30B3\u3099}{lj}{nj}]", 1415 "[\u30FE\u00e6]", 1416 "[a]", 1417 "[\u3099]", 1418 "[]" 1419 } 1420 }; 1421 1422 RuleBasedCollator coll = null; 1423 int i = 0; 1424 UnicodeSet conts = new UnicodeSet(); 1425 UnicodeSet exp = new UnicodeSet(); 1426 UnicodeSet set = new UnicodeSet(); 1427 1428 for(i = 0; i < tests.length; i++) { 1429 logln("Testing locale: "+ tests[i][0]); 1430 coll = (RuleBasedCollator)Collator.getInstance(new ULocale(tests[i][0])); 1431 coll.getContractionsAndExpansions(conts, exp, true); 1432 boolean ok = true; 1433 logln("Contractions "+conts.size()+":\n"+conts.toPattern(true)); 1434 ok &= doSetsTest(conts, set, tests[i][1], tests[i][2]); 1435 logln("Expansions "+exp.size()+":\n"+exp.toPattern(true)); 1436 ok &= doSetsTest(exp, set, tests[i][3], tests[i][4]); 1437 if(!ok) { 1438 // In case of failure, log the rule string for better diagnostics. 1439 String rules = coll.getRules(false); 1440 logln("Collation rules (getLocale()="+ 1441 coll.getLocale(ULocale.ACTUAL_LOCALE).toString()+"): "+ 1442 Utility.escape(rules)); 1443 } 1444 1445 // No unsafe set in ICU4J 1446 //noConts = ucol_getUnsafeSet(coll, conts, &status); 1447 //doSetsTest(conts, set, tests[i][5], tests[i][6]); 1448 //log_verbose("Unsafes "+conts.size()+":\n"+conts.toPattern(true)+"\n"); 1449 } 1450 } 1451 private static final String bigone = "One"; 1452 private static final String littleone = "one"; 1453 1454 @Test 1455 public void TestClone() { 1456 logln("\ninit c0"); 1457 RuleBasedCollator c0 = (RuleBasedCollator)Collator.getInstance(); 1458 c0.setStrength(Collator.TERTIARY); 1459 dump("c0", c0); 1460 1461 logln("\ninit c1"); 1462 RuleBasedCollator c1 = (RuleBasedCollator)Collator.getInstance(); 1463 c1.setStrength(Collator.TERTIARY); 1464 c1.setUpperCaseFirst(!c1.isUpperCaseFirst()); 1465 dump("c0", c0); 1466 dump("c1", c1); 1467 try{ 1468 logln("\ninit c2"); 1469 RuleBasedCollator c2 = (RuleBasedCollator)c1.clone(); 1470 c2.setUpperCaseFirst(!c2.isUpperCaseFirst()); 1471 dump("c0", c0); 1472 dump("c1", c1); 1473 dump("c2", c2); 1474 if(c1.equals(c2)){ 1475 errln("The cloned objects refer to same data"); 1476 } 1477 }catch(CloneNotSupportedException ex){ 1478 errln("Could not clone the collator"); 1479 } 1480 } 1481 1482 private void dump(String msg, RuleBasedCollator c) { 1483 logln(msg + " " + c.compare(bigone, littleone) + 1484 " s: " + c.getStrength() + 1485 " u: " + c.isUpperCaseFirst()); 1486 } 1487 1488 @Test 1489 public void TestIterNumeric() throws Exception { // misnomer for Java, but parallel with C++ test 1490 // Regression test for ticket #9915. 1491 // The collation code sometimes masked the continuation marker away 1492 // but later tested the result for isContinuation(). 1493 // This test case failed because the third bytes of the computed numeric-collation primaries 1494 // were permutated with the script reordering table. 1495 // It should have been possible to reproduce this with the root collator 1496 // and characters with appropriate 3-byte primary weights. 1497 // The effectiveness of this test depends completely on the collation elements 1498 // and on the implementation code. 1499 RuleBasedCollator coll = new RuleBasedCollator("[reorder Hang Hani]"); 1500 coll.setNumericCollation(true); 1501 int result = coll.compare("40", "72"); 1502 assertTrue("40<72", result < 0); 1503 } 1504 1505 /* 1506 * Tests the method public void setStrength(int newStrength) 1507 */ 1508 @Test 1509 public void TestSetStrength() { 1510 // Tests when if ((newStrength != PRIMARY) && ... ) is true 1511 int[] cases = { -1, 4, 5 }; 1512 for (int i = 0; i < cases.length; i++) { 1513 try { 1514 // Assuming -1 is not one of the values 1515 Collator c = Collator.getInstance(); 1516 c.setStrength(cases[i]); 1517 errln("Collator.setStrength(int) is suppose to return " 1518 + "an exception for an invalid newStrength value of " + cases[i]); 1519 } catch (Exception e) { 1520 } 1521 } 1522 } 1523 1524 /* 1525 * Tests the method public void setDecomposition(int decomposition) 1526 */ 1527 @Test 1528 public void TestSetDecomposition() { 1529 // Tests when if ((decomposition != NO_DECOMPOSITION) && ...) is true 1530 int[] cases = { 0, 1, 14, 15, 18, 19 }; 1531 for (int i = 0; i < cases.length; i++) { 1532 try { 1533 // Assuming -1 is not one of the values 1534 Collator c = Collator.getInstance(); 1535 c.setDecomposition(cases[i]); 1536 errln("Collator.setDecomposition(int) is suppose to return " 1537 + "an exception for an invalid decomposition value of " + cases[i]); 1538 } catch (Exception e) { 1539 } 1540 } 1541 } 1542 1543 /* 1544 * Tests the class CollatorFactory 1545 */ 1546 @Test 1547 public void TestCreateCollator() { 1548 // The following class override public Collator createCollator(Locale loc) 1549 class TestCreateCollator extends CollatorFactory { 1550 @Override 1551 public Set<String> getSupportedLocaleIDs() { 1552 return new HashSet<String>(); 1553 } 1554 1555 public TestCreateCollator() { 1556 super(); 1557 } 1558 1559 @Override 1560 public Collator createCollator(ULocale c) { 1561 return null; 1562 } 1563 } 1564 // The following class override public Collator createCollator(ULocale loc) 1565 class TestCreateCollator1 extends CollatorFactory { 1566 @Override 1567 public Set<String> getSupportedLocaleIDs() { 1568 return new HashSet<String>(); 1569 } 1570 1571 public TestCreateCollator1() { 1572 super(); 1573 } 1574 1575 @Override 1576 public Collator createCollator(Locale c) { 1577 return null; 1578 } 1579 @Override 1580 public boolean visible(){ 1581 return false; 1582 } 1583 } 1584 1585 /* 1586 * Tests the method public Collator createCollator(Locale loc) using TestCreateCollator1 class 1587 */ 1588 try { 1589 TestCreateCollator tcc = new TestCreateCollator(); 1590 tcc.createCollator(new Locale("en_US")); 1591 } catch (Exception e) { 1592 errln("Collator.createCollator(Locale) was not suppose to " + "return an exception."); 1593 } 1594 1595 /* 1596 * Tests the method public Collator createCollator(ULocale loc) using TestCreateCollator1 class 1597 */ 1598 try { 1599 TestCreateCollator1 tcc = new TestCreateCollator1(); 1600 tcc.createCollator(new ULocale("en_US")); 1601 } catch (Exception e) { 1602 errln("Collator.createCollator(ULocale) was not suppose to " + "return an exception."); 1603 } 1604 1605 /* 1606 * Tests the method public String getDisplayName(Locale objectLocale, Locale displayLocale) using TestCreateCollator1 class 1607 */ 1608 try { 1609 TestCreateCollator tcc = new TestCreateCollator(); 1610 tcc.getDisplayName(new Locale("en_US"), new Locale("jp_JP")); 1611 } catch (Exception e) { 1612 errln("Collator.getDisplayName(Locale,Locale) was not suppose to return an exception."); 1613 } 1614 1615 /* 1616 * Tests the method public String getDisplayName(ULocale objectLocale, ULocale displayLocale) using TestCreateCollator1 class 1617 */ 1618 try { 1619 TestCreateCollator1 tcc = new TestCreateCollator1(); 1620 tcc.getDisplayName(new ULocale("en_US"), new ULocale("jp_JP")); 1621 } catch (Exception e) { 1622 errln("Collator.getDisplayName(ULocale,ULocale) was not suppose to return an exception."); 1623 } 1624 } 1625 /* Tests the method 1626 * public static final String[] getKeywordValues(String keyword) 1627 */ 1628 @SuppressWarnings("static-access") 1629 @Test 1630 public void TestGetKeywordValues(){ 1631 // Tests when "if (!keyword.equals(KEYWORDS[0]))" is true 1632 String[] cases = {"","dummy"}; 1633 for(int i=0; i<cases.length; i++){ 1634 try{ 1635 Collator c = Collator.getInstance(); 1636 @SuppressWarnings("unused") 1637 String[] s = c.getKeywordValues(cases[i]); 1638 errln("Collator.getKeywordValues(String) is suppose to return " + 1639 "an exception for an invalid keyword."); 1640 } catch(Exception e){} 1641 } 1642 } 1643 1644 @Test 1645 public void TestBadKeywords() { 1646 // Test locale IDs with errors. 1647 // Valid locale IDs are tested via data-driven tests. 1648 // Note: ICU4C tests with a bogus Locale. There is no such thing in ICU4J. 1649 1650 // Unknown value. 1651 String localeID = "it-u-ks-xyz"; 1652 try { 1653 Collator.getInstance(new ULocale(localeID)); 1654 errln("Collator.getInstance(" + localeID + ") did not fail as expected"); 1655 } catch(IllegalArgumentException expected) { 1656 } catch(Exception other) { 1657 errln("Collator.getInstance(" + localeID + ") did not fail as expected - " + other); 1658 } 1659 1660 // Unsupported attributes. 1661 localeID = "it@colHiraganaQuaternary=true"; 1662 try { 1663 Collator.getInstance(new ULocale(localeID)); 1664 errln("Collator.getInstance(" + localeID + ") did not fail as expected"); 1665 } catch(UnsupportedOperationException expected) { 1666 } catch(Exception other) { 1667 errln("Collator.getInstance(" + localeID + ") did not fail as expected - " + other); 1668 } 1669 1670 localeID = "it-u-vt-u24"; 1671 try { 1672 Collator.getInstance(new ULocale(localeID)); 1673 errln("Collator.getInstance(" + localeID + ") did not fail as expected"); 1674 } catch(UnsupportedOperationException expected) { 1675 } catch(Exception other) { 1676 errln("Collator.getInstance(" + localeID + ") did not fail as expected - " + other); 1677 } 1678 } 1679 1680 @Test 1681 public void TestGapTooSmall() { 1682 // Try to tailor >20k characters into a too-small primary gap between symbols 1683 // that have 3-byte primary weights. 1684 // In FractionalUCA.txt: 1685 // 263A; [0C BA D0, 05, 05] # Zyyy So [084A.0020.0002] * WHITE SMILING FACE 1686 // 263B; [0C BA D7, 05, 05] # Zyyy So [084B.0020.0002] * BLACK SMILING FACE 1687 try { 1688 new RuleBasedCollator("&<*\u4E00-\u9FFF"); 1689 errln("no exception for primary-gap overflow"); 1690 } catch (UnsupportedOperationException e) { 1691 assertTrue("exception message mentions 'gap'", e.getMessage().contains("gap")); 1692 } catch (Exception e) { 1693 errln("unexpected exception for primary-gap overflow: " + e); 1694 } 1695 1696 // CLDR 32/ICU 60 FractionalUCA.txt makes room at the end of the symbols range 1697 // for several 2-byte primaries, or a large number of 3-byters. 1698 // The reset point is primary-before what should be 1699 // the special currency-first-primary contraction, 1700 // which is hopefully fairly stable, but not guaranteed stable. 1701 // In FractionalUCA.txt: 1702 // FDD1 20AC; [0D 70 02, 05, 05] # CURRENCY first primary 1703 try { 1704 Collator coll = new RuleBasedCollator("&[before 1]\uFDD1<*\u4E00-\u9FFF"); 1705 assertTrue("tailored Han before currency", coll.compare("\u4E00", "$") < 0); 1706 } catch (Exception e) { 1707 errln("unexpected exception for tailoring many characters at the end of symbols: " + e); 1708 } 1709 } 1710 } 1711