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 ohos.global.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 ohos.global.icu.dev.test.TestFmwk; 31 import ohos.global.icu.impl.Utility; 32 import ohos.global.icu.lang.UCharacter; 33 import ohos.global.icu.text.CollationElementIterator; 34 import ohos.global.icu.text.CollationKey; 35 import ohos.global.icu.text.Collator; 36 import ohos.global.icu.text.Collator.CollatorFactory; 37 import ohos.global.icu.text.RawCollationKey; 38 import ohos.global.icu.text.RuleBasedCollator; 39 import ohos.global.icu.text.UCharacterIterator; 40 import ohos.global.icu.text.UnicodeSet; 41 import ohos.global.icu.util.ULocale; 42 import ohos.global.icu.util.VersionInfo; 43 44 45 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 TestCollationKey()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 doAssert(boolean conditions, String message)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 TestCompare()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 TestDecomposition()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 TestDuplicate()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 TestElemIter()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 TestHashCode()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 TestProperty()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 RuleBasedCollator rcol = (RuleBasedCollator)Collator.getInstance(new Locale("da", "DK")); 503 doAssert(rcol.getRules().length() != 0, "da_DK rules does not have length 0"); 504 505 try { 506 col = Collator.getInstance(Locale.FRENCH); 507 } catch (Exception e) { 508 errln("Creating French collation failed."); 509 return; 510 } 511 512 col.setStrength(Collator.PRIMARY); 513 logln("testing Collator.getStrength() method again ..."); 514 doAssert((col.getStrength() != Collator.TERTIARY), "collation object has the wrong strength"); 515 doAssert((col.getStrength() == Collator.PRIMARY), "collation object's strength is not primary difference"); 516 517 logln("testing French Collator.setStrength() method ..."); 518 col.setStrength(Collator.TERTIARY); 519 doAssert((col.getStrength() == Collator.TERTIARY), "collation object's strength is not tertiary difference"); 520 doAssert((col.getStrength() != Collator.PRIMARY), "collation object's strength is primary difference"); 521 doAssert((col.getStrength() != Collator.SECONDARY), "collation object's strength is secondary difference"); 522 523 } 524 525 @Test 526 public void TestJunkCollator(){ 527 logln("Create junk collation: "); 528 Locale abcd = new Locale("ab", "CD", ""); 529 530 Collator junk = Collator.getInstance(abcd); 531 Collator col = Collator.getInstance(); 532 533 534 String colrules = ((RuleBasedCollator)col).getRules(); 535 String junkrules = ((RuleBasedCollator)junk).getRules(); 536 doAssert(colrules == junkrules || colrules.equals(junkrules), 537 "The default collation should be returned."); 538 Collator frCol = null; 539 try { 540 frCol = Collator.getInstance(Locale.CANADA_FRENCH); 541 } catch (Exception e) { 542 errln("Creating fr_CA collator failed."); 543 return; 544 } 545 546 doAssert(!(frCol.equals(junk)), "The junk is the same as the fr_CA collator."); 547 logln("Collator property test ended."); 548 549 } 550 551 /** 552 * This tests the RuleBasedCollator 553 * - constructor/destructor 554 * - getRules 555 */ 556 @Test 557 public void TestRuleBasedColl() { 558 RuleBasedCollator col1 = null, col2 = null, col3 = null, col4 = null; 559 560 String ruleset1 = "&9 < a, A < b, B < c, C; ch, cH, Ch, CH < d, D, e, E"; 561 String ruleset2 = "&9 < a, A < b, B < c, C < d, D, e, E"; 562 String ruleset3 = "&"; 563 564 try { 565 col1 = new RuleBasedCollator(ruleset1); 566 } catch (Exception e) { 567 // only first error needs to be a warning since we exit function 568 warnln("RuleBased Collator creation failed."); 569 return; 570 } 571 572 try { 573 col2 = new RuleBasedCollator(ruleset2); 574 } catch (Exception e) { 575 errln("RuleBased Collator creation failed."); 576 return; 577 } 578 579 try { 580 // empty rules fail 581 col3 = new RuleBasedCollator(ruleset3); 582 errln("Failure: Empty rules for the collator should fail"); 583 return; 584 } catch (MissingResourceException e) { 585 warnln(e.getMessage()); 586 } catch (Exception e) { 587 logln("PASS: Empty rules for the collator failed as expected"); 588 } 589 590 Locale locale = new Locale("aa", "AA"); 591 try { 592 col3 = (RuleBasedCollator)Collator.getInstance(locale); 593 } catch (Exception e) { 594 errln("Fallback Collator creation failed.: %s"); 595 return; 596 } 597 598 try { 599 col3 = (RuleBasedCollator)Collator.getInstance(); 600 } catch (Exception e) { 601 errln("Default Collator creation failed.: %s"); 602 return; 603 } 604 605 String rule1 = col1.getRules(); 606 String rule2 = col2.getRules(); 607 String rule3 = col3.getRules(); 608 609 doAssert(!rule1.equals(rule2), "Default collator getRules failed"); 610 doAssert(!rule2.equals(rule3), "Default collator getRules failed"); 611 doAssert(!rule1.equals(rule3), "Default collator getRules failed"); 612 613 try { 614 col4 = new RuleBasedCollator(rule2); 615 } catch (Exception e) { 616 errln("RuleBased Collator creation failed."); 617 return; 618 } 619 620 String rule4 = col4.getRules(); 621 doAssert(rule2.equals(rule4), "Default collator getRules failed"); 622 // tests that modifier ! is always ignored 623 String exclamationrules = "!&a<b"; 624 // java does not allow ! to be the start of the rule 625 String thaistr = "\u0e40\u0e01\u0e2d"; 626 try { 627 RuleBasedCollator col5 = new RuleBasedCollator(exclamationrules); 628 RuleBasedCollator encol = (RuleBasedCollator) 629 Collator.getInstance(Locale.ENGLISH); 630 CollationElementIterator col5iter 631 = col5.getCollationElementIterator(thaistr); 632 CollationElementIterator encoliter 633 = encol.getCollationElementIterator( 634 thaistr); 635 while (true) { 636 // testing with en since thai has its own tailoring 637 int ce = col5iter.next(); 638 int ce2 = encoliter.next(); 639 if (ce2 != ce) { 640 errln("! modifier test failed"); 641 } 642 if (ce == CollationElementIterator.NULLORDER) { 643 break; 644 } 645 } 646 } catch (Exception e) { 647 errln("RuleBased Collator creation failed for ! modifier."); 648 return; 649 } 650 } 651 652 /** 653 * This tests the RuleBasedCollator 654 * - getRules 655 */ 656 @Test 657 public void TestRules() { 658 RuleBasedCollator coll = (RuleBasedCollator)Collator.getInstance(new Locale("","","")); //root 659 // logln("PASS: RuleBased Collator creation passed"); 660 661 662 String rules = coll.getRules(); 663 if (rules != null && rules.length() != 0) { 664 errln("Root tailored rules failed"); 665 } 666 } 667 668 @Test 669 public void TestSafeClone() { 670 String test1 = "abCda"; 671 String test2 = "abcda"; 672 673 // one default collator & two complex ones 674 RuleBasedCollator someCollators[] = { 675 (RuleBasedCollator)Collator.getInstance(Locale.ENGLISH), 676 (RuleBasedCollator)Collator.getInstance(Locale.KOREA), 677 (RuleBasedCollator)Collator.getInstance(Locale.JAPAN) 678 }; 679 RuleBasedCollator someClonedCollators[] = new RuleBasedCollator[3]; 680 681 // change orig & clone & make sure they are independent 682 683 for (int index = 0; index < someCollators.length; index ++) 684 { 685 try { 686 someClonedCollators[index] 687 = (RuleBasedCollator)someCollators[index].clone(); 688 } catch (CloneNotSupportedException e) { 689 errln("Error cloning collator"); 690 } 691 692 someClonedCollators[index].setStrength(Collator.TERTIARY); 693 someCollators[index].setStrength(Collator.PRIMARY); 694 someClonedCollators[index].setCaseLevel(false); 695 someCollators[index].setCaseLevel(false); 696 697 doAssert(someClonedCollators[index].compare(test1, test2) > 0, 698 "Result should be \"abCda\" >>> \"abcda\" "); 699 doAssert(someCollators[index].compare(test1, test2) == 0, 700 "Result should be \"abCda\" == \"abcda\" "); 701 } 702 } 703 704 @Test 705 public void TestGetTailoredSet() 706 { 707 logln("testing getTailoredSet..."); 708 String rules[] = { 709 "&a < \u212b", 710 "& S < \u0161 <<< \u0160", 711 }; 712 String data[][] = { 713 { "\u212b", "A\u030a", "\u00c5" }, 714 { "\u0161", "s\u030C", "\u0160", "S\u030C" } 715 }; 716 717 int i = 0, j = 0; 718 719 RuleBasedCollator coll; 720 UnicodeSet set; 721 722 for(i = 0; i < rules.length; i++) { 723 try { 724 logln("Instantiating a collator from "+rules[i]); 725 coll = new RuleBasedCollator(rules[i]); 726 set = coll.getTailoredSet(); 727 logln("Got set: "+set.toPattern(true)); 728 if(set.size() < data[i].length) { 729 errln("Tailored set size smaller ("+set.size()+") than expected ("+data[i].length+")"); 730 } 731 for(j = 0; j < data[i].length; j++) { 732 logln("Checking to see whether "+data[i][j]+" is in set"); 733 if(!set.contains(data[i][j])) { 734 errln("Tailored set doesn't contain "+data[i][j]+"... It should"); 735 } 736 } 737 } catch (Exception e) { 738 warnln("Couldn't open collator with rules "+ rules[i]); 739 } 740 } 741 } 742 743 /** 744 * Simple test to see if Collator is subclassable. 745 * Also test coverage of base class methods that are overridden by RuleBasedCollator. 746 */ 747 @Test 748 public void TestSubClass() 749 { 750 class TestCollator extends Collator 751 { 752 @Override 753 public boolean equals(Object that) { 754 return this == that; 755 } 756 757 @Override 758 public int hashCode() { 759 return 0; 760 } 761 762 @Override 763 public int compare(String source, String target) { 764 return source.compareTo(target); 765 } 766 767 @Override 768 public CollationKey getCollationKey(String source) 769 { return new CollationKey(source, 770 getRawCollationKey(source, new RawCollationKey())); 771 } 772 773 @Override 774 public RawCollationKey getRawCollationKey(String source, 775 RawCollationKey key) 776 { 777 byte temp1[] = source.getBytes(); 778 byte temp2[] = new byte[temp1.length + 1]; 779 System.arraycopy(temp1, 0, temp2, 0, temp1.length); 780 temp2[temp1.length] = 0; 781 if (key == null) { 782 key = new RawCollationKey(); 783 } 784 key.bytes = temp2; 785 key.size = temp2.length; 786 return key; 787 } 788 789 @Override 790 public void setVariableTop(int ce) 791 { 792 if (isFrozen()) { 793 throw new UnsupportedOperationException("Attempt to modify frozen object"); 794 } 795 } 796 797 @Override 798 public int setVariableTop(String str) 799 { 800 if (isFrozen()) { 801 throw new UnsupportedOperationException("Attempt to modify frozen object"); 802 } 803 804 return 0; 805 } 806 807 @Override 808 public int getVariableTop() 809 { 810 return 0; 811 } 812 @Override 813 public VersionInfo getVersion() 814 { 815 return VersionInfo.getInstance(0); 816 } 817 @Override 818 public VersionInfo getUCAVersion() 819 { 820 return VersionInfo.getInstance(0); 821 } 822 } 823 824 Collator col1 = new TestCollator(); 825 Collator col2 = new TestCollator(); 826 if (col1.equals(col2)) { 827 errln("2 different instance of TestCollator should fail"); 828 } 829 if (col1.hashCode() != col2.hashCode()) { 830 errln("Every TestCollator has the same hashcode"); 831 } 832 String abc = "abc"; 833 String bcd = "bcd"; 834 if (col1.compare(abc, bcd) != abc.compareTo(bcd)) { 835 errln("TestCollator compare should be the same as the default " + 836 "string comparison"); 837 } 838 CollationKey key = col1.getCollationKey(abc); 839 byte temp1[] = abc.getBytes(); 840 byte temp2[] = new byte[temp1.length + 1]; 841 System.arraycopy(temp1, 0, temp2, 0, temp1.length); 842 temp2[temp1.length] = 0; 843 if (!java.util.Arrays.equals(key.toByteArray(), temp2) 844 || !key.getSourceString().equals(abc)) { 845 errln("TestCollator collationkey API is returning wrong values"); 846 } 847 UnicodeSet set = col1.getTailoredSet(); 848 if (!set.equals(new UnicodeSet(0, 0x10FFFF))) { 849 errln("Error getting default tailored set"); 850 } 851 852 // Base class code coverage. 853 // Most of these methods are dummies; 854 // they are overridden by any subclass that supports their features. 855 856 assertEquals("compare(strings as Object)", 0, 857 col1.compare(new StringBuilder("abc"), new StringBuffer("abc"))); 858 859 col1.setStrength(Collator.SECONDARY); 860 assertNotEquals("getStrength()", Collator.PRIMARY, col1.getStrength()); 861 862 // setStrength2() is @internal and returns this. 863 // The base class getStrength() always returns the same value, 864 // since the base class does not have a field to store the strength. 865 assertNotEquals("setStrength2().getStrength()", Collator.PRIMARY, 866 col1.setStrength2(Collator.IDENTICAL).getStrength()); 867 868 // (base class).setDecomposition() may or may not be implemented. 869 try { 870 col1.setDecomposition(Collator.CANONICAL_DECOMPOSITION); 871 } catch (UnsupportedOperationException expected) { 872 } 873 assertNotEquals("getDecomposition()", -1, col1.getDecomposition()); // don't care about the value 874 875 // (base class).setMaxVariable() may or may not be implemented. 876 try { 877 col1.setMaxVariable(Collator.ReorderCodes.CURRENCY); 878 } catch (UnsupportedOperationException expected) { 879 } 880 assertNotEquals("getMaxVariable()", -1, col1.getMaxVariable()); // don't care about the value 881 882 // (base class).setReorderCodes() may or may not be implemented. 883 try { 884 col1.setReorderCodes(0, 1, 2); 885 } catch (UnsupportedOperationException expected) { 886 } 887 try { 888 col1.getReorderCodes(); 889 } catch (UnsupportedOperationException expected) { 890 } 891 892 assertFalse("getDisplayName()", Collator.getDisplayName(Locale.GERMAN).isEmpty()); 893 assertFalse("getDisplayName()", Collator.getDisplayName(Locale.GERMAN, Locale.ITALIAN).isEmpty()); 894 895 assertNotEquals("getLocale()", ULocale.GERMAN, col1.getLocale(ULocale.ACTUAL_LOCALE)); 896 897 // Cover Collator.setLocale() which is only package-visible. 898 Object token = Collator.registerInstance(new TestCollator(), new ULocale("de-Japn-419")); 899 Collator.unregister(token); 900 901 // Freezable default implementations. freeze() may or may not be implemented. 902 assertFalse("not yet frozen", col2.isFrozen()); 903 try { 904 col2.freeze(); 905 assertTrue("now frozen", col2.isFrozen()); 906 } catch (UnsupportedOperationException expected) { 907 } 908 try { 909 col2.setStrength(Collator.PRIMARY); 910 if (col2.isFrozen()) { 911 fail("(frozen Collator).setStrength() should throw an exception"); 912 } 913 } catch (UnsupportedOperationException expected) { 914 } 915 try { 916 Collator col3 = col2.cloneAsThawed(); 917 assertFalse("!cloneAsThawed().isFrozen()", col3.isFrozen()); 918 } catch (UnsupportedOperationException expected) { 919 } 920 } 921 922 /** 923 * Simple test the collator setter and getters. 924 * Similar to C++ apicoll.cpp TestAttribute(). 925 */ 926 @Test 927 public void TestSetGet() 928 { 929 RuleBasedCollator collator = (RuleBasedCollator)Collator.getInstance(); 930 int decomp = collator.getDecomposition(); 931 int strength = collator.getStrength(); 932 boolean alt = collator.isAlternateHandlingShifted(); 933 boolean caselevel = collator.isCaseLevel(); 934 boolean french = collator.isFrenchCollation(); 935 boolean hquart = collator.isHiraganaQuaternary(); 936 boolean lowercase = collator.isLowerCaseFirst(); 937 boolean uppercase = collator.isUpperCaseFirst(); 938 939 collator.setDecomposition(Collator.CANONICAL_DECOMPOSITION); 940 if (collator.getDecomposition() != Collator.CANONICAL_DECOMPOSITION) { 941 errln("Setting decomposition failed"); 942 } 943 collator.setStrength(Collator.QUATERNARY); 944 if (collator.getStrength() != Collator.QUATERNARY) { 945 errln("Setting strength failed"); 946 } 947 collator.setAlternateHandlingShifted(!alt); 948 if (collator.isAlternateHandlingShifted() == alt) { 949 errln("Setting alternate handling failed"); 950 } 951 collator.setCaseLevel(!caselevel); 952 if (collator.isCaseLevel() == caselevel) { 953 errln("Setting case level failed"); 954 } 955 collator.setFrenchCollation(!french); 956 if (collator.isFrenchCollation() == french) { 957 errln("Setting french collation failed"); 958 } 959 collator.setHiraganaQuaternary(!hquart); 960 if (collator.isHiraganaQuaternary() != hquart) { 961 errln("Setting hiragana quartenary worked but should be a no-op since ICU 50"); 962 } 963 collator.setLowerCaseFirst(!lowercase); 964 if (collator.isLowerCaseFirst() == lowercase) { 965 errln("Setting lower case first failed"); 966 } 967 collator.setUpperCaseFirst(!uppercase); 968 if (collator.isUpperCaseFirst() == uppercase) { 969 errln("Setting upper case first failed"); 970 } 971 collator.setDecompositionDefault(); 972 if (collator.getDecomposition() != decomp) { 973 errln("Setting decomposition default failed"); 974 } 975 collator.setStrengthDefault(); 976 if (collator.getStrength() != strength) { 977 errln("Setting strength default failed"); 978 } 979 collator.setAlternateHandlingDefault(); 980 if (collator.isAlternateHandlingShifted() != alt) { 981 errln("Setting alternate handling default failed"); 982 } 983 collator.setCaseLevelDefault(); 984 if (collator.isCaseLevel() != caselevel) { 985 errln("Setting case level default failed"); 986 } 987 collator.setFrenchCollationDefault(); 988 if (collator.isFrenchCollation() != french) { 989 errln("Setting french handling default failed"); 990 } 991 collator.setHiraganaQuaternaryDefault(); 992 if (collator.isHiraganaQuaternary() != hquart) { 993 errln("Setting Hiragana Quartenary default failed"); 994 } 995 collator.setCaseFirstDefault(); 996 if (collator.isLowerCaseFirst() != lowercase 997 || collator.isUpperCaseFirst() != uppercase) { 998 errln("Setting case first handling default failed"); 999 } 1000 } 1001 1002 @Test 1003 public void TestVariableTopSetting() { 1004 // Use the root collator, not the default collator. 1005 // This test fails with en_US_POSIX which tailors the dollar sign after 'A'. 1006 RuleBasedCollator coll = (RuleBasedCollator)Collator.getInstance(ULocale.ROOT); 1007 1008 int oldVarTop = coll.getVariableTop(); 1009 1010 // ICU 53+: The character must be in a supported reordering group, 1011 // and the variable top is pinned to the end of that group. 1012 try { 1013 coll.setVariableTop("A"); 1014 errln("setVariableTop(letter) did not detect illegal argument"); 1015 } catch(IllegalArgumentException expected) { 1016 } 1017 1018 // dollar sign (currency symbol) 1019 int newVarTop = coll.setVariableTop("$"); 1020 1021 if(newVarTop != coll.getVariableTop()) { 1022 errln("setVariableTop(dollar sign) != following getVariableTop()"); 1023 } 1024 1025 String dollar = "$"; 1026 String euro = "\u20AC"; 1027 int newVarTop2 = coll.setVariableTop(euro); 1028 assertEquals("setVariableTop(Euro sign) == following getVariableTop()", 1029 newVarTop2, coll.getVariableTop()); 1030 assertEquals("setVariableTop(Euro sign) == setVariableTop(dollar sign) (should pin to top of currency group)", 1031 newVarTop2, newVarTop); 1032 1033 coll.setAlternateHandlingShifted(true); 1034 assertEquals("empty==dollar", 0, coll.compare("", dollar)); // UCOL_EQUAL 1035 assertEquals("empty==euro", 0, coll.compare("", euro)); // UCOL_EQUAL 1036 assertEquals("dollar<zero", -1, coll.compare(dollar, "0")); // UCOL_LESS 1037 1038 coll.setVariableTop(oldVarTop); 1039 1040 int newerVarTop = coll.setVariableTop("$"); 1041 1042 if(newVarTop != newerVarTop) { 1043 errln("Didn't set vartop properly from String!\n"); 1044 } 1045 } 1046 1047 @Test 1048 public void TestMaxVariable() { 1049 RuleBasedCollator coll = (RuleBasedCollator)Collator.getInstance(ULocale.ROOT); 1050 1051 try { 1052 coll.setMaxVariable(Collator.ReorderCodes.OTHERS); 1053 errln("setMaxVariable(others) did not detect illegal argument"); 1054 } catch(IllegalArgumentException expected) { 1055 } 1056 1057 coll.setMaxVariable(Collator.ReorderCodes.CURRENCY); 1058 1059 if(Collator.ReorderCodes.CURRENCY != coll.getMaxVariable()) { 1060 errln("setMaxVariable(currency) != following getMaxVariable()"); 1061 } 1062 1063 coll.setAlternateHandlingShifted(true); 1064 assertEquals("empty==dollar", 0, coll.compare("", "$")); // UCOL_EQUAL 1065 assertEquals("empty==euro", 0, coll.compare("", "\u20AC")); // UCOL_EQUAL 1066 assertEquals("dollar<zero", -1, coll.compare("$", "0")); // UCOL_LESS 1067 } 1068 1069 @Test 1070 public void TestGetLocale() { 1071 String rules = "&a<x<y<z"; 1072 1073 Collator coll = Collator.getInstance(new ULocale("root")); 1074 ULocale locale = coll.getLocale(ULocale.ACTUAL_LOCALE); 1075 if(!locale.equals(ULocale.ROOT)) { 1076 errln("Collator.getInstance(\"root\").getLocale(actual) != ULocale.ROOT; " + 1077 "getLocale().getName() = \"" + locale.getName() + "\""); 1078 } 1079 1080 coll = Collator.getInstance(new ULocale("")); 1081 locale = coll.getLocale(ULocale.ACTUAL_LOCALE); 1082 if(!locale.equals(ULocale.ROOT)) { 1083 errln("Collator.getInstance(\"\").getLocale(actual) != ULocale.ROOT; " + 1084 "getLocale().getName() = \"" + locale.getName() + "\""); 1085 } 1086 1087 int i = 0; 1088 1089 String[][] testStruct = { 1090 // requestedLocale, validLocale, actualLocale 1091 // Note: ULocale.ROOT.getName() == "" not "root". 1092 { "de_DE", "de", "" }, 1093 { "sr_RS", "sr_Cyrl_RS", "sr" }, 1094 { "en_US_CALIFORNIA", "en_US", "" }, 1095 { "fr_FR_NONEXISTANT", "fr", "" }, 1096 // pinyin is the default, therefore suppressed. 1097 { "zh_CN", "zh_Hans_CN", "zh" }, 1098 // zh_Hant has default=stroke but the data is in zh. 1099 { "zh_TW", "zh_Hant_TW", "zh@collation=stroke" }, 1100 { "zh_TW@collation=pinyin", "zh_Hant_TW@collation=pinyin", "zh" }, 1101 { "zh_CN@collation=stroke", "zh_Hans_CN@collation=stroke", "zh@collation=stroke" }, 1102 // yue/yue_Hant aliased to zh_Hant, yue_Hans aliased to zh_Hans. 1103 { "yue", "zh_Hant", "zh@collation=stroke" }, 1104 { "yue_HK", "zh_Hant", "zh@collation=stroke" }, 1105 { "yue_Hant", "zh_Hant", "zh@collation=stroke" }, 1106 { "yue_Hant_HK", "zh_Hant", "zh@collation=stroke" }, 1107 { "yue@collation=pinyin", "zh_Hant@collation=pinyin", "zh" }, 1108 { "yue_HK@collation=pinyin", "zh_Hant@collation=pinyin", "zh" }, 1109 { "yue_CN", "zh_Hans", "zh" }, 1110 { "yue_Hans", "zh_Hans", "zh" }, 1111 { "yue_Hans_CN", "zh_Hans", "zh" }, 1112 { "yue_Hans@collation=stroke", "zh_Hans@collation=stroke", "zh@collation=stroke" }, 1113 { "yue_CN@collation=stroke", "zh_Hans@collation=stroke", "zh@collation=stroke" } 1114 }; 1115 1116 /* test opening collators for different locales */ 1117 for(i = 0; i<testStruct.length; i++) { 1118 String requestedLocale = testStruct[i][0]; 1119 String validLocale = testStruct[i][1]; 1120 String actualLocale = testStruct[i][2]; 1121 try { 1122 coll = Collator.getInstance(new ULocale(requestedLocale)); 1123 } catch(Exception e) { 1124 errln(String.format("Failed to open collator for %s with %s", requestedLocale, e)); 1125 continue; 1126 } 1127 // Note: C++ getLocale() recognizes ULOC_REQUESTED_LOCALE 1128 // which does not exist in Java. 1129 locale = coll.getLocale(ULocale.VALID_LOCALE); 1130 if(!locale.equals(new ULocale(validLocale))) { 1131 errln(String.format("[Coll %s]: Error in valid locale, expected %s, got %s", 1132 requestedLocale, validLocale, locale.getName())); 1133 } 1134 locale = coll.getLocale(ULocale.ACTUAL_LOCALE); 1135 if(!locale.equals(new ULocale(actualLocale))) { 1136 errln(String.format("[Coll %s]: Error in actual locale, expected %s, got %s", 1137 requestedLocale, actualLocale, locale.getName())); 1138 } 1139 // If we open a collator for the actual locale, we should get an equivalent one again. 1140 Collator coll2; 1141 try { 1142 coll2 = Collator.getInstance(locale); 1143 } catch(Exception e) { 1144 errln(String.format("Failed to open collator for actual locale \"%s\" with %s", 1145 locale.getName(), e)); 1146 continue; 1147 } 1148 ULocale actual2 = coll2.getLocale(ULocale.ACTUAL_LOCALE); 1149 if(!actual2.equals(locale)) { 1150 errln(String.format("[Coll actual \"%s\"]: Error in actual locale, got different one: \"%s\"", 1151 locale.getName(), actual2.getName())); 1152 } 1153 if(!coll2.equals(coll)) { 1154 errln(String.format("[Coll actual \"%s\"]: Got different collator than before", 1155 locale.getName())); 1156 } 1157 } 1158 1159 /* completely non-existent locale for collator should get a root collator */ 1160 { 1161 try { 1162 coll = Collator.getInstance(new ULocale("blahaha")); 1163 } catch(Exception e) { 1164 errln("Failed to open collator with " + e); 1165 return; 1166 } 1167 ULocale valid = coll.getLocale(ULocale.VALID_LOCALE); 1168 String name = valid.getName(); 1169 if(name.length() != 0 && !name.equals("root")) { 1170 errln("Valid locale for nonexisting locale collator is \"" + name + "\" not root"); 1171 } 1172 ULocale actual = coll.getLocale(ULocale.ACTUAL_LOCALE); 1173 name = actual.getName(); 1174 if(name.length() != 0 && !name.equals("root")) { 1175 errln("Actual locale for nonexisting locale collator is \"" + name + "\" not root"); 1176 } 1177 } 1178 1179 /* collator instantiated from rules should have all locales null */ 1180 try { 1181 coll = new RuleBasedCollator(rules); 1182 } catch (Exception e) { 1183 errln("RuleBasedCollator(" + rules + ") failed: " + e); 1184 return; 1185 } 1186 locale = coll.getLocale(ULocale.VALID_LOCALE); 1187 if(locale != null) { 1188 errln(String.format("For collator instantiated from rules, valid locale %s is not bogus", 1189 locale.getName())); 1190 } 1191 locale = coll.getLocale(ULocale.ACTUAL_LOCALE); 1192 if(locale != null) { 1193 errln(String.format("For collator instantiated from rules, actual locale %s is not bogus", 1194 locale.getName())); 1195 } 1196 } 1197 1198 @Test 1199 public void TestBounds() 1200 { 1201 Collator coll = Collator.getInstance(new Locale("sh", "")); 1202 1203 String test[] = { "John Smith", "JOHN SMITH", 1204 "john SMITH", "j\u00F6hn sm\u00EFth", 1205 "J\u00F6hn Sm\u00EFth", "J\u00D6HN SM\u00CFTH", 1206 "john smithsonian", "John Smithsonian", 1207 }; 1208 1209 String testStr[] = { 1210 "\u010CAKI MIHALJ", 1211 "\u010CAKI MIHALJ", 1212 "\u010CAKI PIRO\u0160KA", 1213 "\u010CABAI ANDRIJA", 1214 "\u010CABAI LAJO\u0160", 1215 "\u010CABAI MARIJA", 1216 "\u010CABAI STEVAN", 1217 "\u010CABAI STEVAN", 1218 "\u010CABARKAPA BRANKO", 1219 "\u010CABARKAPA MILENKO", 1220 "\u010CABARKAPA MIROSLAV", 1221 "\u010CABARKAPA SIMO", 1222 "\u010CABARKAPA STANKO", 1223 "\u010CABARKAPA TAMARA", 1224 "\u010CABARKAPA TOMA\u0160", 1225 "\u010CABDARI\u0106 NIKOLA", 1226 "\u010CABDARI\u0106 ZORICA", 1227 "\u010CABI NANDOR", 1228 "\u010CABOVI\u0106 MILAN", 1229 "\u010CABRADI AGNEZIJA", 1230 "\u010CABRADI IVAN", 1231 "\u010CABRADI JELENA", 1232 "\u010CABRADI LJUBICA", 1233 "\u010CABRADI STEVAN", 1234 "\u010CABRDA MARTIN", 1235 "\u010CABRILO BOGDAN", 1236 "\u010CABRILO BRANISLAV", 1237 "\u010CABRILO LAZAR", 1238 "\u010CABRILO LJUBICA", 1239 "\u010CABRILO SPASOJA", 1240 "\u010CADE\u0160 ZDENKA", 1241 "\u010CADESKI BLAGOJE", 1242 "\u010CADOVSKI VLADIMIR", 1243 "\u010CAGLJEVI\u0106 TOMA", 1244 "\u010CAGOROVI\u0106 VLADIMIR", 1245 "\u010CAJA VANKA", 1246 "\u010CAJI\u0106 BOGOLJUB", 1247 "\u010CAJI\u0106 BORISLAV", 1248 "\u010CAJI\u0106 RADOSLAV", 1249 "\u010CAK\u0160IRAN MILADIN", 1250 "\u010CAKAN EUGEN", 1251 "\u010CAKAN EVGENIJE", 1252 "\u010CAKAN IVAN", 1253 "\u010CAKAN JULIJAN", 1254 "\u010CAKAN MIHAJLO", 1255 "\u010CAKAN STEVAN", 1256 "\u010CAKAN VLADIMIR", 1257 "\u010CAKAN VLADIMIR", 1258 "\u010CAKAN VLADIMIR", 1259 "\u010CAKARA ANA", 1260 "\u010CAKAREVI\u0106 MOMIR", 1261 "\u010CAKAREVI\u0106 NEDELJKO", 1262 "\u010CAKI \u0160ANDOR", 1263 "\u010CAKI AMALIJA", 1264 "\u010CAKI ANDRA\u0160", 1265 "\u010CAKI LADISLAV", 1266 "\u010CAKI LAJO\u0160", 1267 "\u010CAKI LASLO" }; 1268 1269 CollationKey testKey[] = new CollationKey[testStr.length]; 1270 for (int i = 0; i < testStr.length; i ++) { 1271 testKey[i] = coll.getCollationKey(testStr[i]); 1272 } 1273 1274 Arrays.sort(testKey); 1275 for(int i = 0; i < testKey.length - 1; i ++) { 1276 CollationKey lower 1277 = testKey[i].getBound(CollationKey.BoundMode.LOWER, 1278 Collator.SECONDARY); 1279 for (int j = i + 1; j < testKey.length; j ++) { 1280 CollationKey upper 1281 = testKey[j].getBound(CollationKey.BoundMode.UPPER, 1282 Collator.SECONDARY); 1283 for (int k = i; k <= j; k ++) { 1284 if (lower.compareTo(testKey[k]) > 0) { 1285 errln("Problem with lower bound at i = " + i + " j = " 1286 + j + " k = " + k); 1287 } 1288 if (upper.compareTo(testKey[k]) <= 0) { 1289 errln("Problem with upper bound at i = " + i + " j = " 1290 + j + " k = " + k); 1291 } 1292 } 1293 } 1294 } 1295 1296 for (int i = 0; i < test.length; i ++) 1297 { 1298 CollationKey key = coll.getCollationKey(test[i]); 1299 CollationKey lower = key.getBound(CollationKey.BoundMode.LOWER, 1300 Collator.SECONDARY); 1301 CollationKey upper = key.getBound(CollationKey.BoundMode.UPPER_LONG, 1302 Collator.SECONDARY); 1303 for (int j = i + 1; j < test.length; j ++) { 1304 key = coll.getCollationKey(test[j]); 1305 if (lower.compareTo(key) > 0) { 1306 errln("Problem with lower bound i = " + i + " j = " + j); 1307 } 1308 if (upper.compareTo(key) <= 0) { 1309 errln("Problem with upper bound i = " + i + " j = " + j); 1310 } 1311 } 1312 } 1313 } 1314 1315 @Test 1316 public final void TestGetAll() { 1317 Locale[] list = Collator.getAvailableLocales(); 1318 int errorCount = 0; 1319 for (int i = 0; i < list.length; ++i) { 1320 log("Locale name: "); 1321 log(list[i].toString()); 1322 log(" , the display name is : "); 1323 logln(list[i].getDisplayName()); 1324 try{ 1325 logln(" ...... Or display as: " + Collator.getDisplayName(list[i])); 1326 logln(" ...... and display in Chinese: " + 1327 Collator.getDisplayName(list[i],Locale.CHINA)); 1328 }catch(MissingResourceException ex){ 1329 errorCount++; 1330 logln("could not get displayName for " + list[i]); 1331 } 1332 } 1333 if(errorCount>0){ 1334 warnln("Could not load the locale data."); 1335 } 1336 } 1337 1338 private boolean 1339 doSetsTest(UnicodeSet ref, UnicodeSet set, String inSet, String outSet) { 1340 boolean ok = true; 1341 set.clear(); 1342 set.applyPattern(inSet); 1343 1344 if(!ref.containsAll(set)) { 1345 err("Some stuff from "+inSet+" is not present in the set.\nMissing:"+ 1346 set.removeAll(ref).toPattern(true)+"\n"); 1347 ok = false; 1348 } 1349 1350 set.clear(); 1351 set.applyPattern(outSet); 1352 if(!ref.containsNone(set)) { 1353 err("Some stuff from "+outSet+" is present in the set.\nUnexpected:"+ 1354 set.retainAll(ref).toPattern(true)+"\n"); 1355 ok = false; 1356 } 1357 return ok; 1358 } 1359 1360 // capitst.c/TestGetContractionsAndUnsafes() 1361 @Test 1362 public void TestGetContractions() throws Exception { 1363 /* static struct { 1364 const char* locale; 1365 const char* inConts; 1366 const char* outConts; 1367 const char* inExp; 1368 const char* outExp; 1369 const char* unsafeCodeUnits; 1370 const char* safeCodeUnits; 1371 } 1372 */ 1373 String tests[][] = { 1374 { "ru", 1375 "[{\u0418\u0306}{\u0438\u0306}]", 1376 "[\u0439\u0457]", 1377 "[\u00e6]", 1378 "[ae]", 1379 "[\u0418\u0438]", 1380 "[aAbBxv]" 1381 }, 1382 { "uk", 1383 "[{\u0406\u0308}{\u0456\u0308}{\u0418\u0306}{\u0438\u0306}]", 1384 "[\u0407\u0419\u0439\u0457]", 1385 "[\u00e6]", 1386 "[ae]", 1387 "[\u0406\u0456\u0418\u0438]", 1388 "[aAbBxv]" 1389 }, 1390 { "sh", 1391 "[{C\u0301}{C\u030C}{C\u0341}{DZ\u030C}{Dz\u030C}{D\u017D}{D\u017E}{lj}{nj}]", 1392 "[{\u309d\u3099}{\u30fd\u3099}]", 1393 "[\u00e6]", 1394 "[a]", 1395 "[nlcdzNLCDZ]", 1396 "[jabv]" 1397 }, 1398 { "ja", 1399 /* 1400 * The "collv2" builder omits mappings if the collator maps their 1401 * character sequences to the same CEs. 1402 * For example, it omits Japanese contractions for NFD forms 1403 * of the voiced iteration mark (U+309E = U+309D + U+3099), such as 1404 * {\u3053\u3099\u309D\u3099}{\u3053\u309D\u3099} 1405 * {\u30B3\u3099\u30FD\u3099}{\u30B3\u30FD\u3099}. 1406 * It does add mappings for the precomposed forms. 1407 */ 1408 "[{\u3053\u3099\u309D}{\u3053\u3099\u309E}{\u3053\u3099\u30FC}" + 1409 "{\u3053\u309D}{\u3053\u309E}{\u3053\u30FC}" + 1410 "{\u30B3\u3099\u30FC}{\u30B3\u3099\u30FD}{\u30B3\u3099\u30FE}" + 1411 "{\u30B3\u30FC}{\u30B3\u30FD}{\u30B3\u30FE}]", 1412 "[{\u30FD\u3099}{\u309D\u3099}{\u3053\u3099}{\u30B3\u3099}{lj}{nj}]", 1413 "[\u30FE\u00e6]", 1414 "[a]", 1415 "[\u3099]", 1416 "[]" 1417 } 1418 }; 1419 1420 RuleBasedCollator coll = null; 1421 int i = 0; 1422 UnicodeSet conts = new UnicodeSet(); 1423 UnicodeSet exp = new UnicodeSet(); 1424 UnicodeSet set = new UnicodeSet(); 1425 1426 for(i = 0; i < tests.length; i++) { 1427 logln("Testing locale: "+ tests[i][0]); 1428 coll = (RuleBasedCollator)Collator.getInstance(new ULocale(tests[i][0])); 1429 coll.getContractionsAndExpansions(conts, exp, true); 1430 boolean ok = true; 1431 logln("Contractions "+conts.size()+":\n"+conts.toPattern(true)); 1432 ok &= doSetsTest(conts, set, tests[i][1], tests[i][2]); 1433 logln("Expansions "+exp.size()+":\n"+exp.toPattern(true)); 1434 ok &= doSetsTest(exp, set, tests[i][3], tests[i][4]); 1435 if(!ok) { 1436 // In case of failure, log the rule string for better diagnostics. 1437 String rules = coll.getRules(false); 1438 logln("Collation rules (getLocale()="+ 1439 coll.getLocale(ULocale.ACTUAL_LOCALE).toString()+"): "+ 1440 Utility.escape(rules)); 1441 } 1442 1443 // No unsafe set in ICU4J 1444 //noConts = ucol_getUnsafeSet(coll, conts, &status); 1445 //doSetsTest(conts, set, tests[i][5], tests[i][6]); 1446 //log_verbose("Unsafes "+conts.size()+":\n"+conts.toPattern(true)+"\n"); 1447 } 1448 } 1449 private static final String bigone = "One"; 1450 private static final String littleone = "one"; 1451 1452 @Test 1453 public void TestClone() { 1454 logln("\ninit c0"); 1455 RuleBasedCollator c0 = (RuleBasedCollator)Collator.getInstance(); 1456 c0.setStrength(Collator.TERTIARY); 1457 dump("c0", c0); 1458 1459 logln("\ninit c1"); 1460 RuleBasedCollator c1 = (RuleBasedCollator)Collator.getInstance(); 1461 c1.setStrength(Collator.TERTIARY); 1462 c1.setUpperCaseFirst(!c1.isUpperCaseFirst()); 1463 dump("c0", c0); 1464 dump("c1", c1); 1465 try{ 1466 logln("\ninit c2"); 1467 RuleBasedCollator c2 = (RuleBasedCollator)c1.clone(); 1468 c2.setUpperCaseFirst(!c2.isUpperCaseFirst()); 1469 dump("c0", c0); 1470 dump("c1", c1); 1471 dump("c2", c2); 1472 if(c1.equals(c2)){ 1473 errln("The cloned objects refer to same data"); 1474 } 1475 }catch(CloneNotSupportedException ex){ 1476 errln("Could not clone the collator"); 1477 } 1478 } 1479 1480 private void dump(String msg, RuleBasedCollator c) { 1481 logln(msg + " " + c.compare(bigone, littleone) + 1482 " s: " + c.getStrength() + 1483 " u: " + c.isUpperCaseFirst()); 1484 } 1485 1486 @Test 1487 public void TestIterNumeric() throws Exception { // misnomer for Java, but parallel with C++ test 1488 // Regression test for ticket #9915. 1489 // The collation code sometimes masked the continuation marker away 1490 // but later tested the result for isContinuation(). 1491 // This test case failed because the third bytes of the computed numeric-collation primaries 1492 // were permutated with the script reordering table. 1493 // It should have been possible to reproduce this with the root collator 1494 // and characters with appropriate 3-byte primary weights. 1495 // The effectiveness of this test depends completely on the collation elements 1496 // and on the implementation code. 1497 RuleBasedCollator coll = new RuleBasedCollator("[reorder Hang Hani]"); 1498 coll.setNumericCollation(true); 1499 int result = coll.compare("40", "72"); 1500 assertTrue("40<72", result < 0); 1501 } 1502 1503 /* 1504 * Tests the method public void setStrength(int newStrength) 1505 */ 1506 @Test 1507 public void TestSetStrength() { 1508 // Tests when if ((newStrength != PRIMARY) && ... ) is true 1509 int[] cases = { -1, 4, 5 }; 1510 for (int i = 0; i < cases.length; i++) { 1511 try { 1512 // Assuming -1 is not one of the values 1513 Collator c = Collator.getInstance(); 1514 c.setStrength(cases[i]); 1515 errln("Collator.setStrength(int) is suppose to return " 1516 + "an exception for an invalid newStrength value of " + cases[i]); 1517 } catch (Exception e) { 1518 } 1519 } 1520 } 1521 1522 /* 1523 * Tests the method public void setDecomposition(int decomposition) 1524 */ 1525 @Test 1526 public void TestSetDecomposition() { 1527 // Tests when if ((decomposition != NO_DECOMPOSITION) && ...) is true 1528 int[] cases = { 0, 1, 14, 15, 18, 19 }; 1529 for (int i = 0; i < cases.length; i++) { 1530 try { 1531 // Assuming -1 is not one of the values 1532 Collator c = Collator.getInstance(); 1533 c.setDecomposition(cases[i]); 1534 errln("Collator.setDecomposition(int) is suppose to return " 1535 + "an exception for an invalid decomposition value of " + cases[i]); 1536 } catch (Exception e) { 1537 } 1538 } 1539 } 1540 1541 /* 1542 * Tests the class CollatorFactory 1543 */ 1544 @Test 1545 public void TestCreateCollator() { 1546 // The following class override public Collator createCollator(Locale loc) 1547 class TestCreateCollator extends CollatorFactory { 1548 @Override 1549 public Set<String> getSupportedLocaleIDs() { 1550 return new HashSet<String>(); 1551 } 1552 1553 public TestCreateCollator() { 1554 super(); 1555 } 1556 1557 @Override 1558 public Collator createCollator(ULocale c) { 1559 return null; 1560 } 1561 } 1562 // The following class override public Collator createCollator(ULocale loc) 1563 class TestCreateCollator1 extends CollatorFactory { 1564 @Override 1565 public Set<String> getSupportedLocaleIDs() { 1566 return new HashSet<String>(); 1567 } 1568 1569 public TestCreateCollator1() { 1570 super(); 1571 } 1572 1573 @Override 1574 public Collator createCollator(Locale c) { 1575 return null; 1576 } 1577 @Override 1578 public boolean visible(){ 1579 return false; 1580 } 1581 } 1582 1583 /* 1584 * Tests the method public Collator createCollator(Locale loc) using TestCreateCollator1 class 1585 */ 1586 try { 1587 TestCreateCollator tcc = new TestCreateCollator(); 1588 tcc.createCollator(new Locale("en_US")); 1589 } catch (Exception e) { 1590 errln("Collator.createCollator(Locale) was not suppose to " + "return an exception."); 1591 } 1592 1593 /* 1594 * Tests the method public Collator createCollator(ULocale loc) using TestCreateCollator1 class 1595 */ 1596 try { 1597 TestCreateCollator1 tcc = new TestCreateCollator1(); 1598 tcc.createCollator(new ULocale("en_US")); 1599 } catch (Exception e) { 1600 errln("Collator.createCollator(ULocale) was not suppose to " + "return an exception."); 1601 } 1602 1603 /* 1604 * Tests the method public String getDisplayName(Locale objectLocale, Locale displayLocale) using TestCreateCollator1 class 1605 */ 1606 try { 1607 TestCreateCollator tcc = new TestCreateCollator(); 1608 tcc.getDisplayName(new Locale("en_US"), new Locale("jp_JP")); 1609 } catch (Exception e) { 1610 errln("Collator.getDisplayName(Locale,Locale) was not suppose to return an exception."); 1611 } 1612 1613 /* 1614 * Tests the method public String getDisplayName(ULocale objectLocale, ULocale displayLocale) using TestCreateCollator1 class 1615 */ 1616 try { 1617 TestCreateCollator1 tcc = new TestCreateCollator1(); 1618 tcc.getDisplayName(new ULocale("en_US"), new ULocale("jp_JP")); 1619 } catch (Exception e) { 1620 errln("Collator.getDisplayName(ULocale,ULocale) was not suppose to return an exception."); 1621 } 1622 } 1623 /* Tests the method 1624 * public static final String[] getKeywordValues(String keyword) 1625 */ 1626 @SuppressWarnings("static-access") 1627 @Test 1628 public void TestGetKeywordValues(){ 1629 // Tests when "if (!keyword.equals(KEYWORDS[0]))" is true 1630 String[] cases = {"","dummy"}; 1631 for(int i=0; i<cases.length; i++){ 1632 try{ 1633 Collator c = Collator.getInstance(); 1634 @SuppressWarnings("unused") 1635 String[] s = c.getKeywordValues(cases[i]); 1636 errln("Collator.getKeywordValues(String) is suppose to return " + 1637 "an exception for an invalid keyword."); 1638 } catch(Exception e){} 1639 } 1640 } 1641 1642 @Test 1643 public void TestBadKeywords() { 1644 // Test locale IDs with errors. 1645 // Valid locale IDs are tested via data-driven tests. 1646 // Note: ICU4C tests with a bogus Locale. There is no such thing in ICU4J. 1647 1648 // Unknown value. 1649 String localeID = "it-u-ks-xyz"; 1650 try { 1651 Collator.getInstance(new ULocale(localeID)); 1652 errln("Collator.getInstance(" + localeID + ") did not fail as expected"); 1653 } catch(IllegalArgumentException expected) { 1654 } catch(Exception other) { 1655 errln("Collator.getInstance(" + localeID + ") did not fail as expected - " + other); 1656 } 1657 1658 // Unsupported attributes. 1659 localeID = "it@colHiraganaQuaternary=true"; 1660 try { 1661 Collator.getInstance(new ULocale(localeID)); 1662 errln("Collator.getInstance(" + localeID + ") did not fail as expected"); 1663 } catch(UnsupportedOperationException expected) { 1664 } catch(Exception other) { 1665 errln("Collator.getInstance(" + localeID + ") did not fail as expected - " + other); 1666 } 1667 1668 localeID = "it-u-vt-u24"; 1669 try { 1670 Collator.getInstance(new ULocale(localeID)); 1671 errln("Collator.getInstance(" + localeID + ") did not fail as expected"); 1672 } catch(UnsupportedOperationException expected) { 1673 } catch(Exception other) { 1674 errln("Collator.getInstance(" + localeID + ") did not fail as expected - " + other); 1675 } 1676 } 1677 1678 @Test 1679 public void TestGapTooSmall() { 1680 // Try to tailor >20k characters into a too-small primary gap between symbols 1681 // that have 3-byte primary weights. 1682 // In FractionalUCA.txt: 1683 // 263A; [0C BA D0, 05, 05] # Zyyy So [084A.0020.0002] * WHITE SMILING FACE 1684 // 263B; [0C BA D7, 05, 05] # Zyyy So [084B.0020.0002] * BLACK SMILING FACE 1685 try { 1686 new RuleBasedCollator("&☺<*\u4E00-\u9FFF"); 1687 errln("no exception for primary-gap overflow"); 1688 } catch (UnsupportedOperationException e) { 1689 assertTrue("exception message mentions 'gap'", e.getMessage().contains("gap")); 1690 } catch (Exception e) { 1691 errln("unexpected exception for primary-gap overflow: " + e); 1692 } 1693 1694 // CLDR 32/ICU 60 FractionalUCA.txt makes room at the end of the symbols range 1695 // for several 2-byte primaries, or a large number of 3-byters. 1696 // The reset point is primary-before what should be 1697 // the special currency-first-primary contraction, 1698 // which is hopefully fairly stable, but not guaranteed stable. 1699 // In FractionalUCA.txt: 1700 // FDD1 20AC; [0D 70 02, 05, 05] # CURRENCY first primary 1701 try { 1702 Collator coll = new RuleBasedCollator("&[before 1]\uFDD1€<*\u4E00-\u9FFF"); 1703 assertTrue("tailored Han before currency", coll.compare("\u4E00", "$") < 0); 1704 } catch (Exception e) { 1705 errln("unexpected exception for tailoring many characters at the end of symbols: " + e); 1706 } 1707 } 1708 } 1709