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