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