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