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