1 /********************************************************************
2 * COPYRIGHT:
3 * Copyright (c) 1997-2012, International Business Machines Corporation and
4 * others. All Rights Reserved.
5 ********************************************************************/
6 //===============================================================================
7 //
8 // File apitest.cpp
9 //
10 //
11 //
12 // Created by: Helena Shih
13 //
14 // Modification History:
15 //
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
22 // in binary mode.
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
26 // testing.
27 // 02/10/98 damiba Added test for compare(UnicodeString&, UnicodeString&, int32_t)
28 //===============================================================================
29
30 #include "unicode/utypes.h"
31
32 #if !UCONFIG_NO_COLLATION
33
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"
39 #include "apicoll.h"
40 #include "unicode/chariter.h"
41 #include "unicode/schriter.h"
42 #include "unicode/ustring.h"
43 #include "unicode/ucol.h"
44
45 #include "sfwdchit.h"
46 #include "cmemory.h"
47 #include <stdlib.h>
48
49 #define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
50
51 void
doAssert(UBool condition,const char * message)52 CollationAPITest::doAssert(UBool condition, const char *message)
53 {
54 if (!condition) {
55 errln(UnicodeString("ERROR : ") + message);
56 }
57 }
58
59 #ifdef U_USE_COLLATION_OBSOLETE_2_6
60 /*
61 * Test Collator::createInstance(... version...) for some locale. Called by TestProperty().
62 */
63 static void
TestOpenVersion(IntlTest & test,const Locale & locale)64 TestOpenVersion(IntlTest &test, const Locale &locale) {
65 UVersionInfo version1, version2;
66 Collator *collator1, *collator2;
67 UErrorCode errorCode;
68
69 errorCode=U_ZERO_ERROR;
70 collator1=Collator::createInstance(locale, errorCode);
71 if(U_SUCCESS(errorCode)) {
72 /* get the current version */
73 collator1->getVersion(version1);
74 delete collator1;
75
76 /* try to get that same version again */
77 collator2=Collator::createInstance(locale, version1, errorCode);
78 if(U_SUCCESS(errorCode)) {
79 collator2->getVersion(version2);
80 if(0!=uprv_memcmp(version1, version2, sizeof(UVersionInfo))) {
81 test.errln("error: Collator::createInstance(\"%s\", (%s collator)->getVersion()) returns a different collator\n", locale.getName(), locale.getName());
82 }
83 delete collator2;
84 } else {
85 test.errln("error: Collator::createInstance(\"%s\", (%s collator)->getVersion()) fails: %s\n", locale.getName(), locale.getName(), u_errorName(errorCode));
86 }
87 }
88 }
89 #endif
90
91 // Collator Class Properties
92 // ctor, dtor, createInstance, compare, getStrength/setStrength
93 // getDecomposition/setDecomposition, getDisplayName
94 void
TestProperty()95 CollationAPITest::TestProperty(/* char* par */)
96 {
97 UErrorCode success = U_ZERO_ERROR;
98 Collator *col = 0;
99 /*
100 * Expected version of the English collator.
101 * Currently, the major/minor version numbers change when the builder code
102 * changes,
103 * number 2 is from the tailoring data version and
104 * number 3 is the UCA version.
105 * This changes with every UCA version change, and the expected value
106 * needs to be adjusted.
107 * Same in cintltst/capitst.c.
108 */
109 UVersionInfo currVersionArray = {0x31, 0xC0, 0x05, 0x2A}; // from ICU 4.4/UCA 5.2
110 UVersionInfo versionArray;
111
112 logln("The property tests begin : ");
113 logln("Test ctors : ");
114 col = Collator::createInstance(Locale::getEnglish(), success);
115 if (U_FAILURE(success)){
116 errcheckln(success, "Default Collator creation failed. - %s", u_errorName(success));
117 return;
118 }
119
120 StringEnumeration* kwEnum = col->getKeywordValuesForLocale("", Locale::getEnglish(),true,success);
121 if (U_FAILURE(success)){
122 errcheckln(success, "Get Keyword Values for Locale failed. - %s", u_errorName(success));
123 return;
124 }
125 delete kwEnum;
126
127 col->getVersion(versionArray);
128 // Check for a version greater than some value rather than equality
129 // so that we need not update the expected version each time.
130 if (uprv_memcmp(versionArray, currVersionArray, 4)<0) {
131 errln("Testing Collator::getVersion() - unexpected result: %02x.%02x.%02x.%02x",
132 versionArray[0], versionArray[1], versionArray[2], versionArray[3]);
133 } else {
134 logln("Collator::getVersion() result: %02x.%02x.%02x.%02x",
135 versionArray[0], versionArray[1], versionArray[2], versionArray[3]);
136 }
137
138 doAssert((col->compare("ab", "abc") == Collator::LESS), "ab < abc comparison failed");
139 doAssert((col->compare("ab", "AB") == Collator::LESS), "ab < AB comparison failed");
140 doAssert((col->compare("blackbird", "black-bird") == Collator::GREATER), "black-bird > blackbird comparison failed");
141 doAssert((col->compare("black bird", "black-bird") == Collator::LESS), "black bird > black-bird comparison failed");
142 doAssert((col->compare("Hello", "hello") == Collator::GREATER), "Hello > hello comparison failed");
143 doAssert((col->compare("","",success) == UCOL_EQUAL), "Comparison between empty strings failed");
144
145 doAssert((col->compareUTF8("\x61\x62\xc3\xa4", "\x61\x62\xc3\x9f", success) == UCOL_LESS), "ab a-umlaut < ab sharp-s UTF-8 comparison failed");
146 success = U_ZERO_ERROR;
147 {
148 UnicodeString abau=UNICODE_STRING_SIMPLE("\\x61\\x62\\xe4").unescape();
149 UnicodeString abss=UNICODE_STRING_SIMPLE("\\x61\\x62\\xdf").unescape();
150 UCharIterator abauIter, abssIter;
151 uiter_setReplaceable(&abauIter, &abau);
152 uiter_setReplaceable(&abssIter, &abss);
153 doAssert((col->compare(abauIter, abssIter, success) == UCOL_LESS), "ab a-umlaut < ab sharp-s UCharIterator comparison failed");
154 success = U_ZERO_ERROR;
155 }
156
157 /*start of update [Bertrand A. D. 02/10/98]*/
158 doAssert((col->compare("ab", "abc", 2) == Collator::EQUAL), "ab = abc with length 2 comparison failed");
159 doAssert((col->compare("ab", "AB", 2) == Collator::LESS), "ab < AB with length 2 comparison failed");
160 doAssert((col->compare("ab", "Aa", 1) == Collator::LESS), "ab < Aa with length 1 comparison failed");
161 doAssert((col->compare("ab", "Aa", 2) == Collator::GREATER), "ab > Aa with length 2 comparison failed");
162 doAssert((col->compare("black-bird", "blackbird", 5) == Collator::EQUAL), "black-bird = blackbird with length of 5 comparison failed");
163 doAssert((col->compare("black bird", "black-bird", 10) == Collator::LESS), "black bird < black-bird with length 10 comparison failed");
164 doAssert((col->compare("Hello", "hello", 5) == Collator::GREATER), "Hello > hello with length 5 comparison failed");
165 /*end of update [Bertrand A. D. 02/10/98]*/
166
167
168 logln("Test ctors ends.");
169 logln("testing Collator::getStrength() method ...");
170 doAssert((col->getStrength() == Collator::TERTIARY), "collation object has the wrong strength");
171 doAssert((col->getStrength() != Collator::PRIMARY), "collation object's strength is primary difference");
172
173
174 logln("testing Collator::setStrength() method ...");
175 col->setStrength(Collator::SECONDARY);
176 doAssert((col->getStrength() != Collator::TERTIARY), "collation object's strength is secondary difference");
177 doAssert((col->getStrength() != Collator::PRIMARY), "collation object's strength is primary difference");
178 doAssert((col->getStrength() == Collator::SECONDARY), "collation object has the wrong strength");
179
180 UnicodeString name;
181
182 logln("Get display name for the US English collation in German : ");
183 logln(Collator::getDisplayName(Locale::getUS(), Locale::getGerman(), name));
184 doAssert((name == UnicodeString("Englisch (Vereinigte Staaten)")), "getDisplayName failed");
185
186 logln("Get display name for the US English collation in English : ");
187 logln(Collator::getDisplayName(Locale::getUS(), Locale::getEnglish(), name));
188 doAssert((name == UnicodeString("English (United States)")), "getDisplayName failed");
189 #if 0
190 // weiv : this test is bogus if we're running on any machine that has different default locale than English.
191 // Therefore, it is banned!
192 logln("Get display name for the US English in default locale language : ");
193 logln(Collator::getDisplayName(Locale::US, name));
194 doAssert((name == UnicodeString("English (United States)")), "getDisplayName failed if this is an English machine");
195 #endif
196 delete col; col = 0;
197
198 // BEGIN android-changed
199 // To save space, Android does not include the collation tailoring rules.
200 // We skip the tailing tests for collations.
201 /*
202 RuleBasedCollator *rcol = (RuleBasedCollator *)Collator::createInstance("da_DK",
203 success);
204 doAssert(rcol->getRules().length() != 0, "da_DK rules does not have length 0");
205 delete rcol;
206 */
207 // END android-changed
208
209 col = Collator::createInstance(Locale::getFrench(), success);
210 if (U_FAILURE(success))
211 {
212 errln("Creating French collation failed.");
213 return;
214 }
215
216 col->setStrength(Collator::PRIMARY);
217 logln("testing Collator::getStrength() method again ...");
218 doAssert((col->getStrength() != Collator::TERTIARY), "collation object has the wrong strength");
219 doAssert((col->getStrength() == Collator::PRIMARY), "collation object's strength is not primary difference");
220
221 logln("testing French Collator::setStrength() method ...");
222 col->setStrength(Collator::TERTIARY);
223 doAssert((col->getStrength() == Collator::TERTIARY), "collation object's strength is not tertiary difference");
224 doAssert((col->getStrength() != Collator::PRIMARY), "collation object's strength is primary difference");
225 doAssert((col->getStrength() != Collator::SECONDARY), "collation object's strength is secondary difference");
226
227 logln("Create junk collation: ");
228 Locale abcd("ab", "CD", "");
229 success = U_ZERO_ERROR;
230 Collator *junk = 0;
231 junk = Collator::createInstance(abcd, success);
232
233 if (U_FAILURE(success))
234 {
235 errln("Junk collation creation failed, should at least return default.");
236 delete col;
237 return;
238 }
239
240 delete col;
241 col = Collator::createInstance(success);
242 if (U_FAILURE(success))
243 {
244 errln("Creating default collator failed.");
245 delete junk;
246 return;
247 }
248
249 doAssert(((RuleBasedCollator *)col)->getRules() == ((RuleBasedCollator *)junk)->getRules(),
250 "The default collation should be returned.");
251 Collator *frCol = Collator::createInstance(Locale::getCanadaFrench(), success);
252 if (U_FAILURE(success))
253 {
254 errln("Creating fr_CA collator failed.");
255 delete col;
256 delete junk;
257 return;
258 }
259
260 // If the default locale isn't French, the French and non-French collators
261 // should be different
262 if (frCol->getLocale(ULOC_ACTUAL_LOCALE, success) != Locale::getCanadaFrench()) {
263 doAssert((*frCol != *junk), "The junk is the same as the fr_CA collator.");
264 }
265 Collator *aFrCol = frCol->clone();
266 doAssert((*frCol == *aFrCol), "The cloning of a fr_CA collator failed.");
267 logln("Collator property test ended.");
268
269 delete col;
270 delete frCol;
271 delete aFrCol;
272 delete junk;
273
274 #ifdef U_USE_COLLATION_OBSOLETE_2_6
275 /* test Collator::createInstance(...version...) */
276 TestOpenVersion(*this, "");
277 TestOpenVersion(*this, "da");
278 TestOpenVersion(*this, "fr");
279 TestOpenVersion(*this, "ja");
280
281 /* try some bogus version */
282 versionArray[0]=0;
283 versionArray[1]=0x99;
284 versionArray[2]=0xc7;
285 versionArray[3]=0xfe;
286 col=Collator::createInstance(Locale(), versionArray, success);
287 if(U_SUCCESS(success)) {
288 errln("error: ucol_openVersion(bogus version) succeeded");
289 delete col;
290 }
291 #endif
292 }
293
294 void
TestRuleBasedColl()295 CollationAPITest::TestRuleBasedColl()
296 {
297 RuleBasedCollator *col1, *col2, *col3, *col4;
298 UErrorCode status = U_ZERO_ERROR;
299
300 UnicodeString ruleset1("&9 < a, A < b, B < c, C; ch, cH, Ch, CH < d, D, e, E");
301 UnicodeString ruleset2("&9 < a, A < b, B < c, C < d, D, e, E");
302
303 col1 = new RuleBasedCollator(ruleset1, status);
304 if (U_FAILURE(status)) {
305 errcheckln(status, "RuleBased Collator creation failed. - %s", u_errorName(status));
306 return;
307 }
308 else {
309 logln("PASS: RuleBased Collator creation passed\n");
310 }
311
312 status = U_ZERO_ERROR;
313 col2 = new RuleBasedCollator(ruleset2, status);
314 if (U_FAILURE(status)) {
315 errln("RuleBased Collator creation failed.\n");
316 return;
317 }
318 else {
319 logln("PASS: RuleBased Collator creation passed\n");
320 }
321
322 status = U_ZERO_ERROR;
323 Locale locale("aa", "AA");
324 col3 = (RuleBasedCollator *)Collator::createInstance(locale, status);
325 if (U_FAILURE(status)) {
326 errln("Fallback Collator creation failed.: %s\n");
327 return;
328 }
329 else {
330 logln("PASS: Fallback Collator creation passed\n");
331 }
332 delete col3;
333
334 status = U_ZERO_ERROR;
335 col3 = (RuleBasedCollator *)Collator::createInstance(status);
336 if (U_FAILURE(status)) {
337 errln("Default Collator creation failed.: %s\n");
338 return;
339 }
340 else {
341 logln("PASS: Default Collator creation passed\n");
342 }
343
344 UnicodeString rule1 = col1->getRules();
345 UnicodeString rule2 = col2->getRules();
346 UnicodeString rule3 = col3->getRules();
347
348 doAssert(rule1 != rule2, "Default collator getRules failed");
349 doAssert(rule2 != rule3, "Default collator getRules failed");
350 doAssert(rule1 != rule3, "Default collator getRules failed");
351
352 col4 = new RuleBasedCollator(rule2, status);
353 if (U_FAILURE(status)) {
354 errln("RuleBased Collator creation failed.\n");
355 return;
356 }
357
358 UnicodeString rule4 = col4->getRules();
359 doAssert(rule2 == rule4, "Default collator getRules failed");
360 int32_t length4 = 0;
361 uint8_t *clonedrule4 = col4->cloneRuleData(length4, status);
362 if (U_FAILURE(status)) {
363 errln("Cloned rule data failed.\n");
364 return;
365 }
366
367 // free(clonedrule4); BAD API!!!!
368 uprv_free(clonedrule4);
369
370
371 delete col1;
372 delete col2;
373 delete col3;
374 delete col4;
375 }
376
377 void
TestRules()378 CollationAPITest::TestRules()
379 {
380 RuleBasedCollator *coll;
381 UErrorCode status = U_ZERO_ERROR;
382 UnicodeString rules;
383
384 coll = (RuleBasedCollator *)Collator::createInstance(Locale::getEnglish(), status);
385 if (U_FAILURE(status)) {
386 errcheckln(status, "English Collator creation failed. - %s", u_errorName(status));
387 return;
388 }
389 else {
390 logln("PASS: RuleBased Collator creation passed\n");
391 }
392
393 coll->getRules(UCOL_TAILORING_ONLY, rules);
394 if (rules.length() != 0x00) {
395 errln("English tailored rules failed - length is 0x%x expected 0x%x", rules.length(), 0x00);
396 }
397
398 coll->getRules(UCOL_FULL_RULES, rules);
399 if (rules.length() < 0) {
400 errln("English full rules failed");
401 }
402 delete coll;
403 }
404
405 void
TestDecomposition()406 CollationAPITest::TestDecomposition() {
407 UErrorCode status = U_ZERO_ERROR;
408 Collator *en_US = Collator::createInstance("en_US", status),
409 *el_GR = Collator::createInstance("el_GR", status),
410 *vi_VN = Collator::createInstance("vi_VN", status);
411
412 if (U_FAILURE(status)) {
413 errcheckln(status, "ERROR: collation creation failed. - %s", u_errorName(status));
414 return;
415 }
416
417 /* there is no reason to have canonical decomposition in en_US OR default locale */
418 if (vi_VN->getAttribute(UCOL_NORMALIZATION_MODE, status) != UCOL_ON)
419 {
420 errln("ERROR: vi_VN collation did not have canonical decomposition for normalization!\n");
421 }
422
423 if (el_GR->getAttribute(UCOL_NORMALIZATION_MODE, status) != UCOL_ON)
424 {
425 errln("ERROR: el_GR collation did not have canonical decomposition for normalization!\n");
426 }
427
428 if (en_US->getAttribute(UCOL_NORMALIZATION_MODE, status) != UCOL_OFF)
429 {
430 errln("ERROR: en_US collation had canonical decomposition for normalization!\n");
431 }
432
433 delete en_US;
434 delete el_GR;
435 delete vi_VN;
436 }
437
438 void
TestSafeClone()439 CollationAPITest::TestSafeClone() {
440 static const int CLONETEST_COLLATOR_COUNT = 3;
441 Collator *someCollators [CLONETEST_COLLATOR_COUNT];
442 Collator *col;
443 UErrorCode err = U_ZERO_ERROR;
444 int index;
445
446 UnicodeString test1("abCda");
447 UnicodeString test2("abcda");
448
449 /* one default collator & two complex ones */
450 someCollators[0] = Collator::createInstance("en_US", err);
451 someCollators[1] = Collator::createInstance("ko", err);
452 someCollators[2] = Collator::createInstance("ja_JP", err);
453 if(U_FAILURE(err)) {
454 errcheckln(err, "Couldn't instantiate collators. Error: %s", u_errorName(err));
455 delete someCollators[0];
456 delete someCollators[1];
457 delete someCollators[2];
458 return;
459 }
460
461 /* change orig & clone & make sure they are independent */
462
463 for (index = 0; index < CLONETEST_COLLATOR_COUNT; index++)
464 {
465 col = someCollators[index]->safeClone();
466 if (col == 0) {
467 errln("SafeClone of collator should not return null\n");
468 break;
469 }
470 col->setStrength(Collator::TERTIARY);
471 someCollators[index]->setStrength(Collator::PRIMARY);
472 col->setAttribute(UCOL_CASE_LEVEL, UCOL_OFF, err);
473 someCollators[index]->setAttribute(UCOL_CASE_LEVEL, UCOL_OFF, err);
474
475 doAssert(col->greater(test1, test2), "Result should be \"abCda\" >>> \"abcda\" ");
476 doAssert(someCollators[index]->equals(test1, test2), "Result should be \"abcda\" == \"abCda\"");
477 delete col;
478 delete someCollators[index];
479 }
480 }
481
482 void
TestHashCode()483 CollationAPITest::TestHashCode(/* char* par */)
484 {
485 logln("hashCode tests begin.");
486 UErrorCode success = U_ZERO_ERROR;
487 Collator *col1 = 0;
488 col1 = Collator::createInstance(Locale::getEnglish(), success);
489 if (U_FAILURE(success))
490 {
491 errcheckln(success, "Default collation creation failed. - %s", u_errorName(success));
492 return;
493 }
494
495 Collator *col2 = 0;
496 Locale dk("da", "DK", "");
497 col2 = Collator::createInstance(dk, success);
498 if (U_FAILURE(success))
499 {
500 errln("Danish collation creation failed.");
501 return;
502 }
503
504 Collator *col3 = 0;
505 col3 = Collator::createInstance(Locale::getEnglish(), success);
506 if (U_FAILURE(success))
507 {
508 errln("2nd default collation creation failed.");
509 return;
510 }
511
512 logln("Collator::hashCode() testing ...");
513
514 doAssert(col1->hashCode() != col2->hashCode(), "Hash test1 result incorrect" );
515 doAssert(!(col1->hashCode() == col2->hashCode()), "Hash test2 result incorrect" );
516 doAssert(col1->hashCode() == col3->hashCode(), "Hash result not equal" );
517
518 logln("hashCode tests end.");
519 delete col1;
520 delete col2;
521
522 UnicodeString test1("Abcda");
523 UnicodeString test2("abcda");
524
525 CollationKey sortk1, sortk2, sortk3;
526 UErrorCode status = U_ZERO_ERROR;
527
528 col3->getCollationKey(test1, sortk1, status);
529 col3->getCollationKey(test2, sortk2, status);
530 col3->getCollationKey(test2, sortk3, status);
531
532 doAssert(sortk1.hashCode() != sortk2.hashCode(), "Hash test1 result incorrect");
533 doAssert(sortk2.hashCode() == sortk3.hashCode(), "Hash result not equal" );
534
535 delete col3;
536 }
537
538 //----------------------------------------------------------------------------
539 // CollationKey -- Tests the CollationKey methods
540 //
541 void
TestCollationKey()542 CollationAPITest::TestCollationKey(/* char* par */)
543 {
544 logln("testing CollationKey begins...");
545 Collator *col = 0;
546 UErrorCode success=U_ZERO_ERROR;
547 col = Collator::createInstance(Locale::getEnglish(), success);
548 if (U_FAILURE(success))
549 {
550 errcheckln(success, "Default collation creation failed. - %s", u_errorName(success));
551 return;
552 }
553 col->setStrength(Collator::TERTIARY);
554
555 CollationKey sortk1, sortk2;
556 UnicodeString test1("Abcda"), test2("abcda");
557 UErrorCode key1Status = U_ZERO_ERROR, key2Status = U_ZERO_ERROR;
558
559 logln("Testing weird arguments");
560 col->getCollationKey(NULL, 0, sortk1, key1Status);
561 // key gets reset here
562 int32_t length;
563 sortk1.getByteArray(length);
564 doAssert(sortk1.isBogus() == FALSE && length == 0,
565 "Empty string should return an empty collation key");
566 // bogus key returned here
567 key1Status = U_ILLEGAL_ARGUMENT_ERROR;
568 col->getCollationKey(NULL, 0, sortk1, key1Status);
569 doAssert(sortk1.isBogus() && (sortk1.getByteArray(length), length) == 0,
570 "Error code should return bogus collation key");
571
572 key1Status = U_ZERO_ERROR;
573 logln("Use tertiary comparison level testing ....");
574
575 col->getCollationKey(test1, sortk1, key1Status);
576 doAssert((sortk1.compareTo(col->getCollationKey(test2, sortk2, key2Status)))
577 == Collator::GREATER,
578 "Result should be \"Abcda\" >>> \"abcda\"");
579
580 CollationKey sortk3(sortk2), sortkNew, sortkEmpty;
581
582
583 sortkNew = sortk1;
584 doAssert((sortk1 != sortk2), "The sort keys should be different");
585 doAssert((sortk1.hashCode() != sortk2.hashCode()), "sort key hashCode() failed");
586 doAssert((sortk2 == sortk3), "The sort keys should be the same");
587 doAssert((sortk1 == sortkNew), "The sort keys assignment failed");
588 doAssert((sortk1.hashCode() == sortkNew.hashCode()), "sort key hashCode() failed");
589 doAssert((sortkNew != sortk3), "The sort keys should be different");
590 doAssert(sortk1.compareTo(sortk3) == Collator::GREATER, "Result should be \"Abcda\" >>> \"abcda\"");
591 doAssert(sortk2.compareTo(sortk3) == Collator::EQUAL, "Result should be \"abcda\" == \"abcda\"");
592 doAssert(sortkEmpty.compareTo(sortk1) == Collator::LESS, "Result should be (empty key) <<< \"Abcda\"");
593 doAssert(sortk1.compareTo(sortkEmpty) == Collator::GREATER, "Result should be \"Abcda\" >>> (empty key)");
594 doAssert(sortkEmpty.compareTo(sortkEmpty) == Collator::EQUAL, "Result should be (empty key) == (empty key)");
595 doAssert(sortk1.compareTo(sortk3, success) == UCOL_GREATER, "Result should be \"Abcda\" >>> \"abcda\"");
596 doAssert(sortk2.compareTo(sortk3, success) == UCOL_EQUAL, "Result should be \"abcda\" == \"abcda\"");
597 doAssert(sortkEmpty.compareTo(sortk1, success) == UCOL_LESS, "Result should be (empty key) <<< \"Abcda\"");
598 doAssert(sortk1.compareTo(sortkEmpty, success) == UCOL_GREATER, "Result should be \"Abcda\" >>> (empty key)");
599 doAssert(sortkEmpty.compareTo(sortkEmpty, success) == UCOL_EQUAL, "Result should be (empty key) == (empty key)");
600
601 int32_t cnt1, cnt2, cnt3, cnt4;
602
603 const uint8_t* byteArray1 = sortk1.getByteArray(cnt1);
604 const uint8_t* byteArray2 = sortk2.getByteArray(cnt2);
605
606 const uint8_t* byteArray3 = 0;
607 byteArray3 = sortk1.getByteArray(cnt3);
608
609 const uint8_t* byteArray4 = 0;
610 byteArray4 = sortk2.getByteArray(cnt4);
611
612 CollationKey sortk4(byteArray1, cnt1), sortk5(byteArray2, cnt2);
613 CollationKey sortk6(byteArray3, cnt3), sortk7(byteArray4, cnt4);
614
615 doAssert(sortk1.compareTo(sortk4) == Collator::EQUAL, "CollationKey::toByteArray(sortk1) Failed.");
616 doAssert(sortk2.compareTo(sortk5) == Collator::EQUAL, "CollationKey::toByteArray(sortk2) Failed.");
617 doAssert(sortk4.compareTo(sortk5) == Collator::GREATER, "sortk4 >>> sortk5 Failed");
618 doAssert(sortk1.compareTo(sortk6) == Collator::EQUAL, "CollationKey::getByteArray(sortk1) Failed.");
619 doAssert(sortk2.compareTo(sortk7) == Collator::EQUAL, "CollationKey::getByteArray(sortk2) Failed.");
620 doAssert(sortk6.compareTo(sortk7) == Collator::GREATER, "sortk6 >>> sortk7 Failed");
621
622 logln("Equality tests : ");
623 doAssert(sortk1 == sortk4, "sortk1 == sortk4 Failed.");
624 doAssert(sortk2 == sortk5, "sortk2 == sortk5 Failed.");
625 doAssert(sortk1 != sortk5, "sortk1 != sortk5 Failed.");
626 doAssert(sortk1 == sortk6, "sortk1 == sortk6 Failed.");
627 doAssert(sortk2 == sortk7, "sortk2 == sortk7 Failed.");
628 doAssert(sortk1 != sortk7, "sortk1 != sortk7 Failed.");
629
630 byteArray1 = 0;
631 byteArray2 = 0;
632
633 sortk3 = sortk1;
634 doAssert(sortk1 == sortk3, "sortk1 = sortk3 assignment Failed.");
635 doAssert(sortk2 != sortk3, "sortk2 != sortk3 Failed.");
636 logln("testing sortkey ends...");
637
638 col->setStrength(Collator::SECONDARY);
639 doAssert(col->getCollationKey(test1, sortk1, key1Status).compareTo(
640 col->getCollationKey(test2, sortk2, key2Status))
641 == Collator::EQUAL,
642 "Result should be \"Abcda\" == \"abcda\"");
643 delete col;
644 }
645
646 //----------------------------------------------------------------------------
647 // Tests the CollatorElementIterator class.
648 // ctor, RuleBasedCollator::createCollationElementIterator(), operator==, operator!=
649 //
650 void
TestElemIter()651 CollationAPITest::TestElemIter(/* char* par */)
652 {
653 logln("testing sortkey begins...");
654 Collator *col = 0;
655 UErrorCode success = U_ZERO_ERROR;
656 col = Collator::createInstance(Locale::getEnglish(), success);
657 if (U_FAILURE(success))
658 {
659 errcheckln(success, "Default collation creation failed. - %s", u_errorName(success));
660 return;
661 }
662
663 UnicodeString testString1("XFILE What subset of all possible test cases has the highest probability of detecting the most errors?");
664 UnicodeString testString2("Xf_ile What subset of all possible test cases has the lowest probability of detecting the least errors?");
665 logln("Constructors and comparison testing....");
666 CollationElementIterator *iterator1 = ((RuleBasedCollator*)col)->createCollationElementIterator(testString1);
667
668 CharacterIterator *chariter=new StringCharacterIterator(testString1);
669 CollationElementIterator *coliter=((RuleBasedCollator*)col)->createCollationElementIterator(*chariter);
670
671 // copy ctor
672 CollationElementIterator *iterator2 = ((RuleBasedCollator*)col)->createCollationElementIterator(testString1);
673 CollationElementIterator *iterator3 = ((RuleBasedCollator*)col)->createCollationElementIterator(testString2);
674
675 int32_t offset = iterator1->getOffset();
676 if (offset != 0) {
677 errln("Error in getOffset for collation element iterator\n");
678 return;
679 }
680 iterator1->setOffset(6, success);
681 if (U_FAILURE(success)) {
682 errln("Error in setOffset for collation element iterator\n");
683 return;
684 }
685 iterator1->setOffset(0, success);
686 int32_t order1, order2, order3;
687 doAssert((*iterator1 == *iterator2), "The two iterators should be the same");
688 doAssert((*iterator1 != *iterator3), "The two iterators should be different");
689
690 doAssert((*coliter == *iterator1), "The two iterators should be the same");
691 doAssert((*coliter == *iterator2), "The two iterators should be the same");
692 doAssert((*coliter != *iterator3), "The two iterators should be different");
693
694 order1 = iterator1->next(success);
695 if (U_FAILURE(success))
696 {
697 errln("Somehow ran out of memory stepping through the iterator.");
698 return;
699 }
700
701 doAssert((*iterator1 != *iterator2), "The first iterator advance failed");
702 order2 = iterator2->getOffset();
703 doAssert((order1 != order2), "The order result should not be the same");
704 order2 = iterator2->next(success);
705 if (U_FAILURE(success))
706 {
707 errln("Somehow ran out of memory stepping through the iterator.");
708 return;
709 }
710
711 doAssert((*iterator1 == *iterator2), "The second iterator advance failed");
712 doAssert((order1 == order2), "The order result should be the same");
713 order3 = iterator3->next(success);
714 if (U_FAILURE(success))
715 {
716 errln("Somehow ran out of memory stepping through the iterator.");
717 return;
718 }
719
720 doAssert((CollationElementIterator::primaryOrder(order1) ==
721 CollationElementIterator::primaryOrder(order3)), "The primary orders should be the same");
722 doAssert((CollationElementIterator::secondaryOrder(order1) ==
723 CollationElementIterator::secondaryOrder(order3)), "The secondary orders should be the same");
724 doAssert((CollationElementIterator::tertiaryOrder(order1) ==
725 CollationElementIterator::tertiaryOrder(order3)), "The tertiary orders should be the same");
726
727 order1 = iterator1->next(success); order3 = iterator3->next(success);
728 if (U_FAILURE(success))
729 {
730 errln("Somehow ran out of memory stepping through the iterator.");
731 return;
732 }
733
734 doAssert((CollationElementIterator::primaryOrder(order1) ==
735 CollationElementIterator::primaryOrder(order3)), "The primary orders should be identical");
736 doAssert((CollationElementIterator::tertiaryOrder(order1) !=
737 CollationElementIterator::tertiaryOrder(order3)), "The tertiary orders should be different");
738
739 order1 = iterator1->next(success);
740 order3 = iterator3->next(success);
741 /* NO! Secondary orders of two CEs are not related, especially in the case of '_' vs 'I' */
742 /*
743 doAssert((CollationElementIterator::secondaryOrder(order1) !=
744 CollationElementIterator::secondaryOrder(order3)), "The secondary orders should not be the same");
745 */
746 doAssert((order1 != CollationElementIterator::NULLORDER), "Unexpected end of iterator reached");
747
748 iterator1->reset(); iterator2->reset(); iterator3->reset();
749 order1 = iterator1->next(success);
750 if (U_FAILURE(success))
751 {
752 errln("Somehow ran out of memory stepping through the iterator.");
753 return;
754 }
755
756 doAssert((*iterator1 != *iterator2), "The first iterator advance failed");
757
758 order2 = iterator2->next(success);
759 if (U_FAILURE(success))
760 {
761 errln("Somehow ran out of memory stepping through the iterator.");
762 return;
763 }
764
765 doAssert((*iterator1 == *iterator2), "The second iterator advance failed");
766 doAssert((order1 == order2), "The order result should be the same");
767
768 order3 = iterator3->next(success);
769 if (U_FAILURE(success))
770 {
771 errln("Somehow ran out of memory stepping through the iterator.");
772 return;
773 }
774
775 doAssert((CollationElementIterator::primaryOrder(order1) ==
776 CollationElementIterator::primaryOrder(order3)), "The primary orders should be the same");
777 doAssert((CollationElementIterator::secondaryOrder(order1) ==
778 CollationElementIterator::secondaryOrder(order3)), "The secondary orders should be the same");
779 doAssert((CollationElementIterator::tertiaryOrder(order1) ==
780 CollationElementIterator::tertiaryOrder(order3)), "The tertiary orders should be the same");
781
782 order1 = iterator1->next(success); order2 = iterator2->next(success); order3 = iterator3->next(success);
783 if (U_FAILURE(success))
784 {
785 errln("Somehow ran out of memory stepping through the iterator.");
786 return;
787 }
788
789 doAssert((CollationElementIterator::primaryOrder(order1) ==
790 CollationElementIterator::primaryOrder(order3)), "The primary orders should be identical");
791 doAssert((CollationElementIterator::tertiaryOrder(order1) !=
792 CollationElementIterator::tertiaryOrder(order3)), "The tertiary orders should be different");
793
794 order1 = iterator1->next(success); order3 = iterator3->next(success);
795 if (U_FAILURE(success))
796 {
797 errln("Somehow ran out of memory stepping through the iterator.");
798 return;
799 }
800
801 /* NO! Secondary orders of two CEs are not related, especially in the case of '_' vs 'I' */
802 /*
803 doAssert((CollationElementIterator::secondaryOrder(order1) !=
804 CollationElementIterator::secondaryOrder(order3)), "The secondary orders should not be the same");
805 */
806 doAssert((order1 != CollationElementIterator::NULLORDER), "Unexpected end of iterator reached");
807 doAssert((*iterator2 != *iterator3), "The iterators should be different");
808
809
810 //test error values
811 success=U_UNSUPPORTED_ERROR;
812 Collator *colerror=NULL;
813 colerror=Collator::createInstance(Locale::getEnglish(), success);
814 if (colerror != 0 || success == U_ZERO_ERROR){
815 errln("Error: createInstance(UErrorCode != U_ZERO_ERROR) should just return and not create an instance\n");
816 }
817 int32_t position=coliter->previous(success);
818 if(position != CollationElementIterator::NULLORDER){
819 errln((UnicodeString)"Expected NULLORDER got" + position);
820 }
821 coliter->reset();
822 coliter->setText(*chariter, success);
823 if(!U_FAILURE(success)){
824 errln("Expeceted error");
825 }
826 iterator1->setText((UnicodeString)"hello there", success);
827 if(!U_FAILURE(success)){
828 errln("Expeceted error");
829 }
830
831 delete chariter;
832 delete coliter;
833 delete iterator1;
834 delete iterator2;
835 delete iterator3;
836 delete col;
837
838
839
840 logln("testing CollationElementIterator ends...");
841 }
842
843 // Test RuleBasedCollator ctor, dtor, operator==, operator!=, clone, copy, and getRules
844 void
TestOperators()845 CollationAPITest::TestOperators(/* char* par */)
846 {
847 UErrorCode success = U_ZERO_ERROR;
848 UnicodeString ruleset1("< a, A < b, B < c, C; ch, cH, Ch, CH < d, D, e, E");
849 UnicodeString ruleset2("< a, A < b, B < c, C < d, D, e, E");
850 RuleBasedCollator *col1 = new RuleBasedCollator(ruleset1, success);
851 if (U_FAILURE(success)) {
852 errcheckln(success, "RuleBasedCollator creation failed. - %s", u_errorName(success));
853 return;
854 }
855 success = U_ZERO_ERROR;
856 RuleBasedCollator *col2 = new RuleBasedCollator(ruleset2, success);
857 if (U_FAILURE(success)) {
858 errln("The RuleBasedCollator constructor failed when building with the 2nd rule set.");
859 return;
860 }
861 logln("The operator tests begin : ");
862 logln("testing operator==, operator!=, clone methods ...");
863 doAssert((*col1 != *col2), "The two different table collations compared equal");
864 *col1 = *col2;
865 doAssert((*col1 == *col2), "Collator objects not equal after assignment (operator=)");
866
867 success = U_ZERO_ERROR;
868 Collator *col3 = Collator::createInstance(Locale::getEnglish(), success);
869 if (U_FAILURE(success)) {
870 errln("Default collation creation failed.");
871 return;
872 }
873 doAssert((*col1 != *col3), "The two different table collations compared equal");
874 Collator* col4 = col1->clone();
875 Collator* col5 = col3->clone();
876 doAssert((*col1 == *col4), "Cloned collation objects not equal");
877 doAssert((*col3 != *col4), "Two different table collations compared equal");
878 doAssert((*col3 == *col5), "Cloned collation objects not equal");
879 doAssert((*col4 != *col5), "Two cloned collations compared equal");
880
881 const UnicodeString& defRules = ((RuleBasedCollator*)col3)->getRules();
882 RuleBasedCollator* col6 = new RuleBasedCollator(defRules, success);
883 if (U_FAILURE(success)) {
884 errln("Creating default collation with rules failed.");
885 return;
886 }
887 doAssert((((RuleBasedCollator*)col3)->getRules() == col6->getRules()), "Default collator getRules failed");
888
889 success = U_ZERO_ERROR;
890 RuleBasedCollator *col7 = new RuleBasedCollator(ruleset2, Collator::TERTIARY, success);
891 if (U_FAILURE(success)) {
892 errln("The RuleBasedCollator constructor failed when building with the 2nd rule set with tertiary strength.");
893 return;
894 }
895 success = U_ZERO_ERROR;
896 RuleBasedCollator *col8 = new RuleBasedCollator(ruleset2, UCOL_OFF, success);
897 if (U_FAILURE(success)) {
898 errln("The RuleBasedCollator constructor failed when building with the 2nd rule set with Normalizer::NO_OP.");
899 return;
900 }
901 success = U_ZERO_ERROR;
902 RuleBasedCollator *col9 = new RuleBasedCollator(ruleset2, Collator::PRIMARY, UCOL_ON, success);
903 if (U_FAILURE(success)) {
904 errln("The RuleBasedCollator constructor failed when building with the 2nd rule set with tertiary strength and Normalizer::NO_OP.");
905 return;
906 }
907 // doAssert((*col7 == *col8), "The two equal table collations compared different");
908 doAssert((*col7 != *col9), "The two different table collations compared equal");
909 doAssert((*col8 != *col9), "The two different table collations compared equal");
910
911 logln("operator tests ended.");
912 delete col1;
913 delete col2;
914 delete col3;
915 delete col4;
916 delete col5;
917 delete col6;
918 delete col7;
919 delete col8;
920 delete col9;
921 }
922
923 // test clone and copy
924 void
TestDuplicate()925 CollationAPITest::TestDuplicate(/* char* par */)
926 {
927 UErrorCode status = U_ZERO_ERROR;
928 Collator *col1 = Collator::createInstance(Locale::getEnglish(), status);
929 if (U_FAILURE(status)) {
930 logln("Default collator creation failed.");
931 return;
932 }
933 Collator *col2 = col1->clone();
934 doAssert((*col1 == *col2), "Cloned object is not equal to the orginal");
935 UnicodeString *ruleset = new UnicodeString("< a, A < b, B < c, C < d, D, e, E");
936 RuleBasedCollator *col3 = new RuleBasedCollator(*ruleset, status);
937 doAssert((*col1 != *col3), "Cloned object is equal to some dummy");
938 *col3 = *((RuleBasedCollator*)col1);
939 doAssert((*col1 == *col3), "Copied object is not equal to the orginal");
940
941 if (U_FAILURE(status)) {
942 logln("Collation tailoring failed.");
943 return;
944 }
945
946 UCollationResult res;
947 UnicodeString first((UChar)0x0061);
948 UnicodeString second((UChar)0x0062);
949 UnicodeString copiedEnglishRules(((RuleBasedCollator*)col1)->getRules());
950
951 delete col1;
952 delete ruleset;
953
954 // Try using the cloned collators after deleting the original data
955 res = col2->compare(first, second, status);
956 if(res != UCOL_LESS) {
957 errln("a should be less then b after tailoring");
958 }
959 if (((RuleBasedCollator*)col2)->getRules() != copiedEnglishRules) {
960 errln(UnicodeString("English rule difference. ")
961 + copiedEnglishRules + UnicodeString("\ngetRules=") + ((RuleBasedCollator*)col2)->getRules());
962 }
963 res = col3->compare(first, second, status);
964 if(res != UCOL_LESS) {
965 errln("a should be less then b after tailoring");
966 }
967 if (col3->getRules() != copiedEnglishRules) {
968 errln(UnicodeString("English rule difference. ")
969 + copiedEnglishRules + UnicodeString("\ngetRules=") + col3->getRules());
970 }
971
972 delete col2;
973 delete col3;
974 }
975
976 void
TestCompare()977 CollationAPITest::TestCompare(/* char* par */)
978 {
979 logln("The compare tests begin : ");
980 Collator *col = 0;
981 UErrorCode success = U_ZERO_ERROR;
982 col = Collator::createInstance(Locale::getEnglish(), success);
983 if (U_FAILURE(success)) {
984 errcheckln(success, "Default collation creation failed. - %s", u_errorName(success));
985 return;
986 }
987 UnicodeString test1("Abcda"), test2("abcda");
988 logln("Use tertiary comparison level testing ....");
989
990 doAssert((!col->equals(test1, test2) ), "Result should be \"Abcda\" != \"abcda\"");
991 doAssert((col->greater(test1, test2) ), "Result should be \"Abcda\" >>> \"abcda\"");
992 doAssert((col->greaterOrEqual(test1, test2) ), "Result should be \"Abcda\" >>> \"abcda\"");
993
994 col->setStrength(Collator::SECONDARY);
995 logln("Use secondary comparison level testing ....");
996
997 doAssert((col->equals(test1, test2) ), "Result should be \"Abcda\" == \"abcda\"");
998 doAssert((!col->greater(test1, test2) ), "Result should be \"Abcda\" == \"abcda\"");
999 doAssert((col->greaterOrEqual(test1, test2) ), "Result should be \"Abcda\" == \"abcda\"");
1000
1001 col->setStrength(Collator::PRIMARY);
1002 logln("Use primary comparison level testing ....");
1003
1004 doAssert((col->equals(test1, test2) ), "Result should be \"Abcda\" == \"abcda\"");
1005 doAssert((!col->greater(test1, test2) ), "Result should be \"Abcda\" == \"abcda\"");
1006 doAssert((col->greaterOrEqual(test1, test2) ), "Result should be \"Abcda\" == \"abcda\"");
1007
1008 // Test different APIs
1009 const UChar* t1 = test1.getBuffer();
1010 int32_t t1Len = test1.length();
1011 const UChar* t2 = test2.getBuffer();
1012 int32_t t2Len = test2.length();
1013
1014 doAssert((col->compare(test1, test2) == Collator::EQUAL), "Problem");
1015 doAssert((col->compare(test1, test2, success) == UCOL_EQUAL), "Problem");
1016 doAssert((col->compare(t1, t1Len, t2, t2Len) == Collator::EQUAL), "Problem");
1017 doAssert((col->compare(t1, t1Len, t2, t2Len, success) == UCOL_EQUAL), "Problem");
1018 doAssert((col->compare(test1, test2, t1Len) == Collator::EQUAL), "Problem");
1019 doAssert((col->compare(test1, test2, t1Len, success) == UCOL_EQUAL), "Problem");
1020
1021 col->setAttribute(UCOL_STRENGTH, UCOL_TERTIARY, success);
1022 doAssert((col->compare(test1, test2) == Collator::GREATER), "Problem");
1023 doAssert((col->compare(test1, test2, success) == UCOL_GREATER), "Problem");
1024 doAssert((col->compare(t1, t1Len, t2, t2Len) == Collator::GREATER), "Problem");
1025 doAssert((col->compare(t1, t1Len, t2, t2Len, success) == UCOL_GREATER), "Problem");
1026 doAssert((col->compare(test1, test2, t1Len) == Collator::GREATER), "Problem");
1027 doAssert((col->compare(test1, test2, t1Len, success) == UCOL_GREATER), "Problem");
1028
1029
1030
1031 logln("The compare tests end.");
1032 delete col;
1033 }
1034
1035 void
TestGetAll()1036 CollationAPITest::TestGetAll(/* char* par */)
1037 {
1038 int32_t count1, count2;
1039 UErrorCode status = U_ZERO_ERROR;
1040
1041 logln("Trying Collator::getAvailableLocales(int&)");
1042
1043 const Locale* list = Collator::getAvailableLocales(count1);
1044 for (int32_t i = 0; i < count1; ++i) {
1045 UnicodeString dispName;
1046 logln(UnicodeString("Locale name: ")
1047 + UnicodeString(list[i].getName())
1048 + UnicodeString(" , the display name is : ")
1049 + UnicodeString(list[i].getDisplayName(dispName)));
1050 }
1051
1052 if (count1 == 0 || list == NULL) {
1053 dataerrln("getAvailableLocales(int&) returned an empty list");
1054 }
1055
1056 logln("Trying Collator::getAvailableLocales()");
1057 StringEnumeration* localeEnum = Collator::getAvailableLocales();
1058 const UnicodeString* locStr;
1059 const char *locCStr;
1060 count2 = 0;
1061
1062 if (localeEnum == NULL) {
1063 dataerrln("getAvailableLocales() returned NULL");
1064 return;
1065 }
1066
1067 while ((locStr = localeEnum->snext(status)) != NULL)
1068 {
1069 logln(UnicodeString("Locale name is: ") + *locStr);
1070 count2++;
1071 }
1072 if (count1 != count2) {
1073 errln("getAvailableLocales(int&) returned %d and getAvailableLocales() returned %d", count1, count2);
1074 }
1075
1076 logln("Trying Collator::getAvailableLocales() clone");
1077 count1 = 0;
1078 StringEnumeration* localeEnum2 = localeEnum->clone();
1079 localeEnum2->reset(status);
1080 while ((locCStr = localeEnum2->next(NULL, status)) != NULL)
1081 {
1082 logln(UnicodeString("Locale name is: ") + UnicodeString(locCStr));
1083 count1++;
1084 }
1085 if (count1 != count2) {
1086 errln("getAvailableLocales(3rd time) returned %d and getAvailableLocales(2nd time) returned %d", count1, count2);
1087 }
1088 if (localeEnum->count(status) != count1) {
1089 errln("localeEnum->count() returned %d and getAvailableLocales() returned %d", localeEnum->count(status), count1);
1090 }
1091 delete localeEnum;
1092 delete localeEnum2;
1093 }
1094
TestSortKey()1095 void CollationAPITest::TestSortKey()
1096 {
1097 UErrorCode status = U_ZERO_ERROR;
1098 /*
1099 this is supposed to open default date format, but later on it treats
1100 it like it is "en_US"
1101 - very bad if you try to run the tests on machine where default
1102 locale is NOT "en_US"
1103 */
1104 Collator *col = Collator::createInstance(Locale::getEnglish(), status);
1105 if (U_FAILURE(status)) {
1106 errcheckln(status, "ERROR: Default collation creation failed.: %s\n", u_errorName(status));
1107 return;
1108 }
1109
1110 if (col->getStrength() != Collator::TERTIARY)
1111 {
1112 errln("ERROR: default collation did not have UCOL_DEFAULT_STRENGTH !\n");
1113 }
1114
1115 /* Need to use identical strength */
1116 col->setAttribute(UCOL_STRENGTH, UCOL_IDENTICAL, status);
1117
1118 UChar test1[6] = {0x41, 0x62, 0x63, 0x64, 0x61, 0},
1119 test2[6] = {0x61, 0x62, 0x63, 0x64, 0x61, 0},
1120 test3[6] = {0x61, 0x62, 0x63, 0x64, 0x61, 0};
1121
1122 uint8_t sortkey1[64];
1123 uint8_t sortkey2[64];
1124 uint8_t sortkey3[64];
1125
1126 logln("Use tertiary comparison level testing ....\n");
1127
1128 CollationKey key1;
1129 col->getCollationKey(test1, u_strlen(test1), key1, status);
1130
1131 CollationKey key2;
1132 col->getCollationKey(test2, u_strlen(test2), key2, status);
1133
1134 CollationKey key3;
1135 col->getCollationKey(test3, u_strlen(test3), key3, status);
1136
1137 doAssert(key1.compareTo(key2) == Collator::GREATER,
1138 "Result should be \"Abcda\" > \"abcda\"");
1139 doAssert(key2.compareTo(key1) == Collator::LESS,
1140 "Result should be \"abcda\" < \"Abcda\"");
1141 doAssert(key2.compareTo(key3) == Collator::EQUAL,
1142 "Result should be \"abcda\" == \"abcda\"");
1143
1144 // Clone the key2 sortkey for later.
1145 int32_t keylength = 0;
1146 const uint8_t *key2primary_alias = key2.getByteArray(keylength);
1147 LocalArray<uint8_t> key2primary(new uint8_t[keylength]);
1148 memcpy(key2primary.getAlias(), key2primary_alias, keylength);
1149
1150 col->getSortKey(test1, sortkey1, 64);
1151 col->getSortKey(test2, sortkey2, 64);
1152 col->getSortKey(test3, sortkey3, 64);
1153
1154 const uint8_t *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");
1163
1164 col->getSortKey(test1, 5, sortkey1, 64);
1165 col->getSortKey(test2, 5, sortkey2, 64);
1166 col->getSortKey(test3, 5, sortkey3, 64);
1167
1168 tempkey = key1.getByteArray(keylength);
1169 doAssert(memcmp(tempkey, sortkey1, keylength) == 0,
1170 "Test1 string should have the same collation key and sort key");
1171 tempkey = key2.getByteArray(keylength);
1172 doAssert(memcmp(tempkey, sortkey2, keylength) == 0,
1173 "Test2 string should have the same collation key and sort key");
1174 tempkey = key3.getByteArray(keylength);
1175 doAssert(memcmp(tempkey, sortkey3, keylength) == 0,
1176 "Test3 string should have the same collation key and sort key");
1177
1178 UnicodeString strtest1(test1);
1179 col->getSortKey(strtest1, sortkey1, 64);
1180 UnicodeString strtest2(test2);
1181 col->getSortKey(strtest2, sortkey2, 64);
1182 UnicodeString strtest3(test3);
1183 col->getSortKey(strtest3, sortkey3, 64);
1184
1185 tempkey = key1.getByteArray(keylength);
1186 doAssert(memcmp(tempkey, sortkey1, keylength) == 0,
1187 "Test1 string should have the same collation key and sort key");
1188 tempkey = key2.getByteArray(keylength);
1189 doAssert(memcmp(tempkey, sortkey2, keylength) == 0,
1190 "Test2 string should have the same collation key and sort key");
1191 tempkey = key3.getByteArray(keylength);
1192 doAssert(memcmp(tempkey, sortkey3, keylength) == 0,
1193 "Test3 string should have the same collation key and sort key");
1194
1195 logln("Use secondary comparision level testing ...\n");
1196 col->setStrength(Collator::SECONDARY);
1197
1198 col->getCollationKey(test1, u_strlen(test1), key1, status);
1199 col->getCollationKey(test2, u_strlen(test2), key2, status);
1200 col->getCollationKey(test3, u_strlen(test3), key3, status);
1201
1202 doAssert(key1.compareTo(key2) == Collator::EQUAL,
1203 "Result should be \"Abcda\" == \"abcda\"");
1204 doAssert(key2.compareTo(key3) == Collator::EQUAL,
1205 "Result should be \"abcda\" == \"abcda\"");
1206
1207 tempkey = key2.getByteArray(keylength);
1208 doAssert(memcmp(tempkey, key2primary.getAlias(), keylength - 1) == 0,
1209 "Binary format for 'abcda' sortkey different for secondary strength!");
1210
1211 col->getSortKey(test1, sortkey1, 64);
1212 col->getSortKey(test2, sortkey2, 64);
1213 col->getSortKey(test3, sortkey3, 64);
1214
1215 tempkey = key1.getByteArray(keylength);
1216 doAssert(memcmp(tempkey, sortkey1, keylength) == 0,
1217 "Test1 string should have the same collation key and sort key");
1218 tempkey = key2.getByteArray(keylength);
1219 doAssert(memcmp(tempkey, sortkey2, keylength) == 0,
1220 "Test2 string should have the same collation key and sort key");
1221 tempkey = key3.getByteArray(keylength);
1222 doAssert(memcmp(tempkey, sortkey3, keylength) == 0,
1223 "Test3 string should have the same collation key and sort key");
1224
1225 col->getSortKey(test1, 5, sortkey1, 64);
1226 col->getSortKey(test2, 5, sortkey2, 64);
1227 col->getSortKey(test3, 5, sortkey3, 64);
1228
1229 tempkey = key1.getByteArray(keylength);
1230 doAssert(memcmp(tempkey, sortkey1, keylength) == 0,
1231 "Test1 string should have the same collation key and sort key");
1232 tempkey = key2.getByteArray(keylength);
1233 doAssert(memcmp(tempkey, sortkey2, keylength) == 0,
1234 "Test2 string should have the same collation key and sort key");
1235 tempkey = key3.getByteArray(keylength);
1236 doAssert(memcmp(tempkey, sortkey3, keylength) == 0,
1237 "Test3 string should have the same collation key and sort key");
1238
1239 col->getSortKey(strtest1, sortkey1, 64);
1240 col->getSortKey(strtest2, sortkey2, 64);
1241 col->getSortKey(strtest3, sortkey3, 64);
1242
1243 tempkey = key1.getByteArray(keylength);
1244 doAssert(memcmp(tempkey, sortkey1, keylength) == 0,
1245 "Test1 string should have the same collation key and sort key");
1246 tempkey = key2.getByteArray(keylength);
1247 doAssert(memcmp(tempkey, sortkey2, keylength) == 0,
1248 "Test2 string should have the same collation key and sort key");
1249 tempkey = key3.getByteArray(keylength);
1250 doAssert(memcmp(tempkey, sortkey3, keylength) == 0,
1251 "Test3 string should have the same collation key and sort key");
1252
1253 logln("testing sortkey ends...");
1254 delete col;
1255 }
1256
TestSortKeyOverflow()1257 void CollationAPITest::TestSortKeyOverflow() {
1258 IcuTestErrorCode errorCode(*this, "TestSortKeyOverflow()");
1259 LocalPointer<Collator> col(Collator::createInstance(Locale::getEnglish(), errorCode));
1260 if (errorCode.logDataIfFailureAndReset("Collator::createInstance(English) failed")) {
1261 return;
1262 }
1263 col->setAttribute(UCOL_STRENGTH, UCOL_PRIMARY, errorCode);
1264 UChar i_and_phi[] = { 0x438, 0x3c6 }; // Cyrillic small i & Greek small phi.
1265 // The sort key should be 6 bytes:
1266 // 2 bytes for the Cyrillic i, 1 byte for the primary-compression terminator,
1267 // 2 bytes for the Greek phi, and 1 byte for the NUL terminator.
1268 uint8_t sortKey[12];
1269 int32_t length = col->getSortKey(i_and_phi, 2, sortKey, LENGTHOF(sortKey));
1270 uint8_t sortKey2[12];
1271 for (int32_t capacity = 0; capacity < length; ++capacity) {
1272 uprv_memset(sortKey2, 2, LENGTHOF(sortKey2));
1273 int32_t length2 = col->getSortKey(i_and_phi, 2, sortKey2, capacity);
1274 if (length2 != length || 0 != uprv_memcmp(sortKey, sortKey2, capacity)) {
1275 errln("getSortKey(i_and_phi, capacity=%d) failed to write proper prefix", capacity);
1276 } else if (sortKey2[capacity] != 2 || sortKey2[capacity + 1] != 2) {
1277 errln("getSortKey(i_and_phi, capacity=%d) wrote beyond capacity", capacity);
1278 }
1279 }
1280
1281 // Now try to break getCollationKey().
1282 // Internally, it always starts with a large stack buffer.
1283 // Since we cannot control the initial capacity, we throw an increasing number
1284 // of characters at it, with the problematic part at the end.
1285 const int32_t longCapacity = 2000;
1286 // Each 'a' in the prefix should result in one primary sort key byte.
1287 // For i_and_phi we expect 6 bytes, then the NUL terminator.
1288 const int32_t maxPrefixLength = longCapacity - 6 - 1;
1289 LocalArray<uint8_t> longSortKey(new uint8_t[longCapacity]);
1290 UnicodeString s(FALSE, i_and_phi, 2);
1291 for (int32_t prefixLength = 0; prefixLength < maxPrefixLength; ++prefixLength) {
1292 length = col->getSortKey(s, longSortKey.getAlias(), longCapacity);
1293 CollationKey collKey;
1294 col->getCollationKey(s, collKey, errorCode);
1295 int32_t collKeyLength;
1296 const uint8_t *collSortKey = collKey.getByteArray(collKeyLength);
1297 if (collKeyLength != length || 0 != uprv_memcmp(longSortKey.getAlias(), collSortKey, length)) {
1298 errln("getCollationKey(prefix[%d]+i_and_phi) failed to write proper sort key", prefixLength);
1299 }
1300
1301 // Insert an 'a' to match ++prefixLength.
1302 s.insert(prefixLength, (UChar)0x61);
1303 }
1304 }
1305
TestMaxExpansion()1306 void CollationAPITest::TestMaxExpansion()
1307 {
1308 UErrorCode status = U_ZERO_ERROR;
1309 UChar ch = 0;
1310 UChar32 unassigned = 0xEFFFD;
1311 uint32_t sorder = 0;
1312 uint32_t temporder = 0;
1313
1314 UnicodeString rule("&a < ab < c/aba < d < z < ch");
1315 RuleBasedCollator coll(rule, status);
1316 if(U_FAILURE(status)) {
1317 errcheckln(status, "Collator creation failed with error %s", u_errorName(status));
1318 return;
1319 }
1320 UnicodeString str(ch);
1321 CollationElementIterator *iter =
1322 coll.createCollationElementIterator(str);
1323
1324 while (ch < 0xFFFF && U_SUCCESS(status)) {
1325 int count = 1;
1326 uint32_t order;
1327 int32_t size = 0;
1328
1329 ch ++;
1330
1331 str.setCharAt(0, ch);
1332 iter->setText(str, status);
1333 order = iter->previous(status);
1334
1335 /* thai management */
1336 if (order == 0)
1337 order = iter->previous(status);
1338
1339 while (U_SUCCESS(status) && iter->previous(status) != UCOL_NULLORDER) {
1340 count ++;
1341 }
1342
1343 size = coll.getMaxExpansion(order);
1344 if (U_FAILURE(status) || size < count) {
1345 errln("Failure at codepoint U+%04X, maximum expansion count %d < %d",
1346 ch, size, count);
1347 }
1348 }
1349
1350 /* testing for exact max expansion */
1351 int32_t size;
1352 ch = 0;
1353 while (ch < 0x61) {
1354 uint32_t order;
1355 str.setCharAt(0, ch);
1356 iter->setText(str, status);
1357 order = iter->previous(status);
1358 size = coll.getMaxExpansion(order);
1359 if (U_FAILURE(status) || size != 1) {
1360 errln("Failure at codepoint U+%04X, maximum expansion count %d < %d",
1361 ch, size, 1);
1362 }
1363 ch ++;
1364 }
1365
1366 ch = 0x63;
1367 str.setTo(ch);
1368 iter->setText(str, status);
1369 temporder = iter->previous(status);
1370 size = coll.getMaxExpansion(temporder);
1371 if (U_FAILURE(status) || size != 3) {
1372 errln("Failure at codepoint U+%04X, CE %08x, maximum expansion count %d != %d",
1373 ch, temporder, size, 3);
1374 }
1375
1376 ch = 0x64;
1377 str.setTo(ch);
1378 iter->setText(str, status);
1379 temporder = iter->previous(status);
1380 size = coll.getMaxExpansion(temporder);
1381 if (U_FAILURE(status) || size != 1) {
1382 errln("Failure at codepoint U+%04X, CE %08x, maximum expansion count %d != %d",
1383 ch, temporder, size, 1);
1384 }
1385
1386 str.setTo(unassigned);
1387 iter->setText(str, status);
1388 sorder = iter->previous(status);
1389 size = coll.getMaxExpansion(sorder);
1390 if (U_FAILURE(status) || size != 2) {
1391 errln("Failure at supplementary codepoints, maximum expansion count %d < %d",
1392 size, 2);
1393 }
1394
1395 /* testing jamo */
1396 ch = 0x1165;
1397 str.setTo(ch);
1398 iter->setText(str, status);
1399 temporder = iter->previous(status);
1400 size = coll.getMaxExpansion(temporder);
1401 if (U_FAILURE(status) || size > 3) {
1402 errln("Failure at codepoint U+%04X, maximum expansion count %d > %d",
1403 ch, size, 3);
1404 }
1405
1406 delete iter;
1407
1408 /* testing special jamo &a<\u1160 */
1409 rule = CharsToUnicodeString("\\u0026\\u0071\\u003c\\u1165\\u002f\\u0071\\u0071\\u0071\\u0071");
1410
1411 RuleBasedCollator jamocoll(rule, status);
1412 iter = jamocoll.createCollationElementIterator(str);
1413 temporder = iter->previous(status);
1414 size = iter->getMaxExpansion(temporder);
1415 if (U_FAILURE(status) || size != 6) {
1416 errln("Failure at codepoint U+%04X, maximum expansion count %d > %d",
1417 ch, size, 5);
1418 }
1419
1420 delete iter;
1421 }
1422
TestDisplayName()1423 void CollationAPITest::TestDisplayName()
1424 {
1425 UErrorCode error = U_ZERO_ERROR;
1426 Collator *coll = Collator::createInstance("en_US", error);
1427 if (U_FAILURE(error)) {
1428 errcheckln(error, "Failure creating english collator - %s", u_errorName(error));
1429 return;
1430 }
1431 UnicodeString name;
1432 UnicodeString result;
1433 coll->getDisplayName(Locale::getCanadaFrench(), result);
1434 Locale::getCanadaFrench().getDisplayName(name);
1435 if (result.compare(name)) {
1436 errln("Failure getting the correct name for locale en_US");
1437 }
1438
1439 coll->getDisplayName(Locale::getSimplifiedChinese(), result);
1440 Locale::getSimplifiedChinese().getDisplayName(name);
1441 if (result.compare(name)) {
1442 errln("Failure getting the correct name for locale zh_SG");
1443 }
1444 delete coll;
1445 }
1446
TestAttribute()1447 void CollationAPITest::TestAttribute()
1448 {
1449 UErrorCode error = U_ZERO_ERROR;
1450 Collator *coll = Collator::createInstance(error);
1451
1452 if (U_FAILURE(error)) {
1453 errcheckln(error, "Creation of default collator failed - %s", u_errorName(error));
1454 return;
1455 }
1456
1457 coll->setAttribute(UCOL_FRENCH_COLLATION, UCOL_OFF, error);
1458 if (coll->getAttribute(UCOL_FRENCH_COLLATION, error) != UCOL_OFF ||
1459 U_FAILURE(error)) {
1460 errln("Setting and retrieving of the french collation failed");
1461 }
1462
1463 coll->setAttribute(UCOL_FRENCH_COLLATION, UCOL_ON, error);
1464 if (coll->getAttribute(UCOL_FRENCH_COLLATION, error) != UCOL_ON ||
1465 U_FAILURE(error)) {
1466 errln("Setting and retrieving of the french collation failed");
1467 }
1468
1469 coll->setAttribute(UCOL_ALTERNATE_HANDLING, UCOL_SHIFTED, error);
1470 if (coll->getAttribute(UCOL_ALTERNATE_HANDLING, error) != UCOL_SHIFTED ||
1471 U_FAILURE(error)) {
1472 errln("Setting and retrieving of the alternate handling failed");
1473 }
1474
1475 coll->setAttribute(UCOL_ALTERNATE_HANDLING, UCOL_NON_IGNORABLE, error);
1476 if (coll->getAttribute(UCOL_ALTERNATE_HANDLING, error) != UCOL_NON_IGNORABLE ||
1477 U_FAILURE(error)) {
1478 errln("Setting and retrieving of the alternate handling failed");
1479 }
1480
1481 coll->setAttribute(UCOL_CASE_FIRST, UCOL_LOWER_FIRST, error);
1482 if (coll->getAttribute(UCOL_CASE_FIRST, error) != UCOL_LOWER_FIRST ||
1483 U_FAILURE(error)) {
1484 errln("Setting and retrieving of the case first attribute failed");
1485 }
1486
1487 coll->setAttribute(UCOL_CASE_FIRST, UCOL_UPPER_FIRST, error);
1488 if (coll->getAttribute(UCOL_CASE_FIRST, error) != UCOL_UPPER_FIRST ||
1489 U_FAILURE(error)) {
1490 errln("Setting and retrieving of the case first attribute failed");
1491 }
1492
1493 coll->setAttribute(UCOL_CASE_LEVEL, UCOL_ON, error);
1494 if (coll->getAttribute(UCOL_CASE_LEVEL, error) != UCOL_ON ||
1495 U_FAILURE(error)) {
1496 errln("Setting and retrieving of the case level attribute failed");
1497 }
1498
1499 coll->setAttribute(UCOL_CASE_LEVEL, UCOL_OFF, error);
1500 if (coll->getAttribute(UCOL_CASE_LEVEL, error) != UCOL_OFF ||
1501 U_FAILURE(error)) {
1502 errln("Setting and retrieving of the case level attribute failed");
1503 }
1504
1505 coll->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_ON, error);
1506 if (coll->getAttribute(UCOL_NORMALIZATION_MODE, error) != UCOL_ON ||
1507 U_FAILURE(error)) {
1508 errln("Setting and retrieving of the normalization on/off attribute failed");
1509 }
1510
1511 coll->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_OFF, error);
1512 if (coll->getAttribute(UCOL_NORMALIZATION_MODE, error) != UCOL_OFF ||
1513 U_FAILURE(error)) {
1514 errln("Setting and retrieving of the normalization on/off attribute failed");
1515 }
1516
1517 coll->setAttribute(UCOL_STRENGTH, UCOL_PRIMARY, error);
1518 if (coll->getAttribute(UCOL_STRENGTH, error) != UCOL_PRIMARY ||
1519 U_FAILURE(error)) {
1520 errln("Setting and retrieving of the collation strength failed");
1521 }
1522
1523 coll->setAttribute(UCOL_STRENGTH, UCOL_SECONDARY, error);
1524 if (coll->getAttribute(UCOL_STRENGTH, error) != UCOL_SECONDARY ||
1525 U_FAILURE(error)) {
1526 errln("Setting and retrieving of the collation strength failed");
1527 }
1528
1529 coll->setAttribute(UCOL_STRENGTH, UCOL_TERTIARY, error);
1530 if (coll->getAttribute(UCOL_STRENGTH, error) != UCOL_TERTIARY ||
1531 U_FAILURE(error)) {
1532 errln("Setting and retrieving of the collation strength failed");
1533 }
1534
1535 coll->setAttribute(UCOL_STRENGTH, UCOL_QUATERNARY, error);
1536 if (coll->getAttribute(UCOL_STRENGTH, error) != UCOL_QUATERNARY ||
1537 U_FAILURE(error)) {
1538 errln("Setting and retrieving of the collation strength failed");
1539 }
1540
1541 coll->setAttribute(UCOL_STRENGTH, UCOL_IDENTICAL, error);
1542 if (coll->getAttribute(UCOL_STRENGTH, error) != UCOL_IDENTICAL ||
1543 U_FAILURE(error)) {
1544 errln("Setting and retrieving of the collation strength failed");
1545 }
1546
1547 delete coll;
1548 }
1549
TestVariableTopSetting()1550 void CollationAPITest::TestVariableTopSetting() {
1551 UErrorCode status = U_ZERO_ERROR;
1552
1553 UChar vt[256] = { 0 };
1554
1555 Collator *coll = Collator::createInstance(status);
1556 if(U_FAILURE(status)) {
1557 delete coll;
1558 errcheckln(status, "Collator creation failed with error %s", u_errorName(status));
1559 return;
1560 }
1561
1562 uint32_t oldVarTop = coll->getVariableTop(status);
1563
1564 vt[0] = 0x0041;
1565
1566 uint32_t newVarTop = coll->setVariableTop(vt, 1, status);
1567
1568 if((newVarTop & 0xFFFF0000) != (coll->getVariableTop(status) & 0xFFFF0000)) {
1569 errln("Didn't set vartop properly\n");
1570 }
1571
1572 coll->setVariableTop(oldVarTop, status);
1573
1574 uint32_t newerVarTop = coll->setVariableTop(UnicodeString(vt, 1), status);
1575
1576 if((newVarTop & 0xFFFF0000) != (newerVarTop & 0xFFFF0000)) {
1577 errln("Didn't set vartop properly from UnicodeString!\n");
1578 }
1579
1580 delete coll;
1581
1582 }
1583
TestGetLocale()1584 void CollationAPITest::TestGetLocale() {
1585 UErrorCode status = U_ZERO_ERROR;
1586 const char *rules = "&a<x<y<z";
1587 UChar rlz[256] = {0};
1588
1589 Collator *coll = NULL;
1590 Locale locale;
1591
1592 int32_t i = 0;
1593
1594 static const struct {
1595 const char* requestedLocale;
1596 const char* validLocale;
1597 const char* actualLocale;
1598 } testStruct[] = {
1599 { "sr_YU", "sr_YU", "root" },
1600 { "sh_YU", "sh_YU", "sh" },
1601 { "en_US_CALIFORNIA", "en_US", "root" },
1602 { "fr_FR_NONEXISTANT", "fr_FR", "fr" }
1603 };
1604
1605 u_unescape(rules, rlz, 256);
1606
1607 /* test opening collators for different locales */
1608 for(i = 0; i<(int32_t)(sizeof(testStruct)/sizeof(testStruct[0])); i++) {
1609 status = U_ZERO_ERROR;
1610 coll = Collator::createInstance(testStruct[i].requestedLocale, status);
1611 if(U_FAILURE(status)) {
1612 log("Failed to open collator for %s with %s\n", testStruct[i].requestedLocale, u_errorName(status));
1613 delete coll;
1614 continue;
1615 }
1616 locale = coll->getLocale(ULOC_REQUESTED_LOCALE, status);
1617 if(locale != testStruct[i].requestedLocale) {
1618 log("[Coll %s]: Error in requested locale, expected %s, got %s\n", testStruct[i].requestedLocale, testStruct[i].requestedLocale, locale.getName());
1619 }
1620 locale = coll->getLocale(ULOC_VALID_LOCALE, status);
1621 if(locale != testStruct[i].validLocale) {
1622 log("[Coll %s]: Error in valid locale, expected %s, got %s\n", testStruct[i].requestedLocale, testStruct[i].validLocale, locale.getName());
1623 }
1624 locale = coll->getLocale(ULOC_ACTUAL_LOCALE, status);
1625 if(locale != testStruct[i].actualLocale) {
1626 log("[Coll %s]: Error in actual locale, expected %s, got %s\n", testStruct[i].requestedLocale, testStruct[i].actualLocale, locale.getName());
1627 }
1628 delete coll;
1629 }
1630
1631 /* completely non-existant locale for collator should get a default collator */
1632 {
1633 Collator *defaultColl = Collator::createInstance((const Locale)NULL, status);
1634 coll = Collator::createInstance("blahaha", status);
1635 if(U_FAILURE(status)) {
1636 log("Failed to open collator with %s\n", u_errorName(status));
1637 delete coll;
1638 delete defaultColl;
1639 return;
1640 }
1641 if(coll->getLocale(ULOC_REQUESTED_LOCALE, status) != "blahaha") {
1642 log("Nonexisting locale didn't preserve the requested locale\n");
1643 }
1644 if(coll->getLocale(ULOC_VALID_LOCALE, status) !=
1645 defaultColl->getLocale(ULOC_VALID_LOCALE, status)) {
1646 log("Valid locale for nonexisting locale locale collator differs "
1647 "from valid locale for default collator\n");
1648 }
1649 if(coll->getLocale(ULOC_ACTUAL_LOCALE, status) !=
1650 defaultColl->getLocale(ULOC_ACTUAL_LOCALE, status)) {
1651 log("Actual locale for nonexisting locale locale collator differs "
1652 "from actual locale for default collator\n");
1653 }
1654 delete coll;
1655 delete defaultColl;
1656 }
1657
1658
1659
1660 /* collator instantiated from rules should have all three locales NULL */
1661 coll = new RuleBasedCollator(rlz, status);
1662 locale = coll->getLocale(ULOC_REQUESTED_LOCALE, status);
1663 if(!locale.isBogus()) {
1664 log("For collator instantiated from rules, requested locale %s is not bogus\n", locale.getName());
1665 }
1666 locale = coll->getLocale(ULOC_VALID_LOCALE, status);
1667 if(!locale.isBogus()) {
1668 log("For collator instantiated from rules, valid locale %s is not bogus\n", locale.getName());
1669 }
1670 locale = coll->getLocale(ULOC_ACTUAL_LOCALE, status);
1671 if(!locale.isBogus()) {
1672 log("For collator instantiated from rules, actual locale %s is not bogus\n", locale.getName());
1673 }
1674 delete coll;
1675 }
1676
1677 struct teststruct {
1678 const char *original;
1679 uint8_t key[256];
1680 };
1681
1682
1683
1684 U_CDECL_BEGIN
1685 static int U_CALLCONV
compare_teststruct(const void * string1,const void * string2)1686 compare_teststruct(const void *string1, const void *string2) {
1687 return(strcmp((const char *)((struct teststruct *)string1)->key, (const char *)((struct teststruct *)string2)->key));
1688 }
1689 U_CDECL_END
1690
1691
TestBounds(void)1692 void CollationAPITest::TestBounds(void) {
1693 UErrorCode status = U_ZERO_ERROR;
1694
1695 Collator *coll = Collator::createInstance(Locale("sh"), status);
1696 if(U_FAILURE(status)) {
1697 delete coll;
1698 errcheckln(status, "Collator creation failed with %s", u_errorName(status));
1699 return;
1700 }
1701
1702 uint8_t sortkey[512], lower[512], upper[512];
1703 UChar buffer[512];
1704
1705 static const char * const test[] = {
1706 "John Smith",
1707 "JOHN SMITH",
1708 "john SMITH",
1709 "j\\u00F6hn sm\\u00EFth",
1710 "J\\u00F6hn Sm\\u00EFth",
1711 "J\\u00D6HN SM\\u00CFTH",
1712 "john smithsonian",
1713 "John Smithsonian"
1714 };
1715
1716 struct teststruct tests[] = {
1717 {"\\u010CAKI MIHALJ", {0}},
1718 {"\\u010CAKI MIHALJ", {0}},
1719 {"\\u010CAKI PIRO\\u0160KA", {0}},
1720 {"\\u010CABAI ANDRIJA", {0}},
1721 {"\\u010CABAI LAJO\\u0160", {0}},
1722 {"\\u010CABAI MARIJA", {0}},
1723 {"\\u010CABAI STEVAN", {0}},
1724 {"\\u010CABAI STEVAN", {0}},
1725 {"\\u010CABARKAPA BRANKO", {0}},
1726 {"\\u010CABARKAPA MILENKO", {0}},
1727 {"\\u010CABARKAPA MIROSLAV", {0}},
1728 {"\\u010CABARKAPA SIMO", {0}},
1729 {"\\u010CABARKAPA STANKO", {0}},
1730 {"\\u010CABARKAPA TAMARA", {0}},
1731 {"\\u010CABARKAPA TOMA\\u0160", {0}},
1732 {"\\u010CABDARI\\u0106 NIKOLA", {0}},
1733 {"\\u010CABDARI\\u0106 ZORICA", {0}},
1734 {"\\u010CABI NANDOR", {0}},
1735 {"\\u010CABOVI\\u0106 MILAN", {0}},
1736 {"\\u010CABRADI AGNEZIJA", {0}},
1737 {"\\u010CABRADI IVAN", {0}},
1738 {"\\u010CABRADI JELENA", {0}},
1739 {"\\u010CABRADI LJUBICA", {0}},
1740 {"\\u010CABRADI STEVAN", {0}},
1741 {"\\u010CABRDA MARTIN", {0}},
1742 {"\\u010CABRILO BOGDAN", {0}},
1743 {"\\u010CABRILO BRANISLAV", {0}},
1744 {"\\u010CABRILO LAZAR", {0}},
1745 {"\\u010CABRILO LJUBICA", {0}},
1746 {"\\u010CABRILO SPASOJA", {0}},
1747 {"\\u010CADE\\u0160 ZDENKA", {0}},
1748 {"\\u010CADESKI BLAGOJE", {0}},
1749 {"\\u010CADOVSKI VLADIMIR", {0}},
1750 {"\\u010CAGLJEVI\\u0106 TOMA", {0}},
1751 {"\\u010CAGOROVI\\u0106 VLADIMIR", {0}},
1752 {"\\u010CAJA VANKA", {0}},
1753 {"\\u010CAJI\\u0106 BOGOLJUB", {0}},
1754 {"\\u010CAJI\\u0106 BORISLAV", {0}},
1755 {"\\u010CAJI\\u0106 RADOSLAV", {0}},
1756 {"\\u010CAK\\u0160IRAN MILADIN", {0}},
1757 {"\\u010CAKAN EUGEN", {0}},
1758 {"\\u010CAKAN EVGENIJE", {0}},
1759 {"\\u010CAKAN IVAN", {0}},
1760 {"\\u010CAKAN JULIJAN", {0}},
1761 {"\\u010CAKAN MIHAJLO", {0}},
1762 {"\\u010CAKAN STEVAN", {0}},
1763 {"\\u010CAKAN VLADIMIR", {0}},
1764 {"\\u010CAKAN VLADIMIR", {0}},
1765 {"\\u010CAKAN VLADIMIR", {0}},
1766 {"\\u010CAKARA ANA", {0}},
1767 {"\\u010CAKAREVI\\u0106 MOMIR", {0}},
1768 {"\\u010CAKAREVI\\u0106 NEDELJKO", {0}},
1769 {"\\u010CAKI \\u0160ANDOR", {0}},
1770 {"\\u010CAKI AMALIJA", {0}},
1771 {"\\u010CAKI ANDRA\\u0160", {0}},
1772 {"\\u010CAKI LADISLAV", {0}},
1773 {"\\u010CAKI LAJO\\u0160", {0}},
1774 {"\\u010CAKI LASLO", {0}}
1775 };
1776
1777
1778
1779 int32_t i = 0, j = 0, k = 0, buffSize = 0, skSize = 0, lowerSize = 0, upperSize = 0;
1780 int32_t arraySize = sizeof(tests)/sizeof(tests[0]);
1781
1782 for(i = 0; i<arraySize; i++) {
1783 buffSize = u_unescape(tests[i].original, buffer, 512);
1784 skSize = coll->getSortKey(buffer, buffSize, tests[i].key, 512);
1785 }
1786
1787 qsort(tests, arraySize, sizeof(struct teststruct), compare_teststruct);
1788
1789 for(i = 0; i < arraySize-1; i++) {
1790 for(j = i+1; j < arraySize; j++) {
1791 lowerSize = coll->getBound(tests[i].key, -1, UCOL_BOUND_LOWER, 1, lower, 512, status);
1792 upperSize = coll->getBound(tests[j].key, -1, UCOL_BOUND_UPPER, 1, upper, 512, status);
1793 for(k = i; k <= j; k++) {
1794 if(strcmp((const char *)lower, (const char *)tests[k].key) > 0) {
1795 errln("Problem with lower! j = %i (%s vs %s)", k, tests[k].original, tests[i].original);
1796 }
1797 if(strcmp((const char *)upper, (const char *)tests[k].key) <= 0) {
1798 errln("Problem with upper! j = %i (%s vs %s)", k, tests[k].original, tests[j].original);
1799 }
1800 }
1801 }
1802 }
1803
1804
1805 for(i = 0; i<(int32_t)(sizeof(test)/sizeof(test[0])); i++) {
1806 buffSize = u_unescape(test[i], buffer, 512);
1807 skSize = coll->getSortKey(buffer, buffSize, sortkey, 512);
1808 lowerSize = ucol_getBound(sortkey, skSize, UCOL_BOUND_LOWER, 1, lower, 512, &status);
1809 upperSize = ucol_getBound(sortkey, skSize, UCOL_BOUND_UPPER_LONG, 1, upper, 512, &status);
1810 for(j = i+1; j<(int32_t)(sizeof(test)/sizeof(test[0])); j++) {
1811 buffSize = u_unescape(test[j], buffer, 512);
1812 skSize = coll->getSortKey(buffer, buffSize, sortkey, 512);
1813 if(strcmp((const char *)lower, (const char *)sortkey) > 0) {
1814 errln("Problem with lower! i = %i, j = %i (%s vs %s)", i, j, test[i], test[j]);
1815 }
1816 if(strcmp((const char *)upper, (const char *)sortkey) <= 0) {
1817 errln("Problem with upper! i = %i, j = %i (%s vs %s)", i, j, test[i], test[j]);
1818 }
1819 }
1820 }
1821 delete coll;
1822 }
1823
1824
TestGetTailoredSet()1825 void CollationAPITest::TestGetTailoredSet()
1826 {
1827 struct {
1828 const char *rules;
1829 const char *tests[20];
1830 int32_t testsize;
1831 } setTest[] = {
1832 { "&a < \\u212b", { "\\u212b", "A\\u030a", "\\u00c5" }, 3},
1833 { "& S < \\u0161 <<< \\u0160", { "\\u0161", "s\\u030C", "\\u0160", "S\\u030C" }, 4}
1834 };
1835
1836 uint32_t i = 0, j = 0;
1837 UErrorCode status = U_ZERO_ERROR;
1838
1839 RuleBasedCollator *coll = NULL;
1840 UnicodeString buff;
1841 UnicodeSet *set = NULL;
1842
1843 for(i = 0; i < sizeof(setTest)/sizeof(setTest[0]); i++) {
1844 buff = UnicodeString(setTest[i].rules, "").unescape();
1845 coll = new RuleBasedCollator(buff, status);
1846 if(U_SUCCESS(status)) {
1847 set = coll->getTailoredSet(status);
1848 if(set->size() != setTest[i].testsize) {
1849 errln("Tailored set size different (%d) than expected (%d)", set->size(), setTest[i].testsize);
1850 }
1851 for(j = 0; j < (uint32_t)setTest[i].testsize; j++) {
1852 buff = UnicodeString(setTest[i].tests[j], "").unescape();
1853 if(!set->contains(buff)) {
1854 errln("Tailored set doesn't contain %s... It should", setTest[i].tests[j]);
1855 }
1856 }
1857 delete set;
1858 } else {
1859 errcheckln(status, "Couldn't open collator with rules %s - %s", setTest[i].rules, u_errorName(status));
1860 }
1861 delete coll;
1862 }
1863 }
1864
TestUClassID()1865 void CollationAPITest::TestUClassID()
1866 {
1867 char id = *((char *)RuleBasedCollator::getStaticClassID());
1868 if (id != 0) {
1869 errln("Static class id for RuleBasedCollator should be 0");
1870 }
1871 UErrorCode status = U_ZERO_ERROR;
1872 RuleBasedCollator *coll
1873 = (RuleBasedCollator *)Collator::createInstance(status);
1874 if(U_FAILURE(status)) {
1875 delete coll;
1876 errcheckln(status, "Collator creation failed with %s", u_errorName(status));
1877 return;
1878 }
1879 id = *((char *)coll->getDynamicClassID());
1880 if (id != 0) {
1881 errln("Dynamic class id for RuleBasedCollator should be 0");
1882 }
1883 id = *((char *)CollationKey::getStaticClassID());
1884 if (id != 0) {
1885 errln("Static class id for CollationKey should be 0");
1886 }
1887 CollationKey *key = new CollationKey();
1888 id = *((char *)key->getDynamicClassID());
1889 if (id != 0) {
1890 errln("Dynamic class id for CollationKey should be 0");
1891 }
1892 id = *((char *)CollationElementIterator::getStaticClassID());
1893 if (id != 0) {
1894 errln("Static class id for CollationElementIterator should be 0");
1895 }
1896 UnicodeString str("testing");
1897 CollationElementIterator *iter = coll->createCollationElementIterator(str);
1898 id = *((char *)iter->getDynamicClassID());
1899 if (id != 0) {
1900 errln("Dynamic class id for CollationElementIterator should be 0");
1901 }
1902 delete key;
1903 delete iter;
1904 delete coll;
1905 }
1906
1907 class TestCollator : public Collator
1908 {
1909 public:
1910 virtual Collator* clone(void) const;
1911
1912 using Collator::compare;
1913
1914 virtual UCollationResult compare(const UnicodeString& source,
1915 const UnicodeString& target,
1916 UErrorCode& status) const;
1917 virtual UCollationResult compare(const UnicodeString& source,
1918 const UnicodeString& target,
1919 int32_t length,
1920 UErrorCode& status) const;
1921 virtual UCollationResult compare(const UChar* source,
1922 int32_t sourceLength,
1923 const UChar* target,
1924 int32_t targetLength,
1925 UErrorCode& status) const;
1926 virtual CollationKey& getCollationKey(const UnicodeString& source,
1927 CollationKey& key,
1928 UErrorCode& status) const;
1929 virtual CollationKey& getCollationKey(const UChar*source,
1930 int32_t sourceLength,
1931 CollationKey& key,
1932 UErrorCode& status) const;
1933 virtual int32_t hashCode(void) const;
1934 virtual Locale getLocale(ULocDataLocaleType type, UErrorCode& status) const;
1935 virtual ECollationStrength getStrength(void) const;
1936 virtual void setStrength(ECollationStrength newStrength);
1937 virtual UClassID getDynamicClassID(void) const;
1938 virtual void getVersion(UVersionInfo info) const;
1939 virtual void setAttribute(UColAttribute attr, UColAttributeValue value,
1940 UErrorCode &status);
1941 virtual UColAttributeValue getAttribute(UColAttribute attr,
1942 UErrorCode &status) const;
1943 virtual uint32_t setVariableTop(const UChar *varTop, int32_t len,
1944 UErrorCode &status);
1945 virtual uint32_t setVariableTop(const UnicodeString &varTop,
1946 UErrorCode &status);
1947 virtual void setVariableTop(uint32_t varTop, UErrorCode &status);
1948 virtual uint32_t getVariableTop(UErrorCode &status) const;
1949 virtual int32_t getSortKey(const UnicodeString& source,
1950 uint8_t* result,
1951 int32_t resultLength) const;
1952 virtual int32_t getSortKey(const UChar*source, int32_t sourceLength,
1953 uint8_t*result, int32_t resultLength) const;
1954 virtual UnicodeSet *getTailoredSet(UErrorCode &status) const;
1955 virtual UBool operator==(const Collator& other) const;
1956 // Collator::operator!= calls !Collator::operator== which works for all subclasses.
1957 virtual void setLocales(const Locale& requestedLocale, const Locale& validLocale, const Locale& actualLocale);
TestCollator()1958 TestCollator() : Collator() {};
TestCollator(UCollationStrength collationStrength,UNormalizationMode decompositionMode)1959 TestCollator(UCollationStrength collationStrength,
1960 UNormalizationMode decompositionMode) : Collator(collationStrength, decompositionMode) {};
1961 };
1962
operator ==(const Collator & other) const1963 inline UBool TestCollator::operator==(const Collator& other) const {
1964 // TestCollator has no fields, so we test for identity.
1965 return this == &other;
1966
1967 // Normally, subclasses should do something like the following:
1968 // if (this == &other) { return TRUE; }
1969 // if (!Collator::operator==(other)) { return FALSE; } // not the same class
1970 //
1971 // const TestCollator &o = (const TestCollator&)other;
1972 // (compare this vs. o's subclass fields)
1973 }
1974
clone() const1975 Collator* TestCollator::clone() const
1976 {
1977 return new TestCollator();
1978 }
1979
compare(const UnicodeString & source,const UnicodeString & target,UErrorCode & status) const1980 UCollationResult TestCollator::compare(const UnicodeString& source,
1981 const UnicodeString& target,
1982 UErrorCode& status) const
1983 {
1984 if(U_SUCCESS(status)) {
1985 return UCollationResult(source.compare(target));
1986 } else {
1987 return UCOL_EQUAL;
1988 }
1989 }
1990
compare(const UnicodeString & source,const UnicodeString & target,int32_t length,UErrorCode & status) const1991 UCollationResult TestCollator::compare(const UnicodeString& source,
1992 const UnicodeString& target,
1993 int32_t length,
1994 UErrorCode& status) const
1995 {
1996 if(U_SUCCESS(status)) {
1997 return UCollationResult(source.compare(0, length, target));
1998 } else {
1999 return UCOL_EQUAL;
2000 }
2001 }
2002
compare(const UChar * source,int32_t sourceLength,const UChar * target,int32_t targetLength,UErrorCode & status) const2003 UCollationResult TestCollator::compare(const UChar* source,
2004 int32_t sourceLength,
2005 const UChar* target,
2006 int32_t targetLength,
2007 UErrorCode& status) const
2008 {
2009 UnicodeString s(source, sourceLength);
2010 UnicodeString t(target, targetLength);
2011 return compare(s, t, status);
2012 }
2013
getCollationKey(const UnicodeString & source,CollationKey & key,UErrorCode & status) const2014 CollationKey& TestCollator::getCollationKey(const UnicodeString& source,
2015 CollationKey& key,
2016 UErrorCode& status) const
2017 {
2018 char temp[100];
2019 int length = 100;
2020 length = source.extract(temp, length, NULL, status);
2021 temp[length] = 0;
2022 CollationKey tempkey((uint8_t*)temp, length);
2023 key = tempkey;
2024 return key;
2025 }
2026
getCollationKey(const UChar * source,int32_t sourceLength,CollationKey & key,UErrorCode & status) const2027 CollationKey& TestCollator::getCollationKey(const UChar*source,
2028 int32_t sourceLength,
2029 CollationKey& key,
2030 UErrorCode& status) const
2031 {
2032 //s tack allocation used since collationkey does not keep the unicodestring
2033 UnicodeString str(source, sourceLength);
2034 return getCollationKey(str, key, status);
2035 }
2036
getSortKey(const UnicodeString & source,uint8_t * result,int32_t resultLength) const2037 int32_t TestCollator::getSortKey(const UnicodeString& source, uint8_t* result,
2038 int32_t resultLength) const
2039 {
2040 UErrorCode status = U_ZERO_ERROR;
2041 int32_t length = source.extract((char *)result, resultLength, NULL,
2042 status);
2043 result[length] = 0;
2044 return length;
2045 }
2046
getSortKey(const UChar * source,int32_t sourceLength,uint8_t * result,int32_t resultLength) const2047 int32_t TestCollator::getSortKey(const UChar*source, int32_t sourceLength,
2048 uint8_t*result, int32_t resultLength) const
2049 {
2050 UnicodeString str(source, sourceLength);
2051 return getSortKey(str, result, resultLength);
2052 }
2053
hashCode() const2054 int32_t TestCollator::hashCode() const
2055 {
2056 return 0;
2057 }
2058
getLocale(ULocDataLocaleType type,UErrorCode & status) const2059 Locale TestCollator::getLocale(ULocDataLocaleType type, UErrorCode& status) const
2060 {
2061 // api not used, this is to make the compiler happy
2062 if (U_FAILURE(status)) {
2063 type = ULOC_DATA_LOCALE_TYPE_LIMIT;
2064 }
2065 return NULL;
2066 }
2067
getStrength() const2068 Collator::ECollationStrength TestCollator::getStrength() const
2069 {
2070 return TERTIARY;
2071 }
2072
setStrength(Collator::ECollationStrength newStrength)2073 void TestCollator::setStrength(Collator::ECollationStrength newStrength)
2074 {
2075 // api not used, this is to make the compiler happy
2076 newStrength = TERTIARY;
2077 }
2078
getDynamicClassID(void) const2079 UClassID TestCollator::getDynamicClassID(void) const
2080 {
2081 return 0;
2082 }
2083
getVersion(UVersionInfo info) const2084 void TestCollator::getVersion(UVersionInfo info) const
2085 {
2086 // api not used, this is to make the compiler happy
2087 memset(info, 0, U_MAX_VERSION_LENGTH);
2088 }
2089
setAttribute(UColAttribute attr,UColAttributeValue value,UErrorCode & status)2090 void TestCollator::setAttribute(UColAttribute attr, UColAttributeValue value,
2091 UErrorCode &status)
2092 {
2093 // api not used, this is to make the compiler happy
2094 if (U_FAILURE(status)) {
2095 attr = UCOL_ATTRIBUTE_COUNT;
2096 value = UCOL_OFF;
2097 }
2098 }
2099
getAttribute(UColAttribute attr,UErrorCode & status) const2100 UColAttributeValue TestCollator::getAttribute(UColAttribute attr,
2101 UErrorCode &status) const
2102 {
2103 // api not used, this is to make the compiler happy
2104 if (U_FAILURE(status) || attr == UCOL_ATTRIBUTE_COUNT) {
2105 return UCOL_OFF;
2106 }
2107 return UCOL_DEFAULT;
2108 }
2109
setVariableTop(const UChar * varTop,int32_t len,UErrorCode & status)2110 uint32_t TestCollator::setVariableTop(const UChar *varTop, int32_t len,
2111 UErrorCode &status)
2112 {
2113 // api not used, this is to make the compiler happy
2114 if (U_SUCCESS(status) && (varTop == 0 || len < -1)) {
2115 status = U_ILLEGAL_ARGUMENT_ERROR;
2116 }
2117 return 0;
2118 }
2119
setVariableTop(const UnicodeString & varTop,UErrorCode & status)2120 uint32_t TestCollator::setVariableTop(const UnicodeString &varTop,
2121 UErrorCode &status)
2122 {
2123 // api not used, this is to make the compiler happy
2124 if (U_SUCCESS(status) && varTop.length() == 0) {
2125 status = U_ILLEGAL_ARGUMENT_ERROR;
2126 }
2127 return 0;
2128 }
2129
setVariableTop(uint32_t varTop,UErrorCode & status)2130 void TestCollator::setVariableTop(uint32_t varTop, UErrorCode &status)
2131 {
2132 // api not used, this is to make the compiler happy
2133 if (U_SUCCESS(status) && varTop == 0) {
2134 status = U_ILLEGAL_ARGUMENT_ERROR;
2135 }
2136 }
2137
getVariableTop(UErrorCode & status) const2138 uint32_t TestCollator::getVariableTop(UErrorCode &status) const
2139 {
2140
2141 // api not used, this is to make the compiler happy
2142 if (U_SUCCESS(status)) {
2143 return 0;
2144 }
2145 return (uint32_t)(0xFFFFFFFFu);
2146 }
2147
getTailoredSet(UErrorCode & status) const2148 UnicodeSet * TestCollator::getTailoredSet(UErrorCode &status) const
2149 {
2150 return Collator::getTailoredSet(status);
2151 }
2152
setLocales(const Locale & requestedLocale,const Locale & validLocale,const Locale & actualLocale)2153 void TestCollator::setLocales(const Locale& requestedLocale, const Locale& validLocale, const Locale& actualLocale)
2154 {
2155 Collator::setLocales(requestedLocale, validLocale, actualLocale);
2156 }
2157
2158
TestSubclass()2159 void CollationAPITest::TestSubclass()
2160 {
2161 TestCollator col1;
2162 TestCollator col2;
2163 doAssert(col1 != col2, "2 instances of TestCollator should be different");
2164 if (col1.hashCode() != col2.hashCode()) {
2165 errln("Every TestCollator has the same hashcode");
2166 }
2167 UnicodeString abc("abc", 3);
2168 UnicodeString bcd("bcd", 3);
2169 if (col1.compare(abc, bcd) != abc.compare(bcd)) {
2170 errln("TestCollator compare should be the same as the default "
2171 "string comparison");
2172 }
2173 CollationKey key;
2174 UErrorCode status = U_ZERO_ERROR;
2175 col1.getCollationKey(abc, key, status);
2176 int32_t length = 0;
2177 const char* bytes = (const char *)key.getByteArray(length);
2178 UnicodeString keyarray(bytes, length, NULL, status);
2179 if (abc != keyarray) {
2180 errln("TestCollator collationkey API is returning wrong values");
2181 }
2182
2183 UnicodeSet expectedset(0, 0x10FFFF);
2184 UnicodeSet *defaultset = col1.getTailoredSet(status);
2185 if (!defaultset->containsAll(expectedset)
2186 || !expectedset.containsAll(*defaultset)) {
2187 errln("Error: expected default tailoring to be 0 to 0x10ffff");
2188 }
2189 delete defaultset;
2190
2191 // use base class implementation
2192 Locale loc1 = Locale::getGermany();
2193 Locale loc2 = Locale::getFrance();
2194 col1.setLocales(loc1, loc2, loc2); // default implementation has no effect
2195
2196 UnicodeString displayName;
2197 col1.getDisplayName(loc1, loc2, displayName); // de_DE collator in fr_FR locale
2198
2199 TestCollator col3(UCOL_TERTIARY, UNORM_NONE);
2200 UnicodeString a("a");
2201 UnicodeString b("b");
2202 Collator::EComparisonResult result = Collator::EComparisonResult(a.compare(b));
2203 if(col1.compare(a, b) != result) {
2204 errln("Collator doesn't give default result");
2205 }
2206 if(col1.compare(a, b, 1) != result) {
2207 errln("Collator doesn't give default result");
2208 }
2209 if(col1.compare(a.getBuffer(), a.length(), b.getBuffer(), b.length()) != result) {
2210 errln("Collator doesn't give default result");
2211 }
2212 }
2213
TestNULLCharTailoring()2214 void CollationAPITest::TestNULLCharTailoring()
2215 {
2216 UErrorCode status = U_ZERO_ERROR;
2217 UChar buf[256] = {0};
2218 int32_t len = u_unescape("&a < '\\u0000'", buf, 256);
2219 UnicodeString first((UChar)0x0061);
2220 UnicodeString second((UChar)0);
2221 RuleBasedCollator *coll = new RuleBasedCollator(UnicodeString(buf, len), status);
2222 if(U_FAILURE(status)) {
2223 delete coll;
2224 errcheckln(status, "Failed to open collator - %s", u_errorName(status));
2225 return;
2226 }
2227 UCollationResult res = coll->compare(first, second, status);
2228 if(res != UCOL_LESS) {
2229 errln("a should be less then NULL after tailoring");
2230 }
2231 delete coll;
2232 }
2233
TestClone()2234 void CollationAPITest::TestClone() {
2235 logln("\ninit c0");
2236 UErrorCode status = U_ZERO_ERROR;
2237 RuleBasedCollator* c0 = (RuleBasedCollator*)Collator::createInstance(status);
2238
2239 if (U_FAILURE(status)) {
2240 errcheckln(status, "Collator::CreateInstance(status) failed with %s", u_errorName(status));
2241 return;
2242 }
2243
2244 c0->setStrength(Collator::TERTIARY);
2245 dump("c0", c0, status);
2246
2247 logln("\ninit c1");
2248 RuleBasedCollator* c1 = (RuleBasedCollator*)Collator::createInstance(status);
2249 c1->setStrength(Collator::TERTIARY);
2250 UColAttributeValue val = c1->getAttribute(UCOL_CASE_FIRST, status);
2251 if(val == UCOL_LOWER_FIRST){
2252 c1->setAttribute(UCOL_CASE_FIRST, UCOL_UPPER_FIRST, status);
2253 }else{
2254 c1->setAttribute(UCOL_CASE_FIRST, UCOL_LOWER_FIRST, status);
2255 }
2256 dump("c0", c0, status);
2257 dump("c1", c1, status);
2258
2259 logln("\ninit c2");
2260 RuleBasedCollator* c2 = (RuleBasedCollator*)c1->clone();
2261 val = c2->getAttribute(UCOL_CASE_FIRST, status);
2262 if(val == UCOL_LOWER_FIRST){
2263 c2->setAttribute(UCOL_CASE_FIRST, UCOL_UPPER_FIRST, status);
2264 }else{
2265 c2->setAttribute(UCOL_CASE_FIRST, UCOL_LOWER_FIRST, status);
2266 }
2267 if(U_FAILURE(status)){
2268 errln("set and get attributes of collator failed. %s\n", u_errorName(status));
2269 return;
2270 }
2271 dump("c0", c0, status);
2272 dump("c1", c1, status);
2273 dump("c2", c2, status);
2274 if(*c1 == *c2){
2275 errln("The cloned objects refer to same data");
2276 }
2277 delete c0;
2278 delete c1;
2279 delete c2;
2280 }
2281
dump(UnicodeString msg,RuleBasedCollator * c,UErrorCode & status)2282 void CollationAPITest::dump(UnicodeString msg, RuleBasedCollator* c, UErrorCode& status) {
2283 const char* bigone = "One";
2284 const char* littleone = "one";
2285
2286 logln(msg + " " + c->compare(bigone, littleone) +
2287 " s: " + c->getStrength() +
2288 " u: " + c->getAttribute(UCOL_CASE_FIRST, status));
2289 }
runIndexedTest(int32_t index,UBool exec,const char * & name,char *)2290 void CollationAPITest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par */)
2291 {
2292 if (exec) logln("TestSuite CollationAPITest: ");
2293 TESTCASE_AUTO_BEGIN;
2294 TESTCASE_AUTO(TestProperty);
2295 TESTCASE_AUTO(TestOperators);
2296 TESTCASE_AUTO(TestDuplicate);
2297 TESTCASE_AUTO(TestCompare);
2298 // BEGIN android-changed
2299 // To save space, Android does not include the collation tailoring rules.
2300 // We skip the tailing tests for collations.
2301 // TESTCASE_AUTO(TestHashCode);
2302 // END android-changed
2303 TESTCASE_AUTO(TestCollationKey);
2304 TESTCASE_AUTO(TestElemIter);
2305 TESTCASE_AUTO(TestGetAll);
2306 TESTCASE_AUTO(TestRuleBasedColl);
2307 TESTCASE_AUTO(TestDecomposition);
2308 TESTCASE_AUTO(TestSafeClone);
2309 TESTCASE_AUTO(TestSortKey);
2310 TESTCASE_AUTO(TestSortKeyOverflow);
2311 TESTCASE_AUTO(TestMaxExpansion);
2312 TESTCASE_AUTO(TestDisplayName);
2313 TESTCASE_AUTO(TestAttribute);
2314 TESTCASE_AUTO(TestVariableTopSetting);
2315 // BEGIN android-changed
2316 // To save space, Android does not include the collation tailoring rules.
2317 // We skip the tailing tests for collations.
2318 // TESTCASE_AUTO(TestRules);
2319 // END android-changed
2320 TESTCASE_AUTO(TestGetLocale);
2321 TESTCASE_AUTO(TestBounds);
2322 TESTCASE_AUTO(TestGetTailoredSet);
2323 TESTCASE_AUTO(TestUClassID);
2324 TESTCASE_AUTO(TestSubclass);
2325 TESTCASE_AUTO(TestNULLCharTailoring);
2326 TESTCASE_AUTO(TestClone);
2327 TESTCASE_AUTO_END;
2328 }
2329
2330 #endif /* #if !UCONFIG_NO_COLLATION */
2331