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