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