1 /********************************************************************
3 * Copyright (c) 1997-2014, International Business Machines Corporation and
4 * others. All Rights Reserved.
5 ********************************************************************/
6 //===============================================================================
12 // Created by: Helena Shih
14 // Modification History:
16 // Date Name Description
17 // 2/5/97 aliu Added streamIn and streamOut methods. Added
18 // constructor which reads RuleBasedCollator object from
19 // a binary file. Added writeToFile method which streams
20 // RuleBasedCollator out to a binary file. The streamIn
21 // and streamOut methods use istream and ostream objects
23 // 6/30/97 helena Added tests for CollationElementIterator::setText, getOffset
24 // setOffset and DecompositionIterator::getOffset, setOffset.
25 // DecompositionIterator is made public so add class scope
27 // 02/10/98 damiba Added test for compare(UnicodeString&, UnicodeString&, int32_t)
28 //===============================================================================
30 #include "unicode/utypes.h"
32 #if !UCONFIG_NO_COLLATION
34 #include "unicode/localpointer.h"
35 #include "unicode/coll.h"
36 #include "unicode/tblcoll.h"
37 #include "unicode/coleitr.h"
38 #include "unicode/sortkey.h"
40 #include "unicode/chariter.h"
41 #include "unicode/schriter.h"
42 #include "unicode/ustring.h"
43 #include "unicode/ucol.h"
49 #define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
52 CollationAPITest::doAssert(UBool condition
, const char *message
)
55 errln(UnicodeString("ERROR : ") + message
);
59 // Collator Class Properties
60 // ctor, dtor, createInstance, compare, getStrength/setStrength
61 // getDecomposition/setDecomposition, getDisplayName
63 CollationAPITest::TestProperty(/* char* par */)
65 UErrorCode success
= U_ZERO_ERROR
;
68 * Expected version of the English collator.
69 * Currently, the major/minor version numbers change when the builder code
71 * number 2 is from the tailoring data version and
72 * number 3 is the UCA version.
73 * This changes with every UCA version change, and the expected value
74 * needs to be adjusted.
75 * Same in cintltst/capitst.c.
77 UVersionInfo currVersionArray
= {0x31, 0xC0, 0x05, 0x2A}; // from ICU 4.4/UCA 5.2
78 UVersionInfo versionArray
;
80 logln("The property tests begin : ");
81 logln("Test ctors : ");
82 col
= Collator::createInstance(Locale::getEnglish(), success
);
83 if (U_FAILURE(success
)){
84 errcheckln(success
, "Default Collator creation failed. - %s", u_errorName(success
));
88 StringEnumeration
* kwEnum
= col
->getKeywordValuesForLocale("", Locale::getEnglish(),true,success
);
89 if (U_FAILURE(success
)){
90 errcheckln(success
, "Get Keyword Values for Locale failed. - %s", u_errorName(success
));
95 col
->getVersion(versionArray
);
96 // Check for a version greater than some value rather than equality
97 // so that we need not update the expected version each time.
98 if (uprv_memcmp(versionArray
, currVersionArray
, 4)<0) {
99 errln("Testing Collator::getVersion() - unexpected result: %02x.%02x.%02x.%02x",
100 versionArray
[0], versionArray
[1], versionArray
[2], versionArray
[3]);
102 logln("Collator::getVersion() result: %02x.%02x.%02x.%02x",
103 versionArray
[0], versionArray
[1], versionArray
[2], versionArray
[3]);
106 doAssert((col
->compare("ab", "abc") == Collator::LESS
), "ab < abc comparison failed");
107 doAssert((col
->compare("ab", "AB") == Collator::LESS
), "ab < AB comparison failed");
108 doAssert((col
->compare("blackbird", "black-bird") == Collator::GREATER
), "black-bird > blackbird comparison failed");
109 doAssert((col
->compare("black bird", "black-bird") == Collator::LESS
), "black bird > black-bird comparison failed");
110 doAssert((col
->compare("Hello", "hello") == Collator::GREATER
), "Hello > hello comparison failed");
111 doAssert((col
->compare("","",success
) == UCOL_EQUAL
), "Comparison between empty strings failed");
113 doAssert((col
->compareUTF8("\x61\x62\xc3\xa4", "\x61\x62\xc3\x9f", success
) == UCOL_LESS
), "ab a-umlaut < ab sharp-s UTF-8 comparison failed");
114 success
= U_ZERO_ERROR
;
116 UnicodeString abau
=UNICODE_STRING_SIMPLE("\\x61\\x62\\xe4").unescape();
117 UnicodeString abss
=UNICODE_STRING_SIMPLE("\\x61\\x62\\xdf").unescape();
118 UCharIterator abauIter
, abssIter
;
119 uiter_setReplaceable(&abauIter
, &abau
);
120 uiter_setReplaceable(&abssIter
, &abss
);
121 doAssert((col
->compare(abauIter
, abssIter
, success
) == UCOL_LESS
), "ab a-umlaut < ab sharp-s UCharIterator comparison failed");
122 success
= U_ZERO_ERROR
;
125 /*start of update [Bertrand A. D. 02/10/98]*/
126 doAssert((col
->compare("ab", "abc", 2) == Collator::EQUAL
), "ab = abc with length 2 comparison failed");
127 doAssert((col
->compare("ab", "AB", 2) == Collator::LESS
), "ab < AB with length 2 comparison failed");
128 doAssert((col
->compare("ab", "Aa", 1) == Collator::LESS
), "ab < Aa with length 1 comparison failed");
129 doAssert((col
->compare("ab", "Aa", 2) == Collator::GREATER
), "ab > Aa with length 2 comparison failed");
130 doAssert((col
->compare("black-bird", "blackbird", 5) == Collator::EQUAL
), "black-bird = blackbird with length of 5 comparison failed");
131 doAssert((col
->compare("black bird", "black-bird", 10) == Collator::LESS
), "black bird < black-bird with length 10 comparison failed");
132 doAssert((col
->compare("Hello", "hello", 5) == Collator::GREATER
), "Hello > hello with length 5 comparison failed");
133 /*end of update [Bertrand A. D. 02/10/98]*/
136 logln("Test ctors ends.");
137 logln("testing Collator::getStrength() method ...");
138 doAssert((col
->getStrength() == Collator::TERTIARY
), "collation object has the wrong strength");
139 doAssert((col
->getStrength() != Collator::PRIMARY
), "collation object's strength is primary difference");
142 logln("testing Collator::setStrength() method ...");
143 col
->setStrength(Collator::SECONDARY
);
144 doAssert((col
->getStrength() != Collator::TERTIARY
), "collation object's strength is secondary difference");
145 doAssert((col
->getStrength() != Collator::PRIMARY
), "collation object's strength is primary difference");
146 doAssert((col
->getStrength() == Collator::SECONDARY
), "collation object has the wrong strength");
150 logln("Get display name for the US English collation in German : ");
151 logln(Collator::getDisplayName(Locale::getUS(), Locale::getGerman(), name
));
152 doAssert((name
== UnicodeString("Englisch (Vereinigte Staaten)")), "getDisplayName failed");
154 logln("Get display name for the US English collation in English : ");
155 logln(Collator::getDisplayName(Locale::getUS(), Locale::getEnglish(), name
));
156 doAssert((name
== UnicodeString("English (United States)")), "getDisplayName failed");
158 // weiv : this test is bogus if we're running on any machine that has different default locale than English.
159 // Therefore, it is banned!
160 logln("Get display name for the US English in default locale language : ");
161 logln(Collator::getDisplayName(Locale::US
, name
));
162 doAssert((name
== UnicodeString("English (United States)")), "getDisplayName failed if this is an English machine");
165 RuleBasedCollator
*rcol
= (RuleBasedCollator
*)Collator::createInstance("da_DK",
167 doAssert(rcol
->getRules().length() != 0, "da_DK rules does not have length 0");
170 col
= Collator::createInstance(Locale::getFrench(), success
);
171 if (U_FAILURE(success
))
173 errln("Creating French collation failed.");
177 col
->setStrength(Collator::PRIMARY
);
178 logln("testing Collator::getStrength() method again ...");
179 doAssert((col
->getStrength() != Collator::TERTIARY
), "collation object has the wrong strength");
180 doAssert((col
->getStrength() == Collator::PRIMARY
), "collation object's strength is not primary difference");
182 logln("testing French Collator::setStrength() method ...");
183 col
->setStrength(Collator::TERTIARY
);
184 doAssert((col
->getStrength() == Collator::TERTIARY
), "collation object's strength is not tertiary difference");
185 doAssert((col
->getStrength() != Collator::PRIMARY
), "collation object's strength is primary difference");
186 doAssert((col
->getStrength() != Collator::SECONDARY
), "collation object's strength is secondary difference");
188 logln("Create junk collation: ");
189 Locale
abcd("ab", "CD", "");
190 success
= U_ZERO_ERROR
;
192 junk
= Collator::createInstance(abcd
, success
);
194 if (U_FAILURE(success
))
196 errln("Junk collation creation failed, should at least return default.");
202 col
= Collator::createInstance(success
);
203 if (U_FAILURE(success
))
205 errln("Creating default collator failed.");
210 doAssert(((RuleBasedCollator
*)col
)->getRules() == ((RuleBasedCollator
*)junk
)->getRules(),
211 "The default collation should be returned.");
212 Collator
*frCol
= Collator::createInstance(Locale::getCanadaFrench(), success
);
213 if (U_FAILURE(success
))
215 errln("Creating fr_CA collator failed.");
221 // If the default locale isn't French, the French and non-French collators
222 // should be different
223 if (frCol
->getLocale(ULOC_ACTUAL_LOCALE
, success
) != Locale::getCanadaFrench()) {
224 doAssert((*frCol
!= *junk
), "The junk is the same as the fr_CA collator.");
226 Collator
*aFrCol
= frCol
->clone();
227 doAssert((*frCol
== *aFrCol
), "The cloning of a fr_CA collator failed.");
228 logln("Collator property test ended.");
237 CollationAPITest::TestRuleBasedColl()
239 RuleBasedCollator
*col1
, *col2
, *col3
, *col4
;
240 UErrorCode status
= U_ZERO_ERROR
;
242 UnicodeString
ruleset1("&9 < a, A < b, B < c, C; ch, cH, Ch, CH < d, D, e, E");
243 UnicodeString
ruleset2("&9 < a, A < b, B < c, C < d, D, e, E");
245 col1
= new RuleBasedCollator(ruleset1
, status
);
246 if (U_FAILURE(status
)) {
247 errcheckln(status
, "RuleBased Collator creation failed. - %s", u_errorName(status
));
251 logln("PASS: RuleBased Collator creation passed\n");
254 status
= U_ZERO_ERROR
;
255 col2
= new RuleBasedCollator(ruleset2
, status
);
256 if (U_FAILURE(status
)) {
257 errln("RuleBased Collator creation failed.\n");
261 logln("PASS: RuleBased Collator creation passed\n");
264 status
= U_ZERO_ERROR
;
265 Locale
locale("aa", "AA");
266 col3
= (RuleBasedCollator
*)Collator::createInstance(locale
, status
);
267 if (U_FAILURE(status
)) {
268 errln("Fallback Collator creation failed.: %s\n");
272 logln("PASS: Fallback Collator creation passed\n");
276 status
= U_ZERO_ERROR
;
277 col3
= (RuleBasedCollator
*)Collator::createInstance(status
);
278 if (U_FAILURE(status
)) {
279 errln("Default Collator creation failed.: %s\n");
283 logln("PASS: Default Collator creation passed\n");
286 UnicodeString rule1
= col1
->getRules();
287 UnicodeString rule2
= col2
->getRules();
288 UnicodeString rule3
= col3
->getRules();
290 doAssert(rule1
!= rule2
, "Default collator getRules failed");
291 doAssert(rule2
!= rule3
, "Default collator getRules failed");
292 doAssert(rule1
!= rule3
, "Default collator getRules failed");
294 col4
= new RuleBasedCollator(rule2
, status
);
295 if (U_FAILURE(status
)) {
296 errln("RuleBased Collator creation failed.\n");
300 UnicodeString rule4
= col4
->getRules();
301 doAssert(rule2
== rule4
, "Default collator getRules failed");
303 uint8_t *clonedrule4
= col4
->cloneRuleData(length4
, status
);
304 if (U_FAILURE(status
)) {
305 errln("Cloned rule data failed.\n");
309 // free(clonedrule4); BAD API!!!!
310 uprv_free(clonedrule4
);
320 CollationAPITest::TestRules()
322 RuleBasedCollator
*coll
;
323 UErrorCode status
= U_ZERO_ERROR
;
326 coll
= (RuleBasedCollator
*)Collator::createInstance(Locale::getEnglish(), status
);
327 if (U_FAILURE(status
)) {
328 errcheckln(status
, "English Collator creation failed. - %s", u_errorName(status
));
332 logln("PASS: RuleBased Collator creation passed\n");
335 coll
->getRules(UCOL_TAILORING_ONLY
, rules
);
336 if (rules
.length() != 0x00) {
337 errln("English tailored rules failed - length is 0x%x expected 0x%x", rules
.length(), 0x00);
340 coll
->getRules(UCOL_FULL_RULES
, rules
);
341 if (rules
.length() < 0) {
342 errln("English full rules failed");
348 CollationAPITest::TestDecomposition() {
349 UErrorCode status
= U_ZERO_ERROR
;
350 Collator
*en_US
= Collator::createInstance("en_US", status
),
351 *el_GR
= Collator::createInstance("el_GR", status
),
352 *vi_VN
= Collator::createInstance("vi_VN", status
);
354 if (U_FAILURE(status
)) {
355 errcheckln(status
, "ERROR: collation creation failed. - %s", u_errorName(status
));
359 /* there is no reason to have canonical decomposition in en_US OR default locale */
360 if (vi_VN
->getAttribute(UCOL_NORMALIZATION_MODE
, status
) != UCOL_ON
)
362 errln("ERROR: vi_VN collation did not have canonical decomposition for normalization!\n");
365 if (el_GR
->getAttribute(UCOL_NORMALIZATION_MODE
, status
) != UCOL_ON
)
367 errln("ERROR: el_GR collation did not have canonical decomposition for normalization!\n");
370 if (en_US
->getAttribute(UCOL_NORMALIZATION_MODE
, status
) != UCOL_OFF
)
372 errln("ERROR: en_US collation had canonical decomposition for normalization!\n");
381 CollationAPITest::TestSafeClone() {
382 static const int CLONETEST_COLLATOR_COUNT
= 3;
383 Collator
*someCollators
[CLONETEST_COLLATOR_COUNT
];
385 UErrorCode err
= U_ZERO_ERROR
;
388 UnicodeString
test1("abCda");
389 UnicodeString
test2("abcda");
391 /* one default collator & two complex ones */
392 someCollators
[0] = Collator::createInstance("en_US", err
);
393 someCollators
[1] = Collator::createInstance("ko", err
);
394 someCollators
[2] = Collator::createInstance("ja_JP", err
);
396 errcheckln(err
, "Couldn't instantiate collators. Error: %s", u_errorName(err
));
397 delete someCollators
[0];
398 delete someCollators
[1];
399 delete someCollators
[2];
403 /* change orig & clone & make sure they are independent */
405 for (index
= 0; index
< CLONETEST_COLLATOR_COUNT
; index
++)
407 col
= someCollators
[index
]->safeClone();
409 errln("SafeClone of collator should not return null\n");
412 col
->setStrength(Collator::TERTIARY
);
413 someCollators
[index
]->setStrength(Collator::PRIMARY
);
414 col
->setAttribute(UCOL_CASE_LEVEL
, UCOL_OFF
, err
);
415 someCollators
[index
]->setAttribute(UCOL_CASE_LEVEL
, UCOL_OFF
, err
);
417 doAssert(col
->greater(test1
, test2
), "Result should be \"abCda\" >>> \"abcda\" ");
418 doAssert(someCollators
[index
]->equals(test1
, test2
), "Result should be \"abcda\" == \"abCda\"");
420 delete someCollators
[index
];
425 CollationAPITest::TestHashCode(/* char* par */)
427 logln("hashCode tests begin.");
428 UErrorCode success
= U_ZERO_ERROR
;
430 col1
= Collator::createInstance(Locale::getEnglish(), success
);
431 if (U_FAILURE(success
))
433 errcheckln(success
, "Default collation creation failed. - %s", u_errorName(success
));
438 Locale
dk("da", "DK", "");
439 col2
= Collator::createInstance(dk
, success
);
440 if (U_FAILURE(success
))
442 errln("Danish collation creation failed.");
447 col3
= Collator::createInstance(Locale::getEnglish(), success
);
448 if (U_FAILURE(success
))
450 errln("2nd default collation creation failed.");
454 logln("Collator::hashCode() testing ...");
456 doAssert(col1
->hashCode() != col2
->hashCode(), "Hash test1 result incorrect" );
457 doAssert(!(col1
->hashCode() == col2
->hashCode()), "Hash test2 result incorrect" );
458 doAssert(col1
->hashCode() == col3
->hashCode(), "Hash result not equal" );
460 logln("hashCode tests end.");
464 UnicodeString
test1("Abcda");
465 UnicodeString
test2("abcda");
467 CollationKey sortk1
, sortk2
, sortk3
;
468 UErrorCode status
= U_ZERO_ERROR
;
470 col3
->getCollationKey(test1
, sortk1
, status
);
471 col3
->getCollationKey(test2
, sortk2
, status
);
472 col3
->getCollationKey(test2
, sortk3
, status
);
474 doAssert(sortk1
.hashCode() != sortk2
.hashCode(), "Hash test1 result incorrect");
475 doAssert(sortk2
.hashCode() == sortk3
.hashCode(), "Hash result not equal" );
480 //----------------------------------------------------------------------------
481 // CollationKey -- Tests the CollationKey methods
484 CollationAPITest::TestCollationKey(/* char* par */)
486 logln("testing CollationKey begins...");
488 UErrorCode success
=U_ZERO_ERROR
;
489 col
= Collator::createInstance(Locale::getEnglish(), success
);
490 if (U_FAILURE(success
))
492 errcheckln(success
, "Default collation creation failed. - %s", u_errorName(success
));
495 col
->setStrength(Collator::TERTIARY
);
497 CollationKey sortk1
, sortk2
;
498 UnicodeString
test1("Abcda"), test2("abcda");
499 UErrorCode key1Status
= U_ZERO_ERROR
, key2Status
= U_ZERO_ERROR
;
501 logln("Testing weird arguments");
502 // No string vs. empty string vs. completely-ignorable string:
503 // See ICU ticket #10495.
504 CollationKey sortkNone
;
506 sortkNone
.getByteArray(length
);
507 doAssert(!sortkNone
.isBogus() && length
== 0,
508 "Default-constructed collation key should be empty");
509 CollationKey sortkEmpty
;
510 col
->getCollationKey(NULL
, 0, sortkEmpty
, key1Status
);
511 // key gets reset here
512 const uint8_t* byteArrayEmpty
= sortkEmpty
.getByteArray(length
);
513 doAssert(sortkEmpty
.isBogus() == FALSE
&& length
== 3 &&
514 byteArrayEmpty
[0] == 1 && byteArrayEmpty
[1] == 1 && byteArrayEmpty
[2] == 0,
515 "Empty string should return a collation key with empty levels");
516 doAssert(sortkNone
.compareTo(sortkEmpty
) == Collator::LESS
,
517 "Expected no collation key < collation key for empty string");
518 doAssert(sortkEmpty
.compareTo(sortkNone
) == Collator::GREATER
,
519 "Expected collation key for empty string > no collation key");
521 CollationKey sortkIgnorable
;
522 // Most control codes and CGJ are completely ignorable.
523 // A string with only completely ignorables must compare equal to an empty string.
524 col
->getCollationKey(UnicodeString((UChar
)1).append((UChar
)0x34f), sortkIgnorable
, key1Status
);
525 sortkIgnorable
.getByteArray(length
);
526 doAssert(!sortkIgnorable
.isBogus() && length
== 3,
527 "Completely ignorable string should return a collation key with empty levels");
528 doAssert(sortkIgnorable
.compareTo(sortkEmpty
) == Collator::EQUAL
,
529 "Completely ignorable string should compare equal to empty string");
531 // bogus key returned here
532 key1Status
= U_ILLEGAL_ARGUMENT_ERROR
;
533 col
->getCollationKey(NULL
, 0, sortk1
, key1Status
);
534 doAssert(sortk1
.isBogus() && (sortk1
.getByteArray(length
), length
) == 0,
535 "Error code should return bogus collation key");
537 key1Status
= U_ZERO_ERROR
;
538 logln("Use tertiary comparison level testing ....");
540 col
->getCollationKey(test1
, sortk1
, key1Status
);
541 if (U_FAILURE(key1Status
)) {
542 errln("getCollationKey(Abcda) failed - %s", u_errorName(key1Status
));
545 doAssert((sortk1
.compareTo(col
->getCollationKey(test2
, sortk2
, key2Status
)))
546 == Collator::GREATER
,
547 "Result should be \"Abcda\" >>> \"abcda\"");
549 CollationKey
sortk3(sortk2
), sortkNew
;
552 doAssert((sortk1
!= sortk2
), "The sort keys should be different");
553 doAssert((sortk1
.hashCode() != sortk2
.hashCode()), "sort key hashCode() failed");
554 doAssert((sortk2
== sortk3
), "The sort keys should be the same");
555 doAssert((sortk1
== sortkNew
), "The sort keys assignment failed");
556 doAssert((sortk1
.hashCode() == sortkNew
.hashCode()), "sort key hashCode() failed");
557 doAssert((sortkNew
!= sortk3
), "The sort keys should be different");
558 doAssert(sortk1
.compareTo(sortk3
) == Collator::GREATER
, "Result should be \"Abcda\" >>> \"abcda\"");
559 doAssert(sortk2
.compareTo(sortk3
) == Collator::EQUAL
, "Result should be \"abcda\" == \"abcda\"");
560 doAssert(sortkEmpty
.compareTo(sortk1
) == Collator::LESS
, "Result should be (empty key) <<< \"Abcda\"");
561 doAssert(sortk1
.compareTo(sortkEmpty
) == Collator::GREATER
, "Result should be \"Abcda\" >>> (empty key)");
562 doAssert(sortkEmpty
.compareTo(sortkEmpty
) == Collator::EQUAL
, "Result should be (empty key) == (empty key)");
563 doAssert(sortk1
.compareTo(sortk3
, success
) == UCOL_GREATER
, "Result should be \"Abcda\" >>> \"abcda\"");
564 doAssert(sortk2
.compareTo(sortk3
, success
) == UCOL_EQUAL
, "Result should be \"abcda\" == \"abcda\"");
565 doAssert(sortkEmpty
.compareTo(sortk1
, success
) == UCOL_LESS
, "Result should be (empty key) <<< \"Abcda\"");
566 doAssert(sortk1
.compareTo(sortkEmpty
, success
) == UCOL_GREATER
, "Result should be \"Abcda\" >>> (empty key)");
567 doAssert(sortkEmpty
.compareTo(sortkEmpty
, success
) == UCOL_EQUAL
, "Result should be (empty key) == (empty key)");
569 int32_t cnt1
, cnt2
, cnt3
, cnt4
;
571 const uint8_t* byteArray1
= sortk1
.getByteArray(cnt1
);
572 const uint8_t* byteArray2
= sortk2
.getByteArray(cnt2
);
574 const uint8_t* byteArray3
= 0;
575 byteArray3
= sortk1
.getByteArray(cnt3
);
577 const uint8_t* byteArray4
= 0;
578 byteArray4
= sortk2
.getByteArray(cnt4
);
580 CollationKey
sortk4(byteArray1
, cnt1
), sortk5(byteArray2
, cnt2
);
581 CollationKey
sortk6(byteArray3
, cnt3
), sortk7(byteArray4
, cnt4
);
583 doAssert(sortk1
.compareTo(sortk4
) == Collator::EQUAL
, "CollationKey::toByteArray(sortk1) Failed.");
584 doAssert(sortk2
.compareTo(sortk5
) == Collator::EQUAL
, "CollationKey::toByteArray(sortk2) Failed.");
585 doAssert(sortk4
.compareTo(sortk5
) == Collator::GREATER
, "sortk4 >>> sortk5 Failed");
586 doAssert(sortk1
.compareTo(sortk6
) == Collator::EQUAL
, "CollationKey::getByteArray(sortk1) Failed.");
587 doAssert(sortk2
.compareTo(sortk7
) == Collator::EQUAL
, "CollationKey::getByteArray(sortk2) Failed.");
588 doAssert(sortk6
.compareTo(sortk7
) == Collator::GREATER
, "sortk6 >>> sortk7 Failed");
590 logln("Equality tests : ");
591 doAssert(sortk1
== sortk4
, "sortk1 == sortk4 Failed.");
592 doAssert(sortk2
== sortk5
, "sortk2 == sortk5 Failed.");
593 doAssert(sortk1
!= sortk5
, "sortk1 != sortk5 Failed.");
594 doAssert(sortk1
== sortk6
, "sortk1 == sortk6 Failed.");
595 doAssert(sortk2
== sortk7
, "sortk2 == sortk7 Failed.");
596 doAssert(sortk1
!= sortk7
, "sortk1 != sortk7 Failed.");
602 doAssert(sortk1
== sortk3
, "sortk1 = sortk3 assignment Failed.");
603 doAssert(sortk2
!= sortk3
, "sortk2 != sortk3 Failed.");
604 logln("testing sortkey ends...");
606 col
->setStrength(Collator::SECONDARY
);
607 doAssert(col
->getCollationKey(test1
, sortk1
, key1Status
).compareTo(
608 col
->getCollationKey(test2
, sortk2
, key2Status
))
610 "Result should be \"Abcda\" == \"abcda\"");
614 //----------------------------------------------------------------------------
615 // Tests the CollatorElementIterator class.
616 // ctor, RuleBasedCollator::createCollationElementIterator(), operator==, operator!=
619 CollationAPITest::TestElemIter(/* char* par */)
621 logln("testing sortkey begins...");
623 UErrorCode success
= U_ZERO_ERROR
;
624 col
= Collator::createInstance(Locale::getEnglish(), success
);
625 if (U_FAILURE(success
))
627 errcheckln(success
, "Default collation creation failed. - %s", u_errorName(success
));
631 UnicodeString
testString1("XFILE What subset of all possible test cases has the highest probability of detecting the most errors?");
632 UnicodeString
testString2("Xf_ile What subset of all possible test cases has the lowest probability of detecting the least errors?");
633 logln("Constructors and comparison testing....");
634 CollationElementIterator
*iterator1
= ((RuleBasedCollator
*)col
)->createCollationElementIterator(testString1
);
636 CharacterIterator
*chariter
=new StringCharacterIterator(testString1
);
637 CollationElementIterator
*coliter
=((RuleBasedCollator
*)col
)->createCollationElementIterator(*chariter
);
640 CollationElementIterator
*iterator2
= ((RuleBasedCollator
*)col
)->createCollationElementIterator(testString1
);
641 CollationElementIterator
*iterator3
= ((RuleBasedCollator
*)col
)->createCollationElementIterator(testString2
);
643 int32_t offset
= iterator1
->getOffset();
645 errln("Error in getOffset for collation element iterator\n");
648 iterator1
->setOffset(6, success
);
649 if (U_FAILURE(success
)) {
650 errln("Error in setOffset for collation element iterator\n");
653 iterator1
->setOffset(0, success
);
654 int32_t order1
, order2
, order3
;
655 doAssert((*iterator1
== *iterator2
), "The two iterators should be the same");
656 doAssert((*iterator1
!= *iterator3
), "The two iterators should be different");
658 doAssert((*coliter
== *iterator1
), "The two iterators should be the same");
659 doAssert((*coliter
== *iterator2
), "The two iterators should be the same");
660 doAssert((*coliter
!= *iterator3
), "The two iterators should be different");
662 order1
= iterator1
->next(success
);
663 if (U_FAILURE(success
))
665 errln("Somehow ran out of memory stepping through the iterator.");
669 doAssert((*iterator1
!= *iterator2
), "The first iterator advance failed");
670 order2
= iterator2
->getOffset();
671 doAssert((order1
!= order2
), "The order result should not be the same");
672 order2
= iterator2
->next(success
);
673 if (U_FAILURE(success
))
675 errln("Somehow ran out of memory stepping through the iterator.");
679 doAssert((*iterator1
== *iterator2
), "The second iterator advance failed");
680 doAssert((order1
== order2
), "The order result should be the same");
681 order3
= iterator3
->next(success
);
682 if (U_FAILURE(success
))
684 errln("Somehow ran out of memory stepping through the iterator.");
688 doAssert((CollationElementIterator::primaryOrder(order1
) ==
689 CollationElementIterator::primaryOrder(order3
)), "The primary orders should be the same");
690 doAssert((CollationElementIterator::secondaryOrder(order1
) ==
691 CollationElementIterator::secondaryOrder(order3
)), "The secondary orders should be the same");
692 doAssert((CollationElementIterator::tertiaryOrder(order1
) ==
693 CollationElementIterator::tertiaryOrder(order3
)), "The tertiary orders should be the same");
695 order1
= iterator1
->next(success
); order3
= iterator3
->next(success
);
696 if (U_FAILURE(success
))
698 errln("Somehow ran out of memory stepping through the iterator.");
702 doAssert((CollationElementIterator::primaryOrder(order1
) ==
703 CollationElementIterator::primaryOrder(order3
)), "The primary orders should be identical");
704 doAssert((CollationElementIterator::tertiaryOrder(order1
) !=
705 CollationElementIterator::tertiaryOrder(order3
)), "The tertiary orders should be different");
707 order1
= iterator1
->next(success
);
708 order3
= iterator3
->next(success
);
709 /* NO! Secondary orders of two CEs are not related, especially in the case of '_' vs 'I' */
711 doAssert((CollationElementIterator::secondaryOrder(order1) !=
712 CollationElementIterator::secondaryOrder(order3)), "The secondary orders should not be the same");
714 doAssert((order1
!= CollationElementIterator::NULLORDER
), "Unexpected end of iterator reached");
716 iterator1
->reset(); iterator2
->reset(); iterator3
->reset();
717 order1
= iterator1
->next(success
);
718 if (U_FAILURE(success
))
720 errln("Somehow ran out of memory stepping through the iterator.");
724 doAssert((*iterator1
!= *iterator2
), "The first iterator advance failed");
726 order2
= iterator2
->next(success
);
727 if (U_FAILURE(success
))
729 errln("Somehow ran out of memory stepping through the iterator.");
733 doAssert((*iterator1
== *iterator2
), "The second iterator advance failed");
734 doAssert((order1
== order2
), "The order result should be the same");
736 order3
= iterator3
->next(success
);
737 if (U_FAILURE(success
))
739 errln("Somehow ran out of memory stepping through the iterator.");
743 doAssert((CollationElementIterator::primaryOrder(order1
) ==
744 CollationElementIterator::primaryOrder(order3
)), "The primary orders should be the same");
745 doAssert((CollationElementIterator::secondaryOrder(order1
) ==
746 CollationElementIterator::secondaryOrder(order3
)), "The secondary orders should be the same");
747 doAssert((CollationElementIterator::tertiaryOrder(order1
) ==
748 CollationElementIterator::tertiaryOrder(order3
)), "The tertiary orders should be the same");
750 order1
= iterator1
->next(success
); order2
= iterator2
->next(success
); order3
= iterator3
->next(success
);
751 if (U_FAILURE(success
))
753 errln("Somehow ran out of memory stepping through the iterator.");
757 doAssert((CollationElementIterator::primaryOrder(order1
) ==
758 CollationElementIterator::primaryOrder(order3
)), "The primary orders should be identical");
759 doAssert((CollationElementIterator::tertiaryOrder(order1
) !=
760 CollationElementIterator::tertiaryOrder(order3
)), "The tertiary orders should be different");
762 order1
= iterator1
->next(success
); order3
= iterator3
->next(success
);
763 if (U_FAILURE(success
))
765 errln("Somehow ran out of memory stepping through the iterator.");
769 /* NO! Secondary orders of two CEs are not related, especially in the case of '_' vs 'I' */
771 doAssert((CollationElementIterator::secondaryOrder(order1) !=
772 CollationElementIterator::secondaryOrder(order3)), "The secondary orders should not be the same");
774 doAssert((order1
!= CollationElementIterator::NULLORDER
), "Unexpected end of iterator reached");
775 doAssert((*iterator2
!= *iterator3
), "The iterators should be different");
779 success
=U_UNSUPPORTED_ERROR
;
780 Collator
*colerror
=NULL
;
781 colerror
=Collator::createInstance(Locale::getEnglish(), success
);
782 if (colerror
!= 0 || success
== U_ZERO_ERROR
){
783 errln("Error: createInstance(UErrorCode != U_ZERO_ERROR) should just return and not create an instance\n");
785 int32_t position
=coliter
->previous(success
);
786 if(position
!= CollationElementIterator::NULLORDER
){
787 errln((UnicodeString
)"Expected NULLORDER got" + position
);
790 coliter
->setText(*chariter
, success
);
791 if(!U_FAILURE(success
)){
792 errln("Expeceted error");
794 iterator1
->setText((UnicodeString
)"hello there", success
);
795 if(!U_FAILURE(success
)){
796 errln("Expeceted error");
808 logln("testing CollationElementIterator ends...");
811 // Test RuleBasedCollator ctor, dtor, operator==, operator!=, clone, copy, and getRules
813 CollationAPITest::TestOperators(/* char* par */)
815 UErrorCode success
= U_ZERO_ERROR
;
816 UnicodeString
ruleset1("&9 < a, A < b, B < c, C; ch, cH, Ch, CH < d, D, e, E");
817 UnicodeString
ruleset2("&9 < a, A < b, B < c, C < d, D, e, E");
818 RuleBasedCollator
*col1
= new RuleBasedCollator(ruleset1
, success
);
819 if (U_FAILURE(success
)) {
820 errcheckln(success
, "RuleBasedCollator creation failed. - %s", u_errorName(success
));
823 success
= U_ZERO_ERROR
;
824 RuleBasedCollator
*col2
= new RuleBasedCollator(ruleset2
, success
);
825 if (U_FAILURE(success
)) {
826 errln("The RuleBasedCollator constructor failed when building with the 2nd rule set.");
829 logln("The operator tests begin : ");
830 logln("testing operator==, operator!=, clone methods ...");
831 doAssert((*col1
!= *col2
), "The two different table collations compared equal");
833 doAssert((*col1
== *col2
), "Collator objects not equal after assignment (operator=)");
835 success
= U_ZERO_ERROR
;
836 Collator
*col3
= Collator::createInstance(Locale::getEnglish(), success
);
837 if (U_FAILURE(success
)) {
838 errln("Default collation creation failed.");
841 doAssert((*col1
!= *col3
), "The two different table collations compared equal");
842 Collator
* col4
= col1
->clone();
843 Collator
* col5
= col3
->clone();
844 doAssert((*col1
== *col4
), "Cloned collation objects not equal");
845 doAssert((*col3
!= *col4
), "Two different table collations compared equal");
846 doAssert((*col3
== *col5
), "Cloned collation objects not equal");
847 doAssert((*col4
!= *col5
), "Two cloned collations compared equal");
849 const UnicodeString
& defRules
= ((RuleBasedCollator
*)col3
)->getRules();
850 RuleBasedCollator
* col6
= new RuleBasedCollator(defRules
, success
);
851 if (U_FAILURE(success
)) {
852 errln("Creating default collation with rules failed.");
855 doAssert((((RuleBasedCollator
*)col3
)->getRules() == col6
->getRules()), "Default collator getRules failed");
857 success
= U_ZERO_ERROR
;
858 RuleBasedCollator
*col7
= new RuleBasedCollator(ruleset2
, Collator::TERTIARY
, success
);
859 if (U_FAILURE(success
)) {
860 errln("The RuleBasedCollator constructor failed when building with the 2nd rule set with tertiary strength.");
863 success
= U_ZERO_ERROR
;
864 RuleBasedCollator
*col8
= new RuleBasedCollator(ruleset2
, UCOL_OFF
, success
);
865 if (U_FAILURE(success
)) {
866 errln("The RuleBasedCollator constructor failed when building with the 2nd rule set with Normalizer::NO_OP.");
869 success
= U_ZERO_ERROR
;
870 RuleBasedCollator
*col9
= new RuleBasedCollator(ruleset2
, Collator::PRIMARY
, UCOL_ON
, success
);
871 if (U_FAILURE(success
)) {
872 errln("The RuleBasedCollator constructor failed when building with the 2nd rule set with tertiary strength and Normalizer::NO_OP.");
875 // doAssert((*col7 == *col8), "The two equal table collations compared different");
876 doAssert((*col7
!= *col9
), "The two different table collations compared equal");
877 doAssert((*col8
!= *col9
), "The two different table collations compared equal");
879 logln("operator tests ended.");
891 // test clone and copy
893 CollationAPITest::TestDuplicate(/* char* par */)
895 UErrorCode status
= U_ZERO_ERROR
;
896 Collator
*col1
= Collator::createInstance(Locale::getEnglish(), status
);
897 if (U_FAILURE(status
)) {
898 logln("Default collator creation failed.");
901 Collator
*col2
= col1
->clone();
902 doAssert((*col1
== *col2
), "Cloned object is not equal to the orginal");
903 UnicodeString
ruleset("&9 < a, A < b, B < c, C < d, D, e, E");
904 RuleBasedCollator
*col3
= new RuleBasedCollator(ruleset
, status
);
905 if (U_FAILURE(status
)) {
906 logln("Collation tailoring failed.");
909 doAssert((*col1
!= *col3
), "Cloned object is equal to some dummy");
910 *col3
= *((RuleBasedCollator
*)col1
);
911 doAssert((*col1
== *col3
), "Copied object is not equal to the orginal");
913 UCollationResult res
;
914 UnicodeString
first((UChar
)0x0061);
915 UnicodeString
second((UChar
)0x0062);
916 UnicodeString
copiedEnglishRules(((RuleBasedCollator
*)col1
)->getRules());
920 // Try using the cloned collators after deleting the original data
921 res
= col2
->compare(first
, second
, status
);
922 if(res
!= UCOL_LESS
) {
923 errln("a should be less then b after tailoring");
925 if (((RuleBasedCollator
*)col2
)->getRules() != copiedEnglishRules
) {
926 errln(UnicodeString("English rule difference. ")
927 + copiedEnglishRules
+ UnicodeString("\ngetRules=") + ((RuleBasedCollator
*)col2
)->getRules());
929 res
= col3
->compare(first
, second
, status
);
930 if(res
!= UCOL_LESS
) {
931 errln("a should be less then b after tailoring");
933 if (col3
->getRules() != copiedEnglishRules
) {
934 errln(UnicodeString("English rule difference. ")
935 + copiedEnglishRules
+ UnicodeString("\ngetRules=") + col3
->getRules());
943 CollationAPITest::TestCompare(/* char* par */)
945 logln("The compare tests begin : ");
947 UErrorCode success
= U_ZERO_ERROR
;
948 col
= Collator::createInstance(Locale::getEnglish(), success
);
949 if (U_FAILURE(success
)) {
950 errcheckln(success
, "Default collation creation failed. - %s", u_errorName(success
));
953 UnicodeString
test1("Abcda"), test2("abcda");
954 logln("Use tertiary comparison level testing ....");
956 doAssert((!col
->equals(test1
, test2
) ), "Result should be \"Abcda\" != \"abcda\"");
957 doAssert((col
->greater(test1
, test2
) ), "Result should be \"Abcda\" >>> \"abcda\"");
958 doAssert((col
->greaterOrEqual(test1
, test2
) ), "Result should be \"Abcda\" >>> \"abcda\"");
960 col
->setStrength(Collator::SECONDARY
);
961 logln("Use secondary comparison level testing ....");
963 doAssert((col
->equals(test1
, test2
) ), "Result should be \"Abcda\" == \"abcda\"");
964 doAssert((!col
->greater(test1
, test2
) ), "Result should be \"Abcda\" == \"abcda\"");
965 doAssert((col
->greaterOrEqual(test1
, test2
) ), "Result should be \"Abcda\" == \"abcda\"");
967 col
->setStrength(Collator::PRIMARY
);
968 logln("Use primary comparison level testing ....");
970 doAssert((col
->equals(test1
, test2
) ), "Result should be \"Abcda\" == \"abcda\"");
971 doAssert((!col
->greater(test1
, test2
) ), "Result should be \"Abcda\" == \"abcda\"");
972 doAssert((col
->greaterOrEqual(test1
, test2
) ), "Result should be \"Abcda\" == \"abcda\"");
974 // Test different APIs
975 const UChar
* t1
= test1
.getBuffer();
976 int32_t t1Len
= test1
.length();
977 const UChar
* t2
= test2
.getBuffer();
978 int32_t t2Len
= test2
.length();
980 doAssert((col
->compare(test1
, test2
) == Collator::EQUAL
), "Problem");
981 doAssert((col
->compare(test1
, test2
, success
) == UCOL_EQUAL
), "Problem");
982 doAssert((col
->compare(t1
, t1Len
, t2
, t2Len
) == Collator::EQUAL
), "Problem");
983 doAssert((col
->compare(t1
, t1Len
, t2
, t2Len
, success
) == UCOL_EQUAL
), "Problem");
984 doAssert((col
->compare(test1
, test2
, t1Len
) == Collator::EQUAL
), "Problem");
985 doAssert((col
->compare(test1
, test2
, t1Len
, success
) == UCOL_EQUAL
), "Problem");
987 col
->setAttribute(UCOL_STRENGTH
, UCOL_TERTIARY
, success
);
988 doAssert((col
->compare(test1
, test2
) == Collator::GREATER
), "Problem");
989 doAssert((col
->compare(test1
, test2
, success
) == UCOL_GREATER
), "Problem");
990 doAssert((col
->compare(t1
, t1Len
, t2
, t2Len
) == Collator::GREATER
), "Problem");
991 doAssert((col
->compare(t1
, t1Len
, t2
, t2Len
, success
) == UCOL_GREATER
), "Problem");
992 doAssert((col
->compare(test1
, test2
, t1Len
) == Collator::GREATER
), "Problem");
993 doAssert((col
->compare(test1
, test2
, t1Len
, success
) == UCOL_GREATER
), "Problem");
997 logln("The compare tests end.");
1002 CollationAPITest::TestGetAll(/* char* par */)
1004 if (logKnownIssue("10774","Side effects from utility/LocaleTest/TestGetLocale")) {
1007 int32_t count1
, count2
;
1008 UErrorCode status
= U_ZERO_ERROR
;
1010 logln("Trying Collator::getAvailableLocales(int&)");
1012 const Locale
* list
= Collator::getAvailableLocales(count1
);
1013 for (int32_t i
= 0; i
< count1
; ++i
) {
1014 UnicodeString dispName
;
1015 logln(UnicodeString("Locale name: ")
1016 + UnicodeString(list
[i
].getName())
1017 + UnicodeString(" , the display name is : ")
1018 + UnicodeString(list
[i
].getDisplayName(dispName
)));
1021 if (count1
== 0 || list
== NULL
) {
1022 dataerrln("getAvailableLocales(int&) returned an empty list");
1025 logln("Trying Collator::getAvailableLocales()");
1026 StringEnumeration
* localeEnum
= Collator::getAvailableLocales();
1027 const UnicodeString
* locStr
;
1028 const char *locCStr
;
1031 if (localeEnum
== NULL
) {
1032 dataerrln("getAvailableLocales() returned NULL");
1036 while ((locStr
= localeEnum
->snext(status
)) != NULL
)
1038 logln(UnicodeString("Locale name is: ") + *locStr
);
1041 if (count1
!= count2
) {
1042 errln("getAvailableLocales(int&) returned %d and getAvailableLocales() returned %d", count1
, count2
);
1045 logln("Trying Collator::getAvailableLocales() clone");
1047 StringEnumeration
* localeEnum2
= localeEnum
->clone();
1048 localeEnum2
->reset(status
);
1049 while ((locCStr
= localeEnum2
->next(NULL
, status
)) != NULL
)
1051 logln(UnicodeString("Locale name is: ") + UnicodeString(locCStr
));
1054 if (count1
!= count2
) {
1055 errln("getAvailableLocales(3rd time) returned %d and getAvailableLocales(2nd time) returned %d", count1
, count2
);
1057 if (localeEnum
->count(status
) != count1
) {
1058 errln("localeEnum->count() returned %d and getAvailableLocales() returned %d", localeEnum
->count(status
), count1
);
1064 void CollationAPITest::TestSortKey()
1066 UErrorCode status
= U_ZERO_ERROR
;
1068 this is supposed to open default date format, but later on it treats
1069 it like it is "en_US"
1070 - very bad if you try to run the tests on machine where default
1071 locale is NOT "en_US"
1073 Collator
*col
= Collator::createInstance(Locale::getEnglish(), status
);
1074 if (U_FAILURE(status
)) {
1075 errcheckln(status
, "ERROR: Default collation creation failed.: %s\n", u_errorName(status
));
1079 if (col
->getStrength() != Collator::TERTIARY
)
1081 errln("ERROR: default collation did not have UCOL_DEFAULT_STRENGTH !\n");
1084 /* Need to use identical strength */
1085 col
->setAttribute(UCOL_STRENGTH
, UCOL_IDENTICAL
, status
);
1087 UChar test1
[6] = {0x41, 0x62, 0x63, 0x64, 0x61, 0},
1088 test2
[6] = {0x61, 0x62, 0x63, 0x64, 0x61, 0},
1089 test3
[6] = {0x61, 0x62, 0x63, 0x64, 0x61, 0};
1091 uint8_t sortkey1
[64];
1092 uint8_t sortkey2
[64];
1093 uint8_t sortkey3
[64];
1095 logln("Use tertiary comparison level testing ....\n");
1098 col
->getCollationKey(test1
, u_strlen(test1
), key1
, status
);
1101 col
->getCollationKey(test2
, u_strlen(test2
), key2
, status
);
1104 col
->getCollationKey(test3
, u_strlen(test3
), key3
, status
);
1106 doAssert(key1
.compareTo(key2
) == Collator::GREATER
,
1107 "Result should be \"Abcda\" > \"abcda\"");
1108 doAssert(key2
.compareTo(key1
) == Collator::LESS
,
1109 "Result should be \"abcda\" < \"Abcda\"");
1110 doAssert(key2
.compareTo(key3
) == Collator::EQUAL
,
1111 "Result should be \"abcda\" == \"abcda\"");
1113 // Clone the key2 sortkey for later.
1114 int32_t keylength
= 0;
1115 const uint8_t *key2primary_alias
= key2
.getByteArray(keylength
);
1116 LocalArray
<uint8_t> key2primary(new uint8_t[keylength
]);
1117 memcpy(key2primary
.getAlias(), key2primary_alias
, keylength
);
1119 col
->getSortKey(test1
, sortkey1
, 64);
1120 col
->getSortKey(test2
, sortkey2
, 64);
1121 col
->getSortKey(test3
, sortkey3
, 64);
1123 const uint8_t *tempkey
= key1
.getByteArray(keylength
);
1124 doAssert(memcmp(tempkey
, sortkey1
, keylength
) == 0,
1125 "Test1 string should have the same collation key and sort key");
1126 tempkey
= key2
.getByteArray(keylength
);
1127 doAssert(memcmp(tempkey
, sortkey2
, keylength
) == 0,
1128 "Test2 string should have the same collation key and sort key");
1129 tempkey
= key3
.getByteArray(keylength
);
1130 doAssert(memcmp(tempkey
, sortkey3
, keylength
) == 0,
1131 "Test3 string should have the same collation key and sort key");
1133 col
->getSortKey(test1
, 5, sortkey1
, 64);
1134 col
->getSortKey(test2
, 5, sortkey2
, 64);
1135 col
->getSortKey(test3
, 5, sortkey3
, 64);
1137 tempkey
= key1
.getByteArray(keylength
);
1138 doAssert(memcmp(tempkey
, sortkey1
, keylength
) == 0,
1139 "Test1 string should have the same collation key and sort key");
1140 tempkey
= key2
.getByteArray(keylength
);
1141 doAssert(memcmp(tempkey
, sortkey2
, keylength
) == 0,
1142 "Test2 string should have the same collation key and sort key");
1143 tempkey
= key3
.getByteArray(keylength
);
1144 doAssert(memcmp(tempkey
, sortkey3
, keylength
) == 0,
1145 "Test3 string should have the same collation key and sort key");
1147 UnicodeString
strtest1(test1
);
1148 col
->getSortKey(strtest1
, sortkey1
, 64);
1149 UnicodeString
strtest2(test2
);
1150 col
->getSortKey(strtest2
, sortkey2
, 64);
1151 UnicodeString
strtest3(test3
);
1152 col
->getSortKey(strtest3
, sortkey3
, 64);
1154 tempkey
= key1
.getByteArray(keylength
);
1155 doAssert(memcmp(tempkey
, sortkey1
, keylength
) == 0,
1156 "Test1 string should have the same collation key and sort key");
1157 tempkey
= key2
.getByteArray(keylength
);
1158 doAssert(memcmp(tempkey
, sortkey2
, keylength
) == 0,
1159 "Test2 string should have the same collation key and sort key");
1160 tempkey
= key3
.getByteArray(keylength
);
1161 doAssert(memcmp(tempkey
, sortkey3
, keylength
) == 0,
1162 "Test3 string should have the same collation key and sort key");
1164 logln("Use secondary comparision level testing ...\n");
1165 col
->setStrength(Collator::SECONDARY
);
1167 col
->getCollationKey(test1
, u_strlen(test1
), key1
, status
);
1168 col
->getCollationKey(test2
, u_strlen(test2
), key2
, status
);
1169 col
->getCollationKey(test3
, u_strlen(test3
), key3
, status
);
1171 doAssert(key1
.compareTo(key2
) == Collator::EQUAL
,
1172 "Result should be \"Abcda\" == \"abcda\"");
1173 doAssert(key2
.compareTo(key3
) == Collator::EQUAL
,
1174 "Result should be \"abcda\" == \"abcda\"");
1176 tempkey
= key2
.getByteArray(keylength
);
1177 doAssert(memcmp(tempkey
, key2primary
.getAlias(), keylength
- 1) == 0,
1178 "Binary format for 'abcda' sortkey different for secondary strength!");
1180 col
->getSortKey(test1
, sortkey1
, 64);
1181 col
->getSortKey(test2
, sortkey2
, 64);
1182 col
->getSortKey(test3
, sortkey3
, 64);
1184 tempkey
= key1
.getByteArray(keylength
);
1185 doAssert(memcmp(tempkey
, sortkey1
, keylength
) == 0,
1186 "Test1 string should have the same collation key and sort key");
1187 tempkey
= key2
.getByteArray(keylength
);
1188 doAssert(memcmp(tempkey
, sortkey2
, keylength
) == 0,
1189 "Test2 string should have the same collation key and sort key");
1190 tempkey
= key3
.getByteArray(keylength
);
1191 doAssert(memcmp(tempkey
, sortkey3
, keylength
) == 0,
1192 "Test3 string should have the same collation key and sort key");
1194 col
->getSortKey(test1
, 5, sortkey1
, 64);
1195 col
->getSortKey(test2
, 5, sortkey2
, 64);
1196 col
->getSortKey(test3
, 5, sortkey3
, 64);
1198 tempkey
= key1
.getByteArray(keylength
);
1199 doAssert(memcmp(tempkey
, sortkey1
, keylength
) == 0,
1200 "Test1 string should have the same collation key and sort key");
1201 tempkey
= key2
.getByteArray(keylength
);
1202 doAssert(memcmp(tempkey
, sortkey2
, keylength
) == 0,
1203 "Test2 string should have the same collation key and sort key");
1204 tempkey
= key3
.getByteArray(keylength
);
1205 doAssert(memcmp(tempkey
, sortkey3
, keylength
) == 0,
1206 "Test3 string should have the same collation key and sort key");
1208 col
->getSortKey(strtest1
, sortkey1
, 64);
1209 col
->getSortKey(strtest2
, sortkey2
, 64);
1210 col
->getSortKey(strtest3
, sortkey3
, 64);
1212 tempkey
= key1
.getByteArray(keylength
);
1213 doAssert(memcmp(tempkey
, sortkey1
, keylength
) == 0,
1214 "Test1 string should have the same collation key and sort key");
1215 tempkey
= key2
.getByteArray(keylength
);
1216 doAssert(memcmp(tempkey
, sortkey2
, keylength
) == 0,
1217 "Test2 string should have the same collation key and sort key");
1218 tempkey
= key3
.getByteArray(keylength
);
1219 doAssert(memcmp(tempkey
, sortkey3
, keylength
) == 0,
1220 "Test3 string should have the same collation key and sort key");
1222 logln("testing sortkey ends...");
1226 void CollationAPITest::TestSortKeyOverflow() {
1227 IcuTestErrorCode
errorCode(*this, "TestSortKeyOverflow()");
1228 LocalPointer
<Collator
> col(Collator::createInstance(Locale::getEnglish(), errorCode
));
1229 if (errorCode
.logDataIfFailureAndReset("Collator::createInstance(English) failed")) {
1232 col
->setAttribute(UCOL_STRENGTH
, UCOL_PRIMARY
, errorCode
);
1233 UChar i_and_phi
[] = { 0x438, 0x3c6 }; // Cyrillic small i & Greek small phi.
1234 // The sort key should be 6 bytes:
1235 // 2 bytes for the Cyrillic i, 1 byte for the primary-compression terminator,
1236 // 2 bytes for the Greek phi, and 1 byte for the NUL terminator.
1237 uint8_t sortKey
[12];
1238 int32_t length
= col
->getSortKey(i_and_phi
, 2, sortKey
, LENGTHOF(sortKey
));
1239 uint8_t sortKey2
[12];
1240 for (int32_t capacity
= 0; capacity
< length
; ++capacity
) {
1241 uprv_memset(sortKey2
, 2, LENGTHOF(sortKey2
));
1242 int32_t length2
= col
->getSortKey(i_and_phi
, 2, sortKey2
, capacity
);
1243 if (length2
!= length
|| 0 != uprv_memcmp(sortKey
, sortKey2
, capacity
)) {
1244 errln("getSortKey(i_and_phi, capacity=%d) failed to write proper prefix", capacity
);
1245 } else if (sortKey2
[capacity
] != 2 || sortKey2
[capacity
+ 1] != 2) {
1246 errln("getSortKey(i_and_phi, capacity=%d) wrote beyond capacity", capacity
);
1250 // Now try to break getCollationKey().
1251 // Internally, it always starts with a large stack buffer.
1252 // Since we cannot control the initial capacity, we throw an increasing number
1253 // of characters at it, with the problematic part at the end.
1254 const int32_t longCapacity
= 2000;
1255 // Each 'a' in the prefix should result in one primary sort key byte.
1256 // For i_and_phi we expect 6 bytes, then the NUL terminator.
1257 const int32_t maxPrefixLength
= longCapacity
- 6 - 1;
1258 LocalArray
<uint8_t> longSortKey(new uint8_t[longCapacity
]);
1259 UnicodeString
s(FALSE
, i_and_phi
, 2);
1260 for (int32_t prefixLength
= 0; prefixLength
< maxPrefixLength
; ++prefixLength
) {
1261 length
= col
->getSortKey(s
, longSortKey
.getAlias(), longCapacity
);
1262 CollationKey collKey
;
1263 col
->getCollationKey(s
, collKey
, errorCode
);
1264 int32_t collKeyLength
;
1265 const uint8_t *collSortKey
= collKey
.getByteArray(collKeyLength
);
1266 if (collKeyLength
!= length
|| 0 != uprv_memcmp(longSortKey
.getAlias(), collSortKey
, length
)) {
1267 errln("getCollationKey(prefix[%d]+i_and_phi) failed to write proper sort key", prefixLength
);
1270 // Insert an 'a' to match ++prefixLength.
1271 s
.insert(prefixLength
, (UChar
)0x61);
1275 void CollationAPITest::TestMaxExpansion()
1277 UErrorCode status
= U_ZERO_ERROR
;
1279 UChar32 unassigned
= 0xEFFFD;
1280 uint32_t sorder
= 0;
1281 uint32_t temporder
= 0;
1283 UnicodeString
rule("&a < ab < c/aba < d < z < ch");
1284 RuleBasedCollator
coll(rule
, status
);
1285 if(U_FAILURE(status
)) {
1286 errcheckln(status
, "Collator creation failed with error %s", u_errorName(status
));
1289 UnicodeString
str(ch
);
1290 CollationElementIterator
*iter
=
1291 coll
.createCollationElementIterator(str
);
1293 while (ch
< 0xFFFF && U_SUCCESS(status
)) {
1300 str
.setCharAt(0, ch
);
1301 iter
->setText(str
, status
);
1302 order
= iter
->previous(status
);
1304 /* thai management */
1306 order
= iter
->previous(status
);
1308 while (U_SUCCESS(status
) && iter
->previous(status
) != CollationElementIterator::NULLORDER
) {
1312 size
= coll
.getMaxExpansion(order
);
1313 if (U_FAILURE(status
) || size
< count
) {
1314 errln("Failure at codepoint U+%04X, maximum expansion count %d < %d",
1319 /* testing for exact max expansion */
1324 str
.setCharAt(0, ch
);
1325 iter
->setText(str
, status
);
1326 order
= iter
->previous(status
);
1327 size
= coll
.getMaxExpansion(order
);
1328 if (U_FAILURE(status
) || size
!= 1) {
1329 errln("Failure at codepoint U+%04X, maximum expansion count %d < %d",
1337 iter
->setText(str
, status
);
1338 temporder
= iter
->previous(status
);
1339 size
= coll
.getMaxExpansion(temporder
);
1340 if (U_FAILURE(status
) || size
!= 3) {
1341 errln("Failure at codepoint U+%04X, CE %08x, maximum expansion count %d != %d",
1342 ch
, temporder
, size
, 3);
1347 iter
->setText(str
, status
);
1348 temporder
= iter
->previous(status
);
1349 size
= coll
.getMaxExpansion(temporder
);
1350 if (U_FAILURE(status
) || size
!= 1) {
1351 errln("Failure at codepoint U+%04X, CE %08x, maximum expansion count %d != %d",
1352 ch
, temporder
, size
, 1);
1355 str
.setTo(unassigned
);
1356 iter
->setText(str
, status
);
1357 sorder
= iter
->previous(status
);
1358 size
= coll
.getMaxExpansion(sorder
);
1359 if (U_FAILURE(status
) || size
!= 2) {
1360 errln("Failure at supplementary codepoints, maximum expansion count %d < %d",
1367 iter
->setText(str
, status
);
1368 temporder
= iter
->previous(status
);
1369 size
= coll
.getMaxExpansion(temporder
);
1370 if (U_FAILURE(status
) || size
> 3) {
1371 errln("Failure at codepoint U+%04X, maximum expansion count %d > %d",
1377 /* testing special jamo &a<\u1160 */
1378 rule
= CharsToUnicodeString("\\u0026\\u0071\\u003c\\u1165\\u002f\\u0071\\u0071\\u0071\\u0071");
1380 RuleBasedCollator
jamocoll(rule
, status
);
1381 iter
= jamocoll
.createCollationElementIterator(str
);
1382 temporder
= iter
->previous(status
);
1383 size
= iter
->getMaxExpansion(temporder
);
1384 if (U_FAILURE(status
) || size
!= 6) {
1385 errln("Failure at codepoint U+%04X, maximum expansion count %d > %d",
1392 void CollationAPITest::TestDisplayName()
1394 UErrorCode error
= U_ZERO_ERROR
;
1395 Collator
*coll
= Collator::createInstance("en_US", error
);
1396 if (U_FAILURE(error
)) {
1397 errcheckln(error
, "Failure creating english collator - %s", u_errorName(error
));
1401 UnicodeString result
;
1402 coll
->getDisplayName(Locale::getCanadaFrench(), result
);
1403 Locale::getCanadaFrench().getDisplayName(name
);
1404 if (result
.compare(name
)) {
1405 errln("Failure getting the correct name for locale en_US");
1408 coll
->getDisplayName(Locale::getSimplifiedChinese(), result
);
1409 Locale::getSimplifiedChinese().getDisplayName(name
);
1410 if (result
.compare(name
)) {
1411 errln("Failure getting the correct name for locale zh_SG");
1416 void CollationAPITest::TestAttribute()
1418 UErrorCode error
= U_ZERO_ERROR
;
1419 Collator
*coll
= Collator::createInstance(error
);
1421 if (U_FAILURE(error
)) {
1422 errcheckln(error
, "Creation of default collator failed - %s", u_errorName(error
));
1426 coll
->setAttribute(UCOL_FRENCH_COLLATION
, UCOL_OFF
, error
);
1427 if (coll
->getAttribute(UCOL_FRENCH_COLLATION
, error
) != UCOL_OFF
||
1429 errln("Setting and retrieving of the french collation failed");
1432 coll
->setAttribute(UCOL_FRENCH_COLLATION
, UCOL_ON
, error
);
1433 if (coll
->getAttribute(UCOL_FRENCH_COLLATION
, error
) != UCOL_ON
||
1435 errln("Setting and retrieving of the french collation failed");
1438 coll
->setAttribute(UCOL_ALTERNATE_HANDLING
, UCOL_SHIFTED
, error
);
1439 if (coll
->getAttribute(UCOL_ALTERNATE_HANDLING
, error
) != UCOL_SHIFTED
||
1441 errln("Setting and retrieving of the alternate handling failed");
1444 coll
->setAttribute(UCOL_ALTERNATE_HANDLING
, UCOL_NON_IGNORABLE
, error
);
1445 if (coll
->getAttribute(UCOL_ALTERNATE_HANDLING
, error
) != UCOL_NON_IGNORABLE
||
1447 errln("Setting and retrieving of the alternate handling failed");
1450 coll
->setAttribute(UCOL_CASE_FIRST
, UCOL_LOWER_FIRST
, error
);
1451 if (coll
->getAttribute(UCOL_CASE_FIRST
, error
) != UCOL_LOWER_FIRST
||
1453 errln("Setting and retrieving of the case first attribute failed");
1456 coll
->setAttribute(UCOL_CASE_FIRST
, UCOL_UPPER_FIRST
, error
);
1457 if (coll
->getAttribute(UCOL_CASE_FIRST
, error
) != UCOL_UPPER_FIRST
||
1459 errln("Setting and retrieving of the case first attribute failed");
1462 coll
->setAttribute(UCOL_CASE_LEVEL
, UCOL_ON
, error
);
1463 if (coll
->getAttribute(UCOL_CASE_LEVEL
, error
) != UCOL_ON
||
1465 errln("Setting and retrieving of the case level attribute failed");
1468 coll
->setAttribute(UCOL_CASE_LEVEL
, UCOL_OFF
, error
);
1469 if (coll
->getAttribute(UCOL_CASE_LEVEL
, error
) != UCOL_OFF
||
1471 errln("Setting and retrieving of the case level attribute failed");
1474 coll
->setAttribute(UCOL_NORMALIZATION_MODE
, UCOL_ON
, error
);
1475 if (coll
->getAttribute(UCOL_NORMALIZATION_MODE
, error
) != UCOL_ON
||
1477 errln("Setting and retrieving of the normalization on/off attribute failed");
1480 coll
->setAttribute(UCOL_NORMALIZATION_MODE
, UCOL_OFF
, error
);
1481 if (coll
->getAttribute(UCOL_NORMALIZATION_MODE
, error
) != UCOL_OFF
||
1483 errln("Setting and retrieving of the normalization on/off attribute failed");
1486 coll
->setAttribute(UCOL_STRENGTH
, UCOL_PRIMARY
, error
);
1487 if (coll
->getAttribute(UCOL_STRENGTH
, error
) != UCOL_PRIMARY
||
1489 errln("Setting and retrieving of the collation strength failed");
1492 coll
->setAttribute(UCOL_STRENGTH
, UCOL_SECONDARY
, error
);
1493 if (coll
->getAttribute(UCOL_STRENGTH
, error
) != UCOL_SECONDARY
||
1495 errln("Setting and retrieving of the collation strength failed");
1498 coll
->setAttribute(UCOL_STRENGTH
, UCOL_TERTIARY
, error
);
1499 if (coll
->getAttribute(UCOL_STRENGTH
, error
) != UCOL_TERTIARY
||
1501 errln("Setting and retrieving of the collation strength failed");
1504 coll
->setAttribute(UCOL_STRENGTH
, UCOL_QUATERNARY
, error
);
1505 if (coll
->getAttribute(UCOL_STRENGTH
, error
) != UCOL_QUATERNARY
||
1507 errln("Setting and retrieving of the collation strength failed");
1510 coll
->setAttribute(UCOL_STRENGTH
, UCOL_IDENTICAL
, error
);
1511 if (coll
->getAttribute(UCOL_STRENGTH
, error
) != UCOL_IDENTICAL
||
1513 errln("Setting and retrieving of the collation strength failed");
1519 void CollationAPITest::TestVariableTopSetting() {
1520 UErrorCode status
= U_ZERO_ERROR
;
1522 UChar vt
[256] = { 0 };
1524 // Use the root collator, not the default collator.
1525 // This test fails with en_US_POSIX which tailors the dollar sign after 'A'.
1526 Collator
*coll
= Collator::createInstance(Locale::getRoot(), status
);
1527 if(U_FAILURE(status
)) {
1529 errcheckln(status
, "Collator creation failed with error %s", u_errorName(status
));
1533 uint32_t oldVarTop
= coll
->getVariableTop(status
);
1535 // ICU 53+: The character must be in a supported reordering group,
1536 // and the variable top is pinned to the end of that group.
1539 (void)coll
->setVariableTop(vt
, 1, status
);
1540 if(status
!= U_ILLEGAL_ARGUMENT_ERROR
) {
1541 errln("setVariableTop(letter) did not detect illegal argument - %s", u_errorName(status
));
1544 status
= U_ZERO_ERROR
;
1545 vt
[0] = 0x24; // dollar sign (currency symbol)
1546 uint32_t newVarTop
= coll
->setVariableTop(vt
, 1, status
);
1548 if(newVarTop
!= coll
->getVariableTop(status
)) {
1549 errln("setVariableTop(dollar sign) != following getVariableTop()");
1552 UnicodeString
dollar((UChar
)0x24);
1553 UnicodeString
euro((UChar
)0x20AC);
1554 uint32_t newVarTop2
= coll
->setVariableTop(euro
, status
);
1555 assertEquals("setVariableTop(Euro sign) == following getVariableTop()",
1556 (int64_t)newVarTop2
, (int64_t)coll
->getVariableTop(status
));
1557 assertEquals("setVariableTop(Euro sign) == setVariableTop(dollar sign) (should pin to top of currency group)",
1558 (int64_t)newVarTop2
, (int64_t)newVarTop
);
1560 coll
->setAttribute(UCOL_ALTERNATE_HANDLING
, UCOL_SHIFTED
, status
);
1561 assertEquals("empty==dollar", UCOL_EQUAL
, coll
->compare(UnicodeString(), dollar
));
1562 assertEquals("empty==euro", UCOL_EQUAL
, coll
->compare(UnicodeString(), euro
));
1563 assertEquals("dollar<zero", UCOL_LESS
, coll
->compare(dollar
, UnicodeString((UChar
)0x30)));
1565 coll
->setVariableTop(oldVarTop
, status
);
1567 uint32_t newerVarTop
= coll
->setVariableTop(UnicodeString(vt
, 1), status
);
1569 if(newVarTop
!= newerVarTop
) {
1570 errln("Didn't set vartop properly from UnicodeString!\n");
1577 void CollationAPITest::TestMaxVariable() {
1578 UErrorCode errorCode
= U_ZERO_ERROR
;
1579 LocalPointer
<Collator
> coll(Collator::createInstance(Locale::getRoot(), errorCode
));
1580 if(U_FAILURE(errorCode
)) {
1581 errcheckln(errorCode
, "Collator creation failed with error %s", u_errorName(errorCode
));
1585 (void)coll
->setMaxVariable(UCOL_REORDER_CODE_OTHERS
, errorCode
);
1586 if(errorCode
!= U_ILLEGAL_ARGUMENT_ERROR
) {
1587 errln("setMaxVariable(others) did not detect illegal argument - %s", u_errorName(errorCode
));
1590 errorCode
= U_ZERO_ERROR
;
1591 (void)coll
->setMaxVariable(UCOL_REORDER_CODE_CURRENCY
, errorCode
);
1593 if(UCOL_REORDER_CODE_CURRENCY
!= coll
->getMaxVariable()) {
1594 errln("setMaxVariable(currency) != following getMaxVariable()");
1597 coll
->setAttribute(UCOL_ALTERNATE_HANDLING
, UCOL_SHIFTED
, errorCode
);
1598 assertEquals("empty==dollar", UCOL_EQUAL
, coll
->compare(UnicodeString(), UnicodeString((UChar
)0x24)));
1599 assertEquals("empty==euro", UCOL_EQUAL
, coll
->compare(UnicodeString(), UnicodeString((UChar
)0x20AC)));
1600 assertEquals("dollar<zero", UCOL_LESS
, coll
->compare(UnicodeString((UChar
)0x24), UnicodeString((UChar
)0x30)));
1603 void CollationAPITest::TestGetLocale() {
1604 UErrorCode status
= U_ZERO_ERROR
;
1605 const char *rules
= "&a<x<y<z";
1606 UChar rlz
[256] = {0};
1608 Collator
*coll
= Collator::createInstance("root", status
);
1609 if(U_FAILURE(status
)) {
1610 dataerrln("Failed to open collator for \"root\" with %s", u_errorName(status
));
1613 Locale locale
= coll
->getLocale(ULOC_ACTUAL_LOCALE
, status
);
1614 if(locale
!= Locale::getRoot()) {
1615 errln("Collator::createInstance(\"root\").getLocale(actual) != Locale::getRoot(); "
1616 "getLocale().getName() = \"%s\"",
1621 coll
= Collator::createInstance("", status
);
1622 if(U_FAILURE(status
)) {
1623 dataerrln("Failed to open collator for \"\" with %s", u_errorName(status
));
1626 locale
= coll
->getLocale(ULOC_ACTUAL_LOCALE
, status
);
1627 if(locale
!= Locale::getRoot()) {
1628 errln("Collator::createInstance(\"\").getLocale(actual) != Locale::getRoot(); "
1629 "getLocale().getName() = \"%s\"",
1636 static const struct {
1637 const char* requestedLocale
;
1638 const char* validLocale
;
1639 const char* actualLocale
;
1641 // Note: Locale::getRoot().getName() == "" not "root".
1642 { "de_DE", "de", "" },
1643 { "sr_RS", "sr_Cyrl_RS", "sr" },
1644 { "en_US_CALIFORNIA", "en_US", "" },
1645 { "fr_FR_NONEXISTANT", "fr", "" },
1646 // pinyin is the default, therefore suppressed.
1647 { "zh_CN", "zh_Hans_CN", "zh" },
1648 // zh_Hant has default=stroke but the data is in zh.
1649 { "zh_TW", "zh_Hant_TW", "zh@collation=stroke" },
1650 { "zh_TW@collation=pinyin", "zh_Hant_TW@collation=pinyin", "zh" },
1651 { "zh_CN@collation=stroke", "zh_Hans_CN@collation=stroke", "zh@collation=stroke" }
1654 u_unescape(rules
, rlz
, 256);
1656 /* test opening collators for different locales */
1657 for(i
= 0; i
<(int32_t)LENGTHOF(testStruct
); i
++) {
1658 status
= U_ZERO_ERROR
;
1659 coll
= Collator::createInstance(testStruct
[i
].requestedLocale
, status
);
1660 if(U_FAILURE(status
)) {
1661 errln("Failed to open collator for %s with %s", testStruct
[i
].requestedLocale
, u_errorName(status
));
1665 // The requested locale may be the same as the valid locale,
1666 // or may not be supported at all. See ticket #10477.
1667 locale
= coll
->getLocale(ULOC_REQUESTED_LOCALE
, status
);
1668 if(locale
!= testStruct
[i
].requestedLocale
&& locale
!= testStruct
[i
].validLocale
) {
1669 errln("[Coll %s]: Error in requested locale, expected %s or %s, got %s",
1670 testStruct
[i
].requestedLocale
,
1671 testStruct
[i
].requestedLocale
, testStruct
[i
].validLocale
, locale
.getName());
1673 locale
= coll
->getLocale(ULOC_VALID_LOCALE
, status
);
1674 if(locale
!= testStruct
[i
].validLocale
) {
1675 errln("[Coll %s]: Error in valid locale, expected %s, got %s",
1676 testStruct
[i
].requestedLocale
, testStruct
[i
].validLocale
, locale
.getName());
1678 locale
= coll
->getLocale(ULOC_ACTUAL_LOCALE
, status
);
1679 if(locale
!= testStruct
[i
].actualLocale
) {
1680 errln("[Coll %s]: Error in actual locale, expected %s, got %s",
1681 testStruct
[i
].requestedLocale
, testStruct
[i
].actualLocale
, locale
.getName());
1683 // If we open a collator for the actual locale, we should get an equivalent one again.
1684 LocalPointer
<Collator
> coll2(Collator::createInstance(locale
, status
));
1685 if(U_FAILURE(status
)) {
1686 errln("Failed to open collator for actual locale \"%s\" with %s",
1687 locale
.getName(), u_errorName(status
));
1689 Locale actual2
= coll2
->getLocale(ULOC_ACTUAL_LOCALE
, status
);
1690 if(actual2
!= locale
) {
1691 errln("[Coll actual \"%s\"]: Error in actual locale, got different one: \"%s\"",
1692 locale
.getName(), actual2
.getName());
1694 if(*coll2
!= *coll
) {
1695 errln("[Coll actual \"%s\"]: Got different collator than before", locale
.getName());
1701 /* completely non-existant locale for collator should get a default collator */
1703 Collator
*defaultColl
= Collator::createInstance((const Locale
)NULL
, status
);
1704 coll
= Collator::createInstance("blahaha", status
);
1705 if(U_FAILURE(status
)) {
1706 errln("Failed to open collator with %s", u_errorName(status
));
1711 if(coll
->getLocale(ULOC_VALID_LOCALE
, status
) !=
1712 defaultColl
->getLocale(ULOC_VALID_LOCALE
, status
)) {
1713 errln("Valid locale for nonexisting locale locale collator differs "
1714 "from valid locale for default collator");
1716 if(coll
->getLocale(ULOC_ACTUAL_LOCALE
, status
) !=
1717 defaultColl
->getLocale(ULOC_ACTUAL_LOCALE
, status
)) {
1718 errln("Actual locale for nonexisting locale locale collator differs "
1719 "from actual locale for default collator");
1727 /* collator instantiated from rules should have all three locales NULL */
1728 coll
= new RuleBasedCollator(rlz
, status
);
1729 locale
= coll
->getLocale(ULOC_REQUESTED_LOCALE
, status
);
1730 if(!locale
.isBogus()) {
1731 errln("For collator instantiated from rules, requested locale %s is not bogus", locale
.getName());
1733 locale
= coll
->getLocale(ULOC_VALID_LOCALE
, status
);
1734 if(!locale
.isBogus()) {
1735 errln("For collator instantiated from rules, valid locale %s is not bogus", locale
.getName());
1737 locale
= coll
->getLocale(ULOC_ACTUAL_LOCALE
, status
);
1738 if(!locale
.isBogus()) {
1739 errln("For collator instantiated from rules, actual locale %s is not bogus", locale
.getName());
1745 const char *original
;
1752 static int U_CALLCONV
1753 compare_teststruct(const void *string1
, const void *string2
) {
1754 return(strcmp((const char *)((struct teststruct
*)string1
)->key
, (const char *)((struct teststruct
*)string2
)->key
));
1759 void CollationAPITest::TestBounds(void) {
1760 UErrorCode status
= U_ZERO_ERROR
;
1762 Collator
*coll
= Collator::createInstance(Locale("sh"), status
);
1763 if(U_FAILURE(status
)) {
1765 errcheckln(status
, "Collator creation failed with %s", u_errorName(status
));
1769 uint8_t sortkey
[512], lower
[512], upper
[512];
1772 static const char * const test
[] = {
1776 "j\\u00F6hn sm\\u00EFth",
1777 "J\\u00F6hn Sm\\u00EFth",
1778 "J\\u00D6HN SM\\u00CFTH",
1783 struct teststruct tests
[] = {
1784 {"\\u010CAKI MIHALJ", {0}},
1785 {"\\u010CAKI MIHALJ", {0}},
1786 {"\\u010CAKI PIRO\\u0160KA", {0}},
1787 {"\\u010CABAI ANDRIJA", {0}},
1788 {"\\u010CABAI LAJO\\u0160", {0}},
1789 {"\\u010CABAI MARIJA", {0}},
1790 {"\\u010CABAI STEVAN", {0}},
1791 {"\\u010CABAI STEVAN", {0}},
1792 {"\\u010CABARKAPA BRANKO", {0}},
1793 {"\\u010CABARKAPA MILENKO", {0}},
1794 {"\\u010CABARKAPA MIROSLAV", {0}},
1795 {"\\u010CABARKAPA SIMO", {0}},
1796 {"\\u010CABARKAPA STANKO", {0}},
1797 {"\\u010CABARKAPA TAMARA", {0}},
1798 {"\\u010CABARKAPA TOMA\\u0160", {0}},
1799 {"\\u010CABDARI\\u0106 NIKOLA", {0}},
1800 {"\\u010CABDARI\\u0106 ZORICA", {0}},
1801 {"\\u010CABI NANDOR", {0}},
1802 {"\\u010CABOVI\\u0106 MILAN", {0}},
1803 {"\\u010CABRADI AGNEZIJA", {0}},
1804 {"\\u010CABRADI IVAN", {0}},
1805 {"\\u010CABRADI JELENA", {0}},
1806 {"\\u010CABRADI LJUBICA", {0}},
1807 {"\\u010CABRADI STEVAN", {0}},
1808 {"\\u010CABRDA MARTIN", {0}},
1809 {"\\u010CABRILO BOGDAN", {0}},
1810 {"\\u010CABRILO BRANISLAV", {0}},
1811 {"\\u010CABRILO LAZAR", {0}},
1812 {"\\u010CABRILO LJUBICA", {0}},
1813 {"\\u010CABRILO SPASOJA", {0}},
1814 {"\\u010CADE\\u0160 ZDENKA", {0}},
1815 {"\\u010CADESKI BLAGOJE", {0}},
1816 {"\\u010CADOVSKI VLADIMIR", {0}},
1817 {"\\u010CAGLJEVI\\u0106 TOMA", {0}},
1818 {"\\u010CAGOROVI\\u0106 VLADIMIR", {0}},
1819 {"\\u010CAJA VANKA", {0}},
1820 {"\\u010CAJI\\u0106 BOGOLJUB", {0}},
1821 {"\\u010CAJI\\u0106 BORISLAV", {0}},
1822 {"\\u010CAJI\\u0106 RADOSLAV", {0}},
1823 {"\\u010CAK\\u0160IRAN MILADIN", {0}},
1824 {"\\u010CAKAN EUGEN", {0}},
1825 {"\\u010CAKAN EVGENIJE", {0}},
1826 {"\\u010CAKAN IVAN", {0}},
1827 {"\\u010CAKAN JULIJAN", {0}},
1828 {"\\u010CAKAN MIHAJLO", {0}},
1829 {"\\u010CAKAN STEVAN", {0}},
1830 {"\\u010CAKAN VLADIMIR", {0}},
1831 {"\\u010CAKAN VLADIMIR", {0}},
1832 {"\\u010CAKAN VLADIMIR", {0}},
1833 {"\\u010CAKARA ANA", {0}},
1834 {"\\u010CAKAREVI\\u0106 MOMIR", {0}},
1835 {"\\u010CAKAREVI\\u0106 NEDELJKO", {0}},
1836 {"\\u010CAKI \\u0160ANDOR", {0}},
1837 {"\\u010CAKI AMALIJA", {0}},
1838 {"\\u010CAKI ANDRA\\u0160", {0}},
1839 {"\\u010CAKI LADISLAV", {0}},
1840 {"\\u010CAKI LAJO\\u0160", {0}},
1841 {"\\u010CAKI LASLO", {0}}
1846 int32_t i
= 0, j
= 0, k
= 0, buffSize
= 0, skSize
= 0, lowerSize
= 0, upperSize
= 0;
1847 int32_t arraySize
= sizeof(tests
)/sizeof(tests
[0]);
1849 (void)lowerSize
; // Suppress unused variable warnings.
1852 for(i
= 0; i
<arraySize
; i
++) {
1853 buffSize
= u_unescape(tests
[i
].original
, buffer
, 512);
1854 skSize
= coll
->getSortKey(buffer
, buffSize
, tests
[i
].key
, 512);
1857 qsort(tests
, arraySize
, sizeof(struct teststruct
), compare_teststruct
);
1859 for(i
= 0; i
< arraySize
-1; i
++) {
1860 for(j
= i
+1; j
< arraySize
; j
++) {
1861 lowerSize
= coll
->getBound(tests
[i
].key
, -1, UCOL_BOUND_LOWER
, 1, lower
, 512, status
);
1862 upperSize
= coll
->getBound(tests
[j
].key
, -1, UCOL_BOUND_UPPER
, 1, upper
, 512, status
);
1863 for(k
= i
; k
<= j
; k
++) {
1864 if(strcmp((const char *)lower
, (const char *)tests
[k
].key
) > 0) {
1865 errln("Problem with lower! j = %i (%s vs %s)", k
, tests
[k
].original
, tests
[i
].original
);
1867 if(strcmp((const char *)upper
, (const char *)tests
[k
].key
) <= 0) {
1868 errln("Problem with upper! j = %i (%s vs %s)", k
, tests
[k
].original
, tests
[j
].original
);
1875 for(i
= 0; i
<(int32_t)(sizeof(test
)/sizeof(test
[0])); i
++) {
1876 buffSize
= u_unescape(test
[i
], buffer
, 512);
1877 skSize
= coll
->getSortKey(buffer
, buffSize
, sortkey
, 512);
1878 lowerSize
= ucol_getBound(sortkey
, skSize
, UCOL_BOUND_LOWER
, 1, lower
, 512, &status
);
1879 upperSize
= ucol_getBound(sortkey
, skSize
, UCOL_BOUND_UPPER_LONG
, 1, upper
, 512, &status
);
1880 for(j
= i
+1; j
<(int32_t)(sizeof(test
)/sizeof(test
[0])); j
++) {
1881 buffSize
= u_unescape(test
[j
], buffer
, 512);
1882 skSize
= coll
->getSortKey(buffer
, buffSize
, sortkey
, 512);
1883 if(strcmp((const char *)lower
, (const char *)sortkey
) > 0) {
1884 errln("Problem with lower! i = %i, j = %i (%s vs %s)", i
, j
, test
[i
], test
[j
]);
1886 if(strcmp((const char *)upper
, (const char *)sortkey
) <= 0) {
1887 errln("Problem with upper! i = %i, j = %i (%s vs %s)", i
, j
, test
[i
], test
[j
]);
1895 void CollationAPITest::TestGetTailoredSet()
1899 const char *tests
[20];
1902 { "&a < \\u212b", { "\\u212b", "A\\u030a", "\\u00c5" }, 3},
1903 { "& S < \\u0161 <<< \\u0160", { "\\u0161", "s\\u030C", "\\u0160", "S\\u030C" }, 4}
1906 int32_t i
= 0, j
= 0;
1907 UErrorCode status
= U_ZERO_ERROR
;
1910 UnicodeSet
*set
= NULL
;
1912 for(i
= 0; i
< LENGTHOF(setTest
); i
++) {
1913 buff
= UnicodeString(setTest
[i
].rules
, -1, US_INV
).unescape();
1914 RuleBasedCollator
coll(buff
, status
);
1915 if(U_SUCCESS(status
)) {
1916 set
= coll
.getTailoredSet(status
);
1917 if(set
->size() < setTest
[i
].testsize
) {
1918 errln("Tailored set size smaller (%d) than expected (%d)", set
->size(), setTest
[i
].testsize
);
1920 for(j
= 0; j
< setTest
[i
].testsize
; j
++) {
1921 buff
= UnicodeString(setTest
[i
].tests
[j
], -1, US_INV
).unescape();
1922 if(!set
->contains(buff
)) {
1923 errln("Tailored set doesn't contain %s... It should", setTest
[i
].tests
[j
]);
1928 errcheckln(status
, "Couldn't open collator with rules %s - %s", setTest
[i
].rules
, u_errorName(status
));
1933 void CollationAPITest::TestUClassID()
1935 char id
= *((char *)RuleBasedCollator::getStaticClassID());
1937 errln("Static class id for RuleBasedCollator should be 0");
1939 UErrorCode status
= U_ZERO_ERROR
;
1940 RuleBasedCollator
*coll
1941 = (RuleBasedCollator
*)Collator::createInstance(status
);
1942 if(U_FAILURE(status
)) {
1944 errcheckln(status
, "Collator creation failed with %s", u_errorName(status
));
1947 id
= *((char *)coll
->getDynamicClassID());
1949 errln("Dynamic class id for RuleBasedCollator should be 0");
1951 id
= *((char *)CollationKey::getStaticClassID());
1953 errln("Static class id for CollationKey should be 0");
1955 CollationKey
*key
= new CollationKey();
1956 id
= *((char *)key
->getDynamicClassID());
1958 errln("Dynamic class id for CollationKey should be 0");
1960 id
= *((char *)CollationElementIterator::getStaticClassID());
1962 errln("Static class id for CollationElementIterator should be 0");
1964 UnicodeString
str("testing");
1965 CollationElementIterator
*iter
= coll
->createCollationElementIterator(str
);
1966 id
= *((char *)iter
->getDynamicClassID());
1968 errln("Dynamic class id for CollationElementIterator should be 0");
1975 class TestCollator
: public Collator
1978 virtual Collator
* clone(void) const;
1980 using Collator::compare
;
1982 virtual UCollationResult
compare(const UnicodeString
& source
,
1983 const UnicodeString
& target
,
1984 UErrorCode
& status
) const;
1985 virtual UCollationResult
compare(const UnicodeString
& source
,
1986 const UnicodeString
& target
,
1988 UErrorCode
& status
) const;
1989 virtual UCollationResult
compare(const UChar
* source
,
1990 int32_t sourceLength
,
1991 const UChar
* target
,
1992 int32_t targetLength
,
1993 UErrorCode
& status
) const;
1994 virtual CollationKey
& getCollationKey(const UnicodeString
& source
,
1996 UErrorCode
& status
) const;
1997 virtual CollationKey
& getCollationKey(const UChar
*source
,
1998 int32_t sourceLength
,
2000 UErrorCode
& status
) const;
2001 virtual int32_t hashCode(void) const;
2002 virtual Locale
getLocale(ULocDataLocaleType type
, UErrorCode
& status
) const;
2003 virtual ECollationStrength
getStrength(void) const;
2004 virtual void setStrength(ECollationStrength newStrength
);
2005 virtual UClassID
getDynamicClassID(void) const;
2006 virtual void getVersion(UVersionInfo info
) const;
2007 virtual void setAttribute(UColAttribute attr
, UColAttributeValue value
,
2008 UErrorCode
&status
);
2009 virtual UColAttributeValue
getAttribute(UColAttribute attr
,
2010 UErrorCode
&status
) const;
2011 virtual uint32_t setVariableTop(const UChar
*varTop
, int32_t len
,
2012 UErrorCode
&status
);
2013 virtual uint32_t setVariableTop(const UnicodeString
&varTop
,
2014 UErrorCode
&status
);
2015 virtual void setVariableTop(uint32_t varTop
, UErrorCode
&status
);
2016 virtual uint32_t getVariableTop(UErrorCode
&status
) const;
2017 virtual int32_t getSortKey(const UnicodeString
& source
,
2019 int32_t resultLength
) const;
2020 virtual int32_t getSortKey(const UChar
*source
, int32_t sourceLength
,
2021 uint8_t*result
, int32_t resultLength
) const;
2022 virtual UnicodeSet
*getTailoredSet(UErrorCode
&status
) const;
2023 virtual UBool
operator==(const Collator
& other
) const;
2024 // Collator::operator!= calls !Collator::operator== which works for all subclasses.
2025 virtual void setLocales(const Locale
& requestedLocale
, const Locale
& validLocale
, const Locale
& actualLocale
);
2026 TestCollator() : Collator() {};
2027 TestCollator(UCollationStrength collationStrength
,
2028 UNormalizationMode decompositionMode
) : Collator(collationStrength
, decompositionMode
) {};
2031 inline UBool
TestCollator::operator==(const Collator
& other
) const {
2032 // TestCollator has no fields, so we test for identity.
2033 return this == &other
;
2035 // Normally, subclasses should do something like the following:
2036 // if (this == &other) { return TRUE; }
2037 // if (!Collator::operator==(other)) { return FALSE; } // not the same class
2039 // const TestCollator &o = (const TestCollator&)other;
2040 // (compare this vs. o's subclass fields)
2043 Collator
* TestCollator::clone() const
2045 return new TestCollator();
2048 UCollationResult
TestCollator::compare(const UnicodeString
& source
,
2049 const UnicodeString
& target
,
2050 UErrorCode
& status
) const
2052 if(U_SUCCESS(status
)) {
2053 return UCollationResult(source
.compare(target
));
2059 UCollationResult
TestCollator::compare(const UnicodeString
& source
,
2060 const UnicodeString
& target
,
2062 UErrorCode
& status
) const
2064 if(U_SUCCESS(status
)) {
2065 return UCollationResult(source
.compare(0, length
, target
));
2071 UCollationResult
TestCollator::compare(const UChar
* source
,
2072 int32_t sourceLength
,
2073 const UChar
* target
,
2074 int32_t targetLength
,
2075 UErrorCode
& status
) const
2077 UnicodeString
s(source
, sourceLength
);
2078 UnicodeString
t(target
, targetLength
);
2079 return compare(s
, t
, status
);
2082 CollationKey
& TestCollator::getCollationKey(const UnicodeString
& source
,
2084 UErrorCode
& status
) const
2088 length
= source
.extract(temp
, length
, NULL
, status
);
2090 CollationKey
tempkey((uint8_t*)temp
, length
);
2095 CollationKey
& TestCollator::getCollationKey(const UChar
*source
,
2096 int32_t sourceLength
,
2098 UErrorCode
& status
) const
2100 //s tack allocation used since collationkey does not keep the unicodestring
2101 UnicodeString
str(source
, sourceLength
);
2102 return getCollationKey(str
, key
, status
);
2105 int32_t TestCollator::getSortKey(const UnicodeString
& source
, uint8_t* result
,
2106 int32_t resultLength
) const
2108 UErrorCode status
= U_ZERO_ERROR
;
2109 int32_t length
= source
.extract((char *)result
, resultLength
, NULL
,
2115 int32_t TestCollator::getSortKey(const UChar
*source
, int32_t sourceLength
,
2116 uint8_t*result
, int32_t resultLength
) const
2118 UnicodeString
str(source
, sourceLength
);
2119 return getSortKey(str
, result
, resultLength
);
2122 int32_t TestCollator::hashCode() const
2127 Locale
TestCollator::getLocale(ULocDataLocaleType type
, UErrorCode
& status
) const
2129 // api not used, this is to make the compiler happy
2130 if (U_FAILURE(status
)) {
2136 Collator::ECollationStrength
TestCollator::getStrength() const
2141 void TestCollator::setStrength(Collator::ECollationStrength newStrength
)
2143 // api not used, this is to make the compiler happy
2147 UClassID
TestCollator::getDynamicClassID(void) const
2152 void TestCollator::getVersion(UVersionInfo info
) const
2154 // api not used, this is to make the compiler happy
2155 memset(info
, 0, U_MAX_VERSION_LENGTH
);
2158 void TestCollator::setAttribute(UColAttribute
/*attr*/, UColAttributeValue
/*value*/,
2159 UErrorCode
& /*status*/)
2163 UColAttributeValue
TestCollator::getAttribute(UColAttribute attr
,
2164 UErrorCode
&status
) const
2166 // api not used, this is to make the compiler happy
2167 if (U_FAILURE(status
) || attr
== UCOL_ATTRIBUTE_COUNT
) {
2170 return UCOL_DEFAULT
;
2173 uint32_t TestCollator::setVariableTop(const UChar
*varTop
, int32_t len
,
2176 // api not used, this is to make the compiler happy
2177 if (U_SUCCESS(status
) && (varTop
== 0 || len
< -1)) {
2178 status
= U_ILLEGAL_ARGUMENT_ERROR
;
2183 uint32_t TestCollator::setVariableTop(const UnicodeString
&varTop
,
2186 // api not used, this is to make the compiler happy
2187 if (U_SUCCESS(status
) && varTop
.length() == 0) {
2188 status
= U_ILLEGAL_ARGUMENT_ERROR
;
2193 void TestCollator::setVariableTop(uint32_t varTop
, UErrorCode
&status
)
2195 // api not used, this is to make the compiler happy
2196 if (U_SUCCESS(status
) && varTop
== 0) {
2197 status
= U_ILLEGAL_ARGUMENT_ERROR
;
2201 uint32_t TestCollator::getVariableTop(UErrorCode
&status
) const
2204 // api not used, this is to make the compiler happy
2205 if (U_SUCCESS(status
)) {
2208 return (uint32_t)(0xFFFFFFFFu
);
2211 UnicodeSet
* TestCollator::getTailoredSet(UErrorCode
&status
) const
2213 return Collator::getTailoredSet(status
);
2216 void TestCollator::setLocales(const Locale
& requestedLocale
, const Locale
& validLocale
, const Locale
& actualLocale
)
2218 Collator::setLocales(requestedLocale
, validLocale
, actualLocale
);
2222 void CollationAPITest::TestSubclass()
2226 doAssert(col1
!= col2
, "2 instances of TestCollator should be different");
2227 if (col1
.hashCode() != col2
.hashCode()) {
2228 errln("Every TestCollator has the same hashcode");
2230 UnicodeString
abc("abc", 3);
2231 UnicodeString
bcd("bcd", 3);
2232 if (col1
.compare(abc
, bcd
) != abc
.compare(bcd
)) {
2233 errln("TestCollator compare should be the same as the default "
2234 "string comparison");
2237 UErrorCode status
= U_ZERO_ERROR
;
2238 col1
.getCollationKey(abc
, key
, status
);
2240 const char* bytes
= (const char *)key
.getByteArray(length
);
2241 UnicodeString
keyarray(bytes
, length
, NULL
, status
);
2242 if (abc
!= keyarray
) {
2243 errln("TestCollator collationkey API is returning wrong values");
2246 UnicodeSet
expectedset(0, 0x10FFFF);
2247 UnicodeSet
*defaultset
= col1
.getTailoredSet(status
);
2248 if (!defaultset
->containsAll(expectedset
)
2249 || !expectedset
.containsAll(*defaultset
)) {
2250 errln("Error: expected default tailoring to be 0 to 0x10ffff");
2254 // use base class implementation
2255 Locale loc1
= Locale::getGermany();
2256 Locale loc2
= Locale::getFrance();
2257 col1
.setLocales(loc1
, loc2
, loc2
); // default implementation has no effect
2259 UnicodeString displayName
;
2260 col1
.getDisplayName(loc1
, loc2
, displayName
); // de_DE collator in fr_FR locale
2262 TestCollator
col3(UCOL_TERTIARY
, UNORM_NONE
);
2263 UnicodeString
a("a");
2264 UnicodeString
b("b");
2265 Collator::EComparisonResult result
= Collator::EComparisonResult(a
.compare(b
));
2266 if(col1
.compare(a
, b
) != result
) {
2267 errln("Collator doesn't give default result");
2269 if(col1
.compare(a
, b
, 1) != result
) {
2270 errln("Collator doesn't give default result");
2272 if(col1
.compare(a
.getBuffer(), a
.length(), b
.getBuffer(), b
.length()) != result
) {
2273 errln("Collator doesn't give default result");
2277 void CollationAPITest::TestNULLCharTailoring()
2279 UErrorCode status
= U_ZERO_ERROR
;
2280 UChar buf
[256] = {0};
2281 int32_t len
= u_unescape("&a < '\\u0000'", buf
, 256);
2282 UnicodeString
first((UChar
)0x0061);
2283 UnicodeString
second((UChar
)0);
2284 RuleBasedCollator
*coll
= new RuleBasedCollator(UnicodeString(buf
, len
), status
);
2285 if(U_FAILURE(status
)) {
2287 errcheckln(status
, "Failed to open collator - %s", u_errorName(status
));
2290 UCollationResult res
= coll
->compare(first
, second
, status
);
2291 if(res
!= UCOL_LESS
) {
2292 errln("a should be less then NULL after tailoring");
2297 void CollationAPITest::TestClone() {
2299 UErrorCode status
= U_ZERO_ERROR
;
2300 RuleBasedCollator
* c0
= (RuleBasedCollator
*)Collator::createInstance(status
);
2302 if (U_FAILURE(status
)) {
2303 errcheckln(status
, "Collator::CreateInstance(status) failed with %s", u_errorName(status
));
2307 c0
->setStrength(Collator::TERTIARY
);
2308 dump("c0", c0
, status
);
2311 RuleBasedCollator
* c1
= (RuleBasedCollator
*)Collator::createInstance(status
);
2312 c1
->setStrength(Collator::TERTIARY
);
2313 UColAttributeValue val
= c1
->getAttribute(UCOL_CASE_FIRST
, status
);
2314 if(val
== UCOL_LOWER_FIRST
){
2315 c1
->setAttribute(UCOL_CASE_FIRST
, UCOL_UPPER_FIRST
, status
);
2317 c1
->setAttribute(UCOL_CASE_FIRST
, UCOL_LOWER_FIRST
, status
);
2319 dump("c0", c0
, status
);
2320 dump("c1", c1
, status
);
2323 RuleBasedCollator
* c2
= (RuleBasedCollator
*)c1
->clone();
2324 val
= c2
->getAttribute(UCOL_CASE_FIRST
, status
);
2325 if(val
== UCOL_LOWER_FIRST
){
2326 c2
->setAttribute(UCOL_CASE_FIRST
, UCOL_UPPER_FIRST
, status
);
2328 c2
->setAttribute(UCOL_CASE_FIRST
, UCOL_LOWER_FIRST
, status
);
2330 if(U_FAILURE(status
)){
2331 errln("set and get attributes of collator failed. %s\n", u_errorName(status
));
2334 dump("c0", c0
, status
);
2335 dump("c1", c1
, status
);
2336 dump("c2", c2
, status
);
2338 errln("The cloned objects refer to same data");
2345 void CollationAPITest::TestCloneBinary() {
2346 IcuTestErrorCode
errorCode(*this, "TestCloneBinary");
2347 LocalPointer
<Collator
> root(Collator::createInstance(Locale::getRoot(), errorCode
));
2348 LocalPointer
<Collator
> coll(Collator::createInstance("de@collation=phonebook", errorCode
));
2349 if(errorCode
.logDataIfFailureAndReset("Collator::createInstance(de@collation=phonebook)")) {
2352 RuleBasedCollator
*rbRoot
= dynamic_cast<RuleBasedCollator
*>(root
.getAlias());
2353 RuleBasedCollator
*rbc
= dynamic_cast<RuleBasedCollator
*>(coll
.getAlias());
2354 if(rbRoot
== NULL
|| rbc
== NULL
) {
2355 infoln("root or de@collation=phonebook is not a RuleBasedCollator");
2358 rbc
->setAttribute(UCOL_STRENGTH
, UCOL_PRIMARY
, errorCode
);
2359 UnicodeString
uUmlaut((UChar
)0xfc);
2360 UnicodeString ue
= UNICODE_STRING_SIMPLE("ue");
2361 assertEquals("rbc/primary: u-umlaut==ue", UCOL_EQUAL
, rbc
->compare(uUmlaut
, ue
, errorCode
));
2363 int32_t binLength
= rbc
->cloneBinary(bin
, LENGTHOF(bin
), errorCode
);
2364 if(errorCode
.logDataIfFailureAndReset("rbc->cloneBinary()")) {
2367 logln("rbc->cloneBinary() -> %d bytes", (int)binLength
);
2369 RuleBasedCollator
rbc2(bin
, binLength
, rbRoot
, errorCode
);
2370 if(errorCode
.logDataIfFailureAndReset("RuleBasedCollator(rbc binary)")) {
2373 assertEquals("rbc2.strength==primary", UCOL_PRIMARY
, rbc2
.getAttribute(UCOL_STRENGTH
, errorCode
));
2374 assertEquals("rbc2: u-umlaut==ue", UCOL_EQUAL
, rbc2
.compare(uUmlaut
, ue
, errorCode
));
2375 assertTrue("rbc==rbc2", *rbc
== rbc2
);
2376 uint8_t bin2
[25000];
2377 int32_t bin2Length
= rbc2
.cloneBinary(bin2
, LENGTHOF(bin2
), errorCode
);
2378 assertEquals("len(rbc binary)==len(rbc2 binary)", binLength
, bin2Length
);
2379 assertTrue("rbc binary==rbc2 binary", binLength
== bin2Length
&& memcmp(bin
, bin2
, binLength
) == 0);
2382 void CollationAPITest::TestIterNumeric() {
2383 // Regression test for ticket #9915.
2384 // The collation code sometimes masked the continuation marker away
2385 // but later tested the result for isContinuation().
2386 // This test case failed because the third bytes of the computed numeric-collation primaries
2387 // were permutated with the script reordering table.
2388 // It should have been possible to reproduce this with the root collator
2389 // and characters with appropriate 3-byte primary weights.
2390 // The effectiveness of this test depends completely on the collation elements
2391 // and on the implementation code.
2392 IcuTestErrorCode
errorCode(*this, "TestIterNumeric");
2393 RuleBasedCollator
coll(UnicodeString("[reorder Hang Hani]"), errorCode
);
2394 if(errorCode
.logDataIfFailureAndReset("RuleBasedCollator constructor")) {
2397 coll
.setAttribute(UCOL_NUMERIC_COLLATION
, UCOL_ON
, errorCode
);
2398 UCharIterator iter40
, iter72
;
2399 uiter_setUTF8(&iter40
, "\x34\x30", 2);
2400 uiter_setUTF8(&iter72
, "\x37\x32", 2);
2401 UCollationResult result
= coll
.compare(iter40
, iter72
, errorCode
);
2402 assertEquals("40<72", (int32_t)UCOL_LESS
, (int32_t)result
);
2405 void CollationAPITest::dump(UnicodeString msg
, RuleBasedCollator
* c
, UErrorCode
& status
) {
2406 const char* bigone
= "One";
2407 const char* littleone
= "one";
2409 logln(msg
+ " " + c
->compare(bigone
, littleone
) +
2410 " s: " + c
->getStrength() +
2411 " u: " + c
->getAttribute(UCOL_CASE_FIRST
, status
));
2413 void CollationAPITest::runIndexedTest( int32_t index
, UBool exec
, const char* &name
, char* /*par */)
2415 if (exec
) logln("TestSuite CollationAPITest: ");
2416 TESTCASE_AUTO_BEGIN
;
2417 TESTCASE_AUTO(TestProperty
);
2418 TESTCASE_AUTO(TestOperators
);
2419 TESTCASE_AUTO(TestDuplicate
);
2420 TESTCASE_AUTO(TestCompare
);
2421 TESTCASE_AUTO(TestHashCode
);
2422 TESTCASE_AUTO(TestCollationKey
);
2423 TESTCASE_AUTO(TestElemIter
);
2424 TESTCASE_AUTO(TestGetAll
);
2425 TESTCASE_AUTO(TestRuleBasedColl
);
2426 TESTCASE_AUTO(TestDecomposition
);
2427 TESTCASE_AUTO(TestSafeClone
);
2428 TESTCASE_AUTO(TestSortKey
);
2429 TESTCASE_AUTO(TestSortKeyOverflow
);
2430 TESTCASE_AUTO(TestMaxExpansion
);
2431 TESTCASE_AUTO(TestDisplayName
);
2432 TESTCASE_AUTO(TestAttribute
);
2433 TESTCASE_AUTO(TestVariableTopSetting
);
2434 TESTCASE_AUTO(TestMaxVariable
);
2435 TESTCASE_AUTO(TestRules
);
2436 TESTCASE_AUTO(TestGetLocale
);
2437 TESTCASE_AUTO(TestBounds
);
2438 TESTCASE_AUTO(TestGetTailoredSet
);
2439 TESTCASE_AUTO(TestUClassID
);
2440 TESTCASE_AUTO(TestSubclass
);
2441 TESTCASE_AUTO(TestNULLCharTailoring
);
2442 TESTCASE_AUTO(TestClone
);
2443 TESTCASE_AUTO(TestCloneBinary
);
2444 TESTCASE_AUTO(TestIterNumeric
);
2448 #endif /* #if !UCONFIG_NO_COLLATION */