Home | History | Annotate | Download | only in intltest
      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 
     48 void
     49 CollationAPITest::doAssert(UBool condition, const char *message)
     50 {
     51     if (!condition) {
     52         errln(UnicodeString("ERROR : ") + message);
     53     }
     54 }
     55 
     56 #ifdef U_USE_COLLATION_OBSOLETE_2_6
     57 /*
     58  * Test Collator::createInstance(... version...) for some locale. Called by TestProperty().
     59  */
     60 static void
     61 TestOpenVersion(IntlTest &test, const Locale &locale) {
     62     UVersionInfo version1, version2;
     63     Collator *collator1, *collator2;
     64     UErrorCode errorCode;
     65 
     66     errorCode=U_ZERO_ERROR;
     67     collator1=Collator::createInstance(locale, errorCode);
     68     if(U_SUCCESS(errorCode)) {
     69         /* get the current version */
     70         collator1->getVersion(version1);
     71         delete collator1;
     72 
     73         /* try to get that same version again */
     74         collator2=Collator::createInstance(locale, version1, errorCode);
     75         if(U_SUCCESS(errorCode)) {
     76             collator2->getVersion(version2);
     77             if(0!=uprv_memcmp(version1, version2, sizeof(UVersionInfo))) {
     78                 test.errln("error: Collator::createInstance(\"%s\", (%s collator)->getVersion()) returns a different collator\n", locale.getName(), locale.getName());
     79             }
     80             delete collator2;
     81         } else {
     82             test.errln("error: Collator::createInstance(\"%s\", (%s collator)->getVersion()) fails: %s\n", locale.getName(), locale.getName(), u_errorName(errorCode));
     83         }
     84     }
     85 }
     86 #endif
     87 
     88 // Collator Class Properties
     89 // ctor, dtor, createInstance, compare, getStrength/setStrength
     90 // getDecomposition/setDecomposition, getDisplayName
     91 void
     92 CollationAPITest::TestProperty(/* char* par */)
     93 {
     94     UErrorCode success = U_ZERO_ERROR;
     95     Collator *col = 0;
     96     /*
     97       All the collations have the same version in an ICU
     98       version.
     99       ICU 2.0 currVersionArray = {0x18, 0xC0, 0x02, 0x02};
    100       ICU 2.1 currVersionArray = {0x19, 0x00, 0x03, 0x03};
    101       ICU 2.2 currVersionArray = {0x21, 0x40, 0x04, 0x04};
    102       ICU 2.4 currVersionArray = {0x21, 0x40, 0x04, 0x04};
    103       ICU 2.6 currVersionArray = {0x21, 0x40, 0x03, 0x03};
    104       ICU 2.8 currVersionArray = {0x29, 0x80, 0x00, 0x04};
    105       ICU 3.4 currVersionArray = {0x31, 0xC0, 0x00, 0x04};
    106     */
    107     UVersionInfo currVersionArray = {0x31, 0xC0, 0x00, 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 
    278 void
    279 CollationAPITest::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 
    361 void
    362 CollationAPITest::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 
    389 void
    390 CollationAPITest::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 
    422 void
    423 CollationAPITest::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 
    466 void
    467 CollationAPITest::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 //
    525 void
    526 CollationAPITest::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 //
    648 void
    649 CollationAPITest::TestElemIter(/* char* par */)
    650 {
    651     logln("testing sortkey begins...");
    652     Collator *col = 0;
    653     UErrorCode success = U_ZERO_ERROR;
    654     col = Collator::createInstance(Locale::getEnglish(), success);
    655     if (U_FAILURE(success))
    656     {
    657         errcheckln(success, "Default collation creation failed. - %s", u_errorName(success));
    658         return;
    659     }
    660 
    661     UnicodeString testString1("XFILE What subset of all possible test cases has the highest probability of detecting the most errors?");
    662     UnicodeString testString2("Xf_ile What subset of all possible test cases has the lowest probability of detecting the least errors?");
    663     logln("Constructors and comparison testing....");
    664     CollationElementIterator *iterator1 = ((RuleBasedCollator*)col)->createCollationElementIterator(testString1);
    665 
    666     CharacterIterator *chariter=new StringCharacterIterator(testString1);
    667     CollationElementIterator *coliter=((RuleBasedCollator*)col)->createCollationElementIterator(*chariter);
    668 
    669     // copy ctor
    670     CollationElementIterator *iterator2 = ((RuleBasedCollator*)col)->createCollationElementIterator(testString1);
    671     CollationElementIterator *iterator3 = ((RuleBasedCollator*)col)->createCollationElementIterator(testString2);
    672 
    673     int32_t offset = iterator1->getOffset();
    674     if (offset != 0) {
    675         errln("Error in getOffset for collation element iterator\n");
    676         return;
    677     }
    678     iterator1->setOffset(6, success);
    679     if (U_FAILURE(success)) {
    680         errln("Error in setOffset for collation element iterator\n");
    681         return;
    682     }
    683     iterator1->setOffset(0, success);
    684     int32_t order1, order2, order3;
    685     doAssert((*iterator1 == *iterator2), "The two iterators should be the same");
    686     doAssert((*iterator1 != *iterator3), "The two iterators should be different");
    687 
    688     doAssert((*coliter == *iterator1), "The two iterators should be the same");
    689     doAssert((*coliter == *iterator2), "The two iterators should be the same");
    690     doAssert((*coliter != *iterator3), "The two iterators should be different");
    691 
    692     order1 = iterator1->next(success);
    693     if (U_FAILURE(success))
    694     {
    695         errln("Somehow ran out of memory stepping through the iterator.");
    696         return;
    697     }
    698 
    699     doAssert((*iterator1 != *iterator2), "The first iterator advance failed");
    700     order2 = iterator2->getOffset();
    701     doAssert((order1 != order2), "The order result should not be the same");
    702     order2 = iterator2->next(success);
    703     if (U_FAILURE(success))
    704     {
    705         errln("Somehow ran out of memory stepping through the iterator.");
    706         return;
    707     }
    708 
    709     doAssert((*iterator1 == *iterator2), "The second iterator advance failed");
    710     doAssert((order1 == order2), "The order result should be the same");
    711     order3 = iterator3->next(success);
    712     if (U_FAILURE(success))
    713     {
    714         errln("Somehow ran out of memory stepping through the iterator.");
    715         return;
    716     }
    717 
    718     doAssert((CollationElementIterator::primaryOrder(order1) ==
    719         CollationElementIterator::primaryOrder(order3)), "The primary orders should be the same");
    720     doAssert((CollationElementIterator::secondaryOrder(order1) ==
    721         CollationElementIterator::secondaryOrder(order3)), "The secondary orders should be the same");
    722     doAssert((CollationElementIterator::tertiaryOrder(order1) ==
    723         CollationElementIterator::tertiaryOrder(order3)), "The tertiary orders should be the same");
    724 
    725     order1 = iterator1->next(success); order3 = iterator3->next(success);
    726     if (U_FAILURE(success))
    727     {
    728         errln("Somehow ran out of memory stepping through the iterator.");
    729         return;
    730     }
    731 
    732     doAssert((CollationElementIterator::primaryOrder(order1) ==
    733         CollationElementIterator::primaryOrder(order3)), "The primary orders should be identical");
    734     doAssert((CollationElementIterator::tertiaryOrder(order1) !=
    735         CollationElementIterator::tertiaryOrder(order3)), "The tertiary orders should be different");
    736 
    737     order1 = iterator1->next(success);
    738     order3 = iterator3->next(success);
    739     /* NO! Secondary orders of two CEs are not related, especially in the case of '_' vs 'I' */
    740     /*
    741     doAssert((CollationElementIterator::secondaryOrder(order1) !=
    742         CollationElementIterator::secondaryOrder(order3)), "The secondary orders should not be the same");
    743     */
    744     doAssert((order1 != CollationElementIterator::NULLORDER), "Unexpected end of iterator reached");
    745 
    746     iterator1->reset(); iterator2->reset(); iterator3->reset();
    747     order1 = iterator1->next(success);
    748     if (U_FAILURE(success))
    749     {
    750         errln("Somehow ran out of memory stepping through the iterator.");
    751         return;
    752     }
    753 
    754     doAssert((*iterator1 != *iterator2), "The first iterator advance failed");
    755 
    756     order2 = iterator2->next(success);
    757     if (U_FAILURE(success))
    758     {
    759         errln("Somehow ran out of memory stepping through the iterator.");
    760         return;
    761     }
    762 
    763     doAssert((*iterator1 == *iterator2), "The second iterator advance failed");
    764     doAssert((order1 == order2), "The order result should be the same");
    765 
    766     order3 = iterator3->next(success);
    767     if (U_FAILURE(success))
    768     {
    769         errln("Somehow ran out of memory stepping through the iterator.");
    770         return;
    771     }
    772 
    773     doAssert((CollationElementIterator::primaryOrder(order1) ==
    774         CollationElementIterator::primaryOrder(order3)), "The primary orders should be the same");
    775     doAssert((CollationElementIterator::secondaryOrder(order1) ==
    776         CollationElementIterator::secondaryOrder(order3)), "The secondary orders should be the same");
    777     doAssert((CollationElementIterator::tertiaryOrder(order1) ==
    778         CollationElementIterator::tertiaryOrder(order3)), "The tertiary orders should be the same");
    779 
    780     order1 = iterator1->next(success); order2 = iterator2->next(success); order3 = iterator3->next(success);
    781     if (U_FAILURE(success))
    782     {
    783         errln("Somehow ran out of memory stepping through the iterator.");
    784         return;
    785     }
    786 
    787     doAssert((CollationElementIterator::primaryOrder(order1) ==
    788         CollationElementIterator::primaryOrder(order3)), "The primary orders should be identical");
    789     doAssert((CollationElementIterator::tertiaryOrder(order1) !=
    790         CollationElementIterator::tertiaryOrder(order3)), "The tertiary orders should be different");
    791 
    792     order1 = iterator1->next(success); order3 = iterator3->next(success);
    793     if (U_FAILURE(success))
    794     {
    795         errln("Somehow ran out of memory stepping through the iterator.");
    796         return;
    797     }
    798 
    799     /* NO! Secondary orders of two CEs are not related, especially in the case of '_' vs 'I' */
    800     /*
    801     doAssert((CollationElementIterator::secondaryOrder(order1) !=
    802         CollationElementIterator::secondaryOrder(order3)), "The secondary orders should not be the same");
    803     */
    804     doAssert((order1 != CollationElementIterator::NULLORDER), "Unexpected end of iterator reached");
    805     doAssert((*iterator2 != *iterator3), "The iterators should be different");
    806 
    807 
    808     //test error values
    809     success=U_UNSUPPORTED_ERROR;
    810     Collator *colerror=NULL;
    811     colerror=Collator::createInstance(Locale::getEnglish(), success);
    812     if (colerror != 0 || success == U_ZERO_ERROR){
    813         errln("Error: createInstance(UErrorCode != U_ZERO_ERROR) should just return and not create an instance\n");
    814     }
    815     int32_t position=coliter->previous(success);
    816     if(position != CollationElementIterator::NULLORDER){
    817         errln((UnicodeString)"Expected NULLORDER got" + position);
    818     }
    819     coliter->reset();
    820     coliter->setText(*chariter, success);
    821     if(!U_FAILURE(success)){
    822         errln("Expeceted error");
    823     }
    824     iterator1->setText((UnicodeString)"hello there", success);
    825     if(!U_FAILURE(success)){
    826         errln("Expeceted error");
    827     }
    828 
    829     delete chariter;
    830     delete coliter;
    831     delete iterator1;
    832     delete iterator2;
    833     delete iterator3;
    834     delete col;
    835 
    836 
    837 
    838     logln("testing CollationElementIterator ends...");
    839 }
    840 
    841 // Test RuleBasedCollator ctor, dtor, operator==, operator!=, clone, copy, and getRules
    842 void
    843 CollationAPITest::TestOperators(/* char* par */)
    844 {
    845     UErrorCode success = U_ZERO_ERROR;
    846     UnicodeString ruleset1("< a, A < b, B < c, C; ch, cH, Ch, CH < d, D, e, E");
    847     UnicodeString ruleset2("< a, A < b, B < c, C < d, D, e, E");
    848     RuleBasedCollator *col1 = new RuleBasedCollator(ruleset1, success);
    849     if (U_FAILURE(success)) {
    850         errcheckln(success, "RuleBasedCollator creation failed. - %s", u_errorName(success));
    851         return;
    852     }
    853     success = U_ZERO_ERROR;
    854     RuleBasedCollator *col2 = new RuleBasedCollator(ruleset2, success);
    855     if (U_FAILURE(success)) {
    856         errln("The RuleBasedCollator constructor failed when building with the 2nd rule set.");
    857         return;
    858     }
    859     logln("The operator tests begin : ");
    860     logln("testing operator==, operator!=, clone  methods ...");
    861     doAssert((*col1 != *col2), "The two different table collations compared equal");
    862     *col1 = *col2;
    863     doAssert((*col1 == *col2), "Collator objects not equal after assignment (operator=)");
    864 
    865     success = U_ZERO_ERROR;
    866     Collator *col3 = Collator::createInstance(Locale::getEnglish(), success);
    867     if (U_FAILURE(success)) {
    868         errln("Default collation creation failed.");
    869         return;
    870     }
    871     doAssert((*col1 != *col3), "The two different table collations compared equal");
    872     Collator* col4 = col1->clone();
    873     Collator* col5 = col3->clone();
    874     doAssert((*col1 == *col4), "Cloned collation objects not equal");
    875     doAssert((*col3 != *col4), "Two different table collations compared equal");
    876     doAssert((*col3 == *col5), "Cloned collation objects not equal");
    877     doAssert((*col4 != *col5), "Two cloned collations compared equal");
    878 
    879     const UnicodeString& defRules = ((RuleBasedCollator*)col3)->getRules();
    880     RuleBasedCollator* col6 = new RuleBasedCollator(defRules, success);
    881     if (U_FAILURE(success)) {
    882         errln("Creating default collation with rules failed.");
    883         return;
    884     }
    885     doAssert((((RuleBasedCollator*)col3)->getRules() == col6->getRules()), "Default collator getRules failed");
    886 
    887     success = U_ZERO_ERROR;
    888     RuleBasedCollator *col7 = new RuleBasedCollator(ruleset2, Collator::TERTIARY, success);
    889     if (U_FAILURE(success)) {
    890         errln("The RuleBasedCollator constructor failed when building with the 2nd rule set with tertiary strength.");
    891         return;
    892     }
    893     success = U_ZERO_ERROR;
    894     RuleBasedCollator *col8 = new RuleBasedCollator(ruleset2, UCOL_OFF, success);
    895     if (U_FAILURE(success)) {
    896         errln("The RuleBasedCollator constructor failed when building with the 2nd rule set with Normalizer::NO_OP.");
    897         return;
    898     }
    899     success = U_ZERO_ERROR;
    900     RuleBasedCollator *col9 = new RuleBasedCollator(ruleset2, Collator::PRIMARY, UCOL_ON, success);
    901     if (U_FAILURE(success)) {
    902         errln("The RuleBasedCollator constructor failed when building with the 2nd rule set with tertiary strength and Normalizer::NO_OP.");
    903         return;
    904     }
    905   //  doAssert((*col7 == *col8), "The two equal table collations compared different");
    906     doAssert((*col7 != *col9), "The two different table collations compared equal");
    907     doAssert((*col8 != *col9), "The two different table collations compared equal");
    908 
    909     logln("operator tests ended.");
    910     delete col1;
    911     delete col2;
    912     delete col3;
    913     delete col4;
    914     delete col5;
    915     delete col6;
    916     delete col7;
    917     delete col8;
    918     delete col9;
    919 }
    920 
    921 // test clone and copy
    922 void
    923 CollationAPITest::TestDuplicate(/* char* par */)
    924 {
    925     UErrorCode status = U_ZERO_ERROR;
    926     Collator *col1 = Collator::createInstance(Locale::getEnglish(), status);
    927     if (U_FAILURE(status)) {
    928         logln("Default collator creation failed.");
    929         return;
    930     }
    931     Collator *col2 = col1->clone();
    932     doAssert((*col1 == *col2), "Cloned object is not equal to the orginal");
    933     UnicodeString *ruleset = new UnicodeString("< a, A < b, B < c, C < d, D, e, E");
    934     RuleBasedCollator *col3 = new RuleBasedCollator(*ruleset, status);
    935     doAssert((*col1 != *col3), "Cloned object is equal to some dummy");
    936     *col3 = *((RuleBasedCollator*)col1);
    937     doAssert((*col1 == *col3), "Copied object is not equal to the orginal");
    938 
    939     if (U_FAILURE(status)) {
    940         logln("Collation tailoring failed.");
    941         return;
    942     }
    943 
    944     UCollationResult res;
    945     UnicodeString first((UChar)0x0061);
    946     UnicodeString second((UChar)0x0062);
    947     UnicodeString copiedEnglishRules(((RuleBasedCollator*)col1)->getRules());
    948 
    949     delete col1;
    950     delete ruleset;
    951 
    952     // Try using the cloned collators after deleting the original data
    953     res = col2->compare(first, second, status);
    954     if(res != UCOL_LESS) {
    955         errln("a should be less then b after tailoring");
    956     }
    957     if (((RuleBasedCollator*)col2)->getRules() != copiedEnglishRules) {
    958         errln(UnicodeString("English rule difference. ")
    959             + copiedEnglishRules + UnicodeString("\ngetRules=") + ((RuleBasedCollator*)col2)->getRules());
    960     }
    961     res = col3->compare(first, second, status);
    962     if(res != UCOL_LESS) {
    963         errln("a should be less then b after tailoring");
    964     }
    965     if (col3->getRules() != copiedEnglishRules) {
    966         errln(UnicodeString("English rule difference. ")
    967             + copiedEnglishRules + UnicodeString("\ngetRules=") + col3->getRules());
    968     }
    969 
    970     delete col2;
    971     delete col3;
    972 }
    973 
    974 void
    975 CollationAPITest::TestCompare(/* char* par */)
    976 {
    977     logln("The compare tests begin : ");
    978     Collator *col = 0;
    979     UErrorCode success = U_ZERO_ERROR;
    980     col = Collator::createInstance(Locale::getEnglish(), success);
    981     if (U_FAILURE(success)) {
    982         errcheckln(success, "Default collation creation failed. - %s", u_errorName(success));
    983         return;
    984     }
    985     UnicodeString test1("Abcda"), test2("abcda");
    986     logln("Use tertiary comparison level testing ....");
    987 
    988     doAssert((!col->equals(test1, test2) ), "Result should be \"Abcda\" != \"abcda\"");
    989     doAssert((col->greater(test1, test2) ), "Result should be \"Abcda\" >>> \"abcda\"");
    990     doAssert((col->greaterOrEqual(test1, test2) ), "Result should be \"Abcda\" >>> \"abcda\"");
    991 
    992     col->setStrength(Collator::SECONDARY);
    993     logln("Use secondary comparison level testing ....");
    994 
    995     doAssert((col->equals(test1, test2) ), "Result should be \"Abcda\" == \"abcda\"");
    996     doAssert((!col->greater(test1, test2) ), "Result should be \"Abcda\" == \"abcda\"");
    997     doAssert((col->greaterOrEqual(test1, test2) ), "Result should be \"Abcda\" == \"abcda\"");
    998 
    999     col->setStrength(Collator::PRIMARY);
   1000     logln("Use primary comparison level testing ....");
   1001 
   1002     doAssert((col->equals(test1, test2) ), "Result should be \"Abcda\" == \"abcda\"");
   1003     doAssert((!col->greater(test1, test2) ), "Result should be \"Abcda\" == \"abcda\"");
   1004     doAssert((col->greaterOrEqual(test1, test2) ), "Result should be \"Abcda\" == \"abcda\"");
   1005 
   1006     // Test different APIs
   1007     const UChar* t1 = test1.getBuffer();
   1008     int32_t t1Len = test1.length();
   1009     const UChar* t2 = test2.getBuffer();
   1010     int32_t t2Len = test2.length();
   1011 
   1012     doAssert((col->compare(test1, test2) == Collator::EQUAL), "Problem");
   1013     doAssert((col->compare(test1, test2, success) == UCOL_EQUAL), "Problem");
   1014     doAssert((col->compare(t1, t1Len, t2, t2Len) == Collator::EQUAL), "Problem");
   1015     doAssert((col->compare(t1, t1Len, t2, t2Len, success) == UCOL_EQUAL), "Problem");
   1016     doAssert((col->compare(test1, test2, t1Len) == Collator::EQUAL), "Problem");
   1017     doAssert((col->compare(test1, test2, t1Len, success) == UCOL_EQUAL), "Problem");
   1018 
   1019     col->setAttribute(UCOL_STRENGTH, UCOL_TERTIARY, success);
   1020     doAssert((col->compare(test1, test2) == Collator::GREATER), "Problem");
   1021     doAssert((col->compare(test1, test2, success) == UCOL_GREATER), "Problem");
   1022     doAssert((col->compare(t1, t1Len, t2, t2Len) == Collator::GREATER), "Problem");
   1023     doAssert((col->compare(t1, t1Len, t2, t2Len, success) == UCOL_GREATER), "Problem");
   1024     doAssert((col->compare(test1, test2, t1Len) == Collator::GREATER), "Problem");
   1025     doAssert((col->compare(test1, test2, t1Len, success) == UCOL_GREATER), "Problem");
   1026 
   1027 
   1028 
   1029     logln("The compare tests end.");
   1030     delete col;
   1031 }
   1032 
   1033 void
   1034 CollationAPITest::TestGetAll(/* char* par */)
   1035 {
   1036     int32_t count1, count2;
   1037     UErrorCode status = U_ZERO_ERROR;
   1038 
   1039     logln("Trying Collator::getAvailableLocales(int&)");
   1040 
   1041     const Locale* list = Collator::getAvailableLocales(count1);
   1042     for (int32_t i = 0; i < count1; ++i) {
   1043         UnicodeString dispName;
   1044         logln(UnicodeString("Locale name: ")
   1045             + UnicodeString(list[i].getName())
   1046             + UnicodeString(" , the display name is : ")
   1047             + UnicodeString(list[i].getDisplayName(dispName)));
   1048     }
   1049 
   1050     if (count1 == 0 || list == NULL) {
   1051         dataerrln("getAvailableLocales(int&) returned an empty list");
   1052     }
   1053 
   1054     logln("Trying Collator::getAvailableLocales()");
   1055     StringEnumeration* localeEnum = Collator::getAvailableLocales();
   1056     const UnicodeString* locStr;
   1057     const char *locCStr;
   1058     count2 = 0;
   1059 
   1060     if (localeEnum == NULL) {
   1061         dataerrln("getAvailableLocales() returned NULL");
   1062         return;
   1063     }
   1064 
   1065     while ((locStr = localeEnum->snext(status)) != NULL)
   1066     {
   1067         logln(UnicodeString("Locale name is: ") + *locStr);
   1068         count2++;
   1069     }
   1070     if (count1 != count2) {
   1071         errln("getAvailableLocales(int&) returned %d and getAvailableLocales() returned %d", count1, count2);
   1072     }
   1073 
   1074     logln("Trying Collator::getAvailableLocales() clone");
   1075     count1 = 0;
   1076     StringEnumeration* localeEnum2 = localeEnum->clone();
   1077     localeEnum2->reset(status);
   1078     while ((locCStr = localeEnum2->next(NULL, status)) != NULL)
   1079     {
   1080         logln(UnicodeString("Locale name is: ") + UnicodeString(locCStr));
   1081         count1++;
   1082     }
   1083     if (count1 != count2) {
   1084         errln("getAvailableLocales(3rd time) returned %d and getAvailableLocales(2nd time) returned %d", count1, count2);
   1085     }
   1086     if (localeEnum->count(status) != count1) {
   1087         errln("localeEnum->count() returned %d and getAvailableLocales() returned %d", localeEnum->count(status), count1);
   1088     }
   1089     delete localeEnum;
   1090     delete localeEnum2;
   1091 }
   1092 
   1093 void CollationAPITest::TestSortKey()
   1094 {
   1095     UErrorCode status = U_ZERO_ERROR;
   1096     /*
   1097     this is supposed to open default date format, but later on it treats
   1098     it like it is "en_US"
   1099     - very bad if you try to run the tests on machine where default
   1100       locale is NOT "en_US"
   1101     */
   1102     Collator *col = Collator::createInstance(Locale::getEnglish(), status);
   1103     if (U_FAILURE(status)) {
   1104         errcheckln(status, "ERROR: Default collation creation failed.: %s\n", u_errorName(status));
   1105         return;
   1106     }
   1107 
   1108     if (col->getStrength() != Collator::TERTIARY)
   1109     {
   1110         errln("ERROR: default collation did not have UCOL_DEFAULT_STRENGTH !\n");
   1111     }
   1112 
   1113     /* Need to use identical strength */
   1114     col->setAttribute(UCOL_STRENGTH, UCOL_IDENTICAL, status);
   1115 
   1116     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 
   1301 void 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 
   1416 void 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 
   1440 void 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 
   1543 void 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 
   1577 void 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 
   1670 struct teststruct {
   1671     const char *original;
   1672     uint8_t key[256];
   1673 };
   1674 
   1675 
   1676 
   1677 U_CDECL_BEGIN
   1678 static int U_CALLCONV
   1679 compare_teststruct(const void *string1, const void *string2) {
   1680   return(strcmp((const char *)((struct teststruct *)string1)->key, (const char *)((struct teststruct *)string2)->key));
   1681 }
   1682 U_CDECL_END
   1683 
   1684 
   1685 void 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 
   1818 void 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 
   1858 void 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 
   1900 class TestCollator  : public Collator
   1901 {
   1902 public:
   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 
   1982 inline 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 
   1991 Collator* TestCollator::clone() const
   1992 {
   1993     return new TestCollator();
   1994 }
   1995 
   1996 UCollationResult 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 
   2007 UCollationResult 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 
   2019 UCollationResult 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 
   2030 CollationKey& 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 
   2043 CollationKey& 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 
   2053 int32_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 
   2063 int32_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 
   2070 int32_t TestCollator::hashCode() const
   2071 {
   2072     return 0;
   2073 }
   2074 
   2075 const 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 
   2085 Collator::ECollationStrength TestCollator::getStrength() const
   2086 {
   2087     return TERTIARY;
   2088 }
   2089 
   2090 void TestCollator::setStrength(Collator::ECollationStrength newStrength)
   2091 {
   2092     // api not used, this is to make the compiler happy
   2093     newStrength = TERTIARY;
   2094 }
   2095 
   2096 UClassID TestCollator::getDynamicClassID(void) const
   2097 {
   2098     return 0;
   2099 }
   2100 
   2101 void 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 
   2107 void 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 
   2117 UColAttributeValue 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 
   2127 uint32_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 
   2137 uint32_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 
   2147 void 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 
   2155 uint32_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 
   2165 Collator* TestCollator::safeClone(void)
   2166 {
   2167     return new TestCollator();
   2168 }
   2169 
   2170 UnicodeSet * TestCollator::getTailoredSet(UErrorCode &status) const
   2171 {
   2172     return Collator::getTailoredSet(status);
   2173 }
   2174 
   2175 void TestCollator::setLocales(const Locale& requestedLocale, const Locale& validLocale, const Locale& actualLocale)
   2176 {
   2177     Collator::setLocales(requestedLocale, validLocale, actualLocale);
   2178 }
   2179 
   2180 
   2181 void 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 
   2236 void 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 
   2256 void 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 }
   2312 void 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