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