]> git.saurik.com Git - apple/icu.git/blob - icuSources/test/intltest/regcoll.cpp
ICU-57165.0.1.tar.gz
[apple/icu.git] / icuSources / test / intltest / regcoll.cpp
1 /********************************************************************
2 * COPYRIGHT:
3 * Copyright (c) 1997-2016, International Business Machines Corporation and
4 * others. All Rights Reserved.
5 ********************************************************************/
6
7 #include "unicode/utypes.h"
8
9 #if !UCONFIG_NO_COLLATION
10
11 #include "unicode/coll.h"
12 #include "unicode/localpointer.h"
13 #include "unicode/tblcoll.h"
14 #include "unicode/unistr.h"
15 #include "unicode/sortkey.h"
16 #include "regcoll.h"
17 #include "sfwdchit.h"
18 #include "testutil.h"
19 #include "cmemory.h"
20
21 CollationRegressionTest::CollationRegressionTest()
22 {
23 UErrorCode status = U_ZERO_ERROR;
24
25 en_us = (RuleBasedCollator *)Collator::createInstance(Locale::getUS(), status);
26 if(U_FAILURE(status)) {
27 delete en_us;
28 en_us = 0;
29 errcheckln(status, "Collator creation failed with %s", u_errorName(status));
30 return;
31 }
32 }
33
34 CollationRegressionTest::~CollationRegressionTest()
35 {
36 delete en_us;
37 }
38
39
40 // @bug 4048446
41 //
42 // CollationElementIterator.reset() doesn't work
43 //
44 void CollationRegressionTest::Test4048446(/* char* par */)
45 {
46 const UnicodeString test1 = "XFILE What subset of all possible test cases has the highest probability of detecting the most errors?";
47 const UnicodeString test2 = "Xf_ile What subset of all possible test cases has the lowest probability of detecting the least errors?";
48 CollationElementIterator *i1 = en_us->createCollationElementIterator(test1);
49 CollationElementIterator *i2 = en_us->createCollationElementIterator(test1);
50 UErrorCode status = U_ZERO_ERROR;
51
52 if (i1 == NULL|| i2 == NULL)
53 {
54 errln("Could not create CollationElementIterator's");
55 delete i1;
56 delete i2;
57 return;
58 }
59
60 while (i1->next(status) != CollationElementIterator::NULLORDER)
61 {
62 if (U_FAILURE(status))
63 {
64 errln("error calling next()");
65
66 delete i1;
67 delete i2;
68 return;
69 }
70 }
71
72 i1->reset();
73
74 assertEqual(*i1, *i2);
75
76 delete i1;
77 delete i2;
78 }
79
80 // @bug 4051866
81 //
82 // Collator -> rules -> Collator round-trip broken for expanding characters
83 //
84 void CollationRegressionTest::Test4051866(/* char* par */)
85 {
86 UnicodeString rules;
87 UErrorCode status = U_ZERO_ERROR;
88
89 rules += "&n < o ";
90 rules += "& oe ,o";
91 rules += (UChar)0x3080;
92 rules += "& oe ,";
93 rules += (UChar)0x1530;
94 rules += " ,O";
95 rules += "& OE ,O";
96 rules += (UChar)0x3080;
97 rules += "& OE ,";
98 rules += (UChar)0x1520;
99 rules += "< p ,P";
100
101 // Build a collator containing expanding characters
102 LocalPointer<RuleBasedCollator> c1(new RuleBasedCollator(rules, status), status);
103 if (U_FAILURE(status)) {
104 errln("RuleBasedCollator(rule string) failed - %s", u_errorName(status));
105 return;
106 }
107
108 // Build another using the rules from the first
109 LocalPointer<RuleBasedCollator> c2(new RuleBasedCollator(c1->getRules(), status), status);
110 if (U_FAILURE(status)) {
111 errln("RuleBasedCollator(rule string from other RBC) failed - %s", u_errorName(status));
112 return;
113 }
114
115 // Make sure they're the same
116 if (!(c1->getRules() == c2->getRules()))
117 {
118 errln("Rules are not equal");
119 }
120 }
121
122 // @bug 4053636
123 //
124 // Collator thinks "black-bird" == "black"
125 //
126 void CollationRegressionTest::Test4053636(/* char* par */)
127 {
128 if (en_us->equals("black_bird", "black"))
129 {
130 errln("black-bird == black");
131 }
132 }
133
134 // @bug 4054238
135 //
136 // CollationElementIterator will not work correctly if the associated
137 // Collator object's mode is changed
138 //
139 void CollationRegressionTest::Test4054238(/* char* par */)
140 {
141 const UChar chars3[] = {0x61, 0x00FC, 0x62, 0x65, 0x63, 0x6b, 0x20, 0x47, 0x72, 0x00F6, 0x00DF, 0x65, 0x20, 0x4c, 0x00FC, 0x62, 0x63, 0x6b, 0};
142 const UnicodeString test3(chars3);
143 RuleBasedCollator *c = (RuleBasedCollator *) en_us->clone();
144
145 // NOTE: The Java code uses en_us to create the CollationElementIterators
146 // but I'm pretty sure that's wrong, so I've changed this to use c.
147 UErrorCode status = U_ZERO_ERROR;
148 c->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_ON, status);
149 CollationElementIterator *i1 = c->createCollationElementIterator(test3);
150 delete i1;
151 delete c;
152 }
153
154 // @bug 4054734
155 //
156 // Collator::IDENTICAL documented but not implemented
157 //
158 void CollationRegressionTest::Test4054734(/* char* par */)
159 {
160 /*
161 Here's the original Java:
162
163 String[] decomp = {
164 "\u0001", "<", "\u0002",
165 "\u0001", "=", "\u0001",
166 "A\u0001", ">", "~\u0002", // Ensure A and ~ are not compared bitwise
167 "\u00C0", "=", "A\u0300" // Decomp should make these equal
168 };
169
170 String[] nodecomp = {
171 "\u00C0", ">", "A\u0300" // A-grave vs. A combining-grave
172 };
173 */
174
175 static const UChar decomp[][CollationRegressionTest::MAX_TOKEN_LEN] =
176 {
177 {0x0001, 0}, {0x3c, 0}, {0x0002, 0},
178 {0x0001, 0}, {0x3d, 0}, {0x0001, 0},
179 {0x41, 0x0001, 0}, {0x3e, 0}, {0x7e, 0x0002, 0},
180 {0x00c0, 0}, {0x3d, 0}, {0x41, 0x0300, 0}
181 };
182
183
184 UErrorCode status = U_ZERO_ERROR;
185 RuleBasedCollator *c = (RuleBasedCollator *) en_us->clone();
186
187 c->setStrength(Collator::IDENTICAL);
188
189 c->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_ON, status);
190 compareArray(*c, decomp, UPRV_LENGTHOF(decomp));
191
192 delete c;
193 }
194
195 // @bug 4054736
196 //
197 // Full Decomposition mode not implemented
198 //
199 void CollationRegressionTest::Test4054736(/* char* par */)
200 {
201 UErrorCode status = U_ZERO_ERROR;
202 RuleBasedCollator *c = (RuleBasedCollator *) en_us->clone();
203
204 c->setStrength(Collator::SECONDARY);
205 c->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_ON, status);
206
207 static const UChar tests[][CollationRegressionTest::MAX_TOKEN_LEN] =
208 {
209 {0xFB4F, 0}, {0x3d, 0}, {0x05D0, 0x05DC} // Alef-Lamed vs. Alef, Lamed
210 };
211
212 compareArray(*c, tests, UPRV_LENGTHOF(tests));
213
214 delete c;
215 }
216
217 // @bug 4058613
218 //
219 // Collator::createInstance() causes an ArrayIndexOutofBoundsException for Korean
220 //
221 void CollationRegressionTest::Test4058613(/* char* par */)
222 {
223 // Creating a default collator doesn't work when Korean is the default
224 // locale
225
226 Locale oldDefault = Locale::getDefault();
227 UErrorCode status = U_ZERO_ERROR;
228
229 Locale::setDefault(Locale::getKorean(), status);
230
231 if (U_FAILURE(status))
232 {
233 errln("Could not set default locale to Locale::KOREAN");
234 return;
235 }
236
237 Collator *c = NULL;
238
239 c = Collator::createInstance("en_US", status);
240
241 if (c == NULL || U_FAILURE(status))
242 {
243 errln("Could not create a Korean collator");
244 Locale::setDefault(oldDefault, status);
245 delete c;
246 return;
247 }
248
249 // Since the fix to this bug was to turn off decomposition for Korean collators,
250 // ensure that's what we got
251 if (c->getAttribute(UCOL_NORMALIZATION_MODE, status) != UCOL_OFF)
252 {
253 errln("Decomposition is not set to NO_DECOMPOSITION for Korean collator");
254 }
255
256 delete c;
257
258 Locale::setDefault(oldDefault, status);
259 }
260
261 // @bug 4059820
262 //
263 // RuleBasedCollator.getRules does not return the exact pattern as input
264 // for expanding character sequences
265 //
266 void CollationRegressionTest::Test4059820(/* char* par */)
267 {
268 UErrorCode status = U_ZERO_ERROR;
269
270 RuleBasedCollator *c = NULL;
271 UnicodeString rules = "&9 < a < b , c/a < d < z";
272
273 c = new RuleBasedCollator(rules, status);
274
275 if (c == NULL || U_FAILURE(status))
276 {
277 errln("Failure building a collator.");
278 delete c;
279 return;
280 }
281
282 if ( c->getRules().indexOf("c/a") == -1)
283 {
284 errln("returned rules do not contain 'c/a'");
285 }
286
287 delete c;
288 }
289
290 // @bug 4060154
291 //
292 // MergeCollation::fixEntry broken for "& H < \u0131, \u0130, i, I"
293 //
294 void CollationRegressionTest::Test4060154(/* char* par */)
295 {
296 UErrorCode status = U_ZERO_ERROR;
297 UnicodeString rules;
298
299 rules += "&f < g, G < h, H < i, I < j, J";
300 rules += " & H < ";
301 rules += (UChar)0x0131;
302 rules += ", ";
303 rules += (UChar)0x0130;
304 rules += ", i, I";
305
306 RuleBasedCollator *c = NULL;
307
308 c = new RuleBasedCollator(rules, status);
309
310 if (c == NULL || U_FAILURE(status))
311 {
312 errln("failure building collator.");
313 delete c;
314 return;
315 }
316
317 c->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_ON, status);
318
319 /*
320 String[] tertiary = {
321 "A", "<", "B",
322 "H", "<", "\u0131",
323 "H", "<", "I",
324 "\u0131", "<", "\u0130",
325 "\u0130", "<", "i",
326 "\u0130", ">", "H",
327 };
328 */
329
330 static const UChar tertiary[][CollationRegressionTest::MAX_TOKEN_LEN] =
331 {
332 {0x41, 0}, {0x3c, 0}, {0x42, 0},
333 {0x48, 0}, {0x3c, 0}, {0x0131, 0},
334 {0x48, 0}, {0x3c, 0}, {0x49, 0},
335 {0x0131, 0}, {0x3c, 0}, {0x0130, 0},
336 {0x0130, 0}, {0x3c, 0}, {0x69, 0},
337 {0x0130, 0}, {0x3e, 0}, {0x48, 0}
338 };
339
340 c->setStrength(Collator::TERTIARY);
341 compareArray(*c, tertiary, UPRV_LENGTHOF(tertiary));
342
343 /*
344 String[] secondary = {
345 "H", "<", "I",
346 "\u0131", "=", "\u0130",
347 };
348 */
349 static const UChar secondary[][CollationRegressionTest::MAX_TOKEN_LEN] =
350 {
351 {0x48, 0}, {0x3c, 0}, {0x49, 0},
352 {0x0131, 0}, {0x3d, 0}, {0x0130, 0}
353 };
354
355 c->setStrength(Collator::PRIMARY);
356 compareArray(*c, secondary, UPRV_LENGTHOF(secondary));
357
358 delete c;
359 }
360
361 // @bug 4062418
362 //
363 // Secondary/Tertiary comparison incorrect in French Secondary
364 //
365 void CollationRegressionTest::Test4062418(/* char* par */)
366 {
367 UErrorCode status = U_ZERO_ERROR;
368
369 RuleBasedCollator *c = NULL;
370
371 c = (RuleBasedCollator *) Collator::createInstance(Locale::getCanadaFrench(), status);
372
373 if (c == NULL || U_FAILURE(status))
374 {
375 errln("Failed to create collator for Locale::getCanadaFrench()");
376 delete c;
377 return;
378 }
379
380 c->setStrength(Collator::SECONDARY);
381
382 /*
383 String[] tests = {
384 "p\u00eache", "<", "p\u00e9ch\u00e9", // Comparing accents from end, p\u00e9ch\u00e9 is greater
385 };
386 */
387 static const UChar tests[][CollationRegressionTest::MAX_TOKEN_LEN] =
388 {
389 {0x70, 0x00EA, 0x63, 0x68, 0x65, 0}, {0x3c, 0}, {0x70, 0x00E9, 0x63, 0x68, 0x00E9, 0}
390 };
391
392 compareArray(*c, tests, UPRV_LENGTHOF(tests));
393
394 delete c;
395 }
396
397 // @bug 4065540
398 //
399 // Collator::compare() method broken if either string contains spaces
400 //
401 void CollationRegressionTest::Test4065540(/* char* par */)
402 {
403 if (en_us->compare("abcd e", "abcd f") == 0)
404 {
405 errln("'abcd e' == 'abcd f'");
406 }
407 }
408
409 // @bug 4066189
410 //
411 // Unicode characters need to be recursively decomposed to get the
412 // correct result. For example,
413 // u1EB1 -> \u0103 + \u0300 -> a + \u0306 + \u0300.
414 //
415 void CollationRegressionTest::Test4066189(/* char* par */)
416 {
417 static const UChar chars1[] = {0x1EB1, 0};
418 static const UChar chars2[] = {0x61, 0x0306, 0x0300, 0};
419 const UnicodeString test1(chars1);
420 const UnicodeString test2(chars2);
421 UErrorCode status = U_ZERO_ERROR;
422
423 // NOTE: The java code used en_us to create the
424 // CollationElementIterator's. I'm pretty sure that
425 // was wrong, so I've change the code to use c1 and c2
426 RuleBasedCollator *c1 = (RuleBasedCollator *) en_us->clone();
427 c1->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_ON, status);
428 CollationElementIterator *i1 = c1->createCollationElementIterator(test1);
429
430 RuleBasedCollator *c2 = (RuleBasedCollator *) en_us->clone();
431 c2->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_OFF, status);
432 CollationElementIterator *i2 = c2->createCollationElementIterator(test2);
433
434 assertEqual(*i1, *i2);
435
436 delete i2;
437 delete c2;
438 delete i1;
439 delete c1;
440 }
441
442 // @bug 4066696
443 //
444 // French secondary collation checking at the end of compare iteration fails
445 //
446 void CollationRegressionTest::Test4066696(/* char* par */)
447 {
448 UErrorCode status = U_ZERO_ERROR;
449 RuleBasedCollator *c = NULL;
450
451 c = (RuleBasedCollator *)Collator::createInstance(Locale::getCanadaFrench(), status);
452
453 if (c == NULL || U_FAILURE(status))
454 {
455 errln("Failure creating collator for Locale::getCanadaFrench()");
456 delete c;
457 return;
458 }
459
460 c->setStrength(Collator::SECONDARY);
461
462 /*
463 String[] tests = {
464 "\u00e0", "<", "\u01fa", // a-grave < A-ring-acute
465 };
466
467 should be:
468
469 String[] tests = {
470 "\u00e0", ">", "\u01fa", // a-grave < A-ring-acute
471 };
472
473 */
474
475 static const UChar tests[][CollationRegressionTest::MAX_TOKEN_LEN] =
476 {
477 {0x00E0, 0}, {0x3e, 0}, {0x01FA, 0}
478 };
479
480 compareArray(*c, tests, UPRV_LENGTHOF(tests));
481
482 delete c;
483 }
484
485 // @bug 4076676
486 //
487 // Bad canonicalization of same-class combining characters
488 //
489 void CollationRegressionTest::Test4076676(/* char* par */)
490 {
491 // These combining characters are all in the same class, so they should not
492 // be reordered, and they should compare as unequal.
493 static const UChar s1[] = {0x41, 0x0301, 0x0302, 0x0300, 0};
494 static const UChar s2[] = {0x41, 0x0302, 0x0300, 0x0301, 0};
495
496 RuleBasedCollator *c = (RuleBasedCollator *) en_us->clone();
497 c->setStrength(Collator::TERTIARY);
498
499 if (c->compare(s1,s2) == 0)
500 {
501 errln("Same-class combining chars were reordered");
502 }
503
504 delete c;
505 }
506
507 // @bug 4079231
508 //
509 // RuleBasedCollator::operator==(NULL) throws NullPointerException
510 //
511 void CollationRegressionTest::Test4079231(/* char* par */)
512 {
513 // I don't think there's any way to write this test
514 // in C++. The following is equivalent to the Java,
515 // but doesn't compile 'cause NULL can't be converted
516 // to Collator&
517 //
518 // if (en_us->operator==(NULL))
519 // {
520 // errln("en_us->operator==(NULL) returned TRUE");
521 // }
522
523 /*
524 try {
525 if (en_us->equals(null)) {
526 errln("en_us->equals(null) returned true");
527 }
528 }
529 catch (Exception e) {
530 errln("en_us->equals(null) threw " + e.toString());
531 }
532 */
533 }
534
535 // @bug 4078588
536 //
537 // RuleBasedCollator breaks on "< a < bb" rule
538 //
539 void CollationRegressionTest::Test4078588(/* char *par */)
540 {
541 UErrorCode status = U_ZERO_ERROR;
542 RuleBasedCollator *rbc = new RuleBasedCollator("&9 < a < bb", status);
543
544 if (rbc == NULL || U_FAILURE(status))
545 {
546 errln("Failed to create RuleBasedCollator.");
547 delete rbc;
548 return;
549 }
550
551 Collator::EComparisonResult result = rbc->compare("a","bb");
552
553 if (result != Collator::LESS)
554 {
555 errln((UnicodeString)"Compare(a,bb) returned " + (int)result
556 + (UnicodeString)"; expected -1");
557 }
558
559 delete rbc;
560 }
561
562 // @bug 4081866
563 //
564 // Combining characters in different classes not reordered properly.
565 //
566 void CollationRegressionTest::Test4081866(/* char* par */)
567 {
568 // These combining characters are all in different classes,
569 // so they should be reordered and the strings should compare as equal.
570 static const UChar s1[] = {0x41, 0x0300, 0x0316, 0x0327, 0x0315, 0};
571 static const UChar s2[] = {0x41, 0x0327, 0x0316, 0x0315, 0x0300, 0};
572
573 UErrorCode status = U_ZERO_ERROR;
574 RuleBasedCollator *c = (RuleBasedCollator *) en_us->clone();
575 c->setStrength(Collator::TERTIARY);
576
577 // Now that the default collators are set to NO_DECOMPOSITION
578 // (as a result of fixing bug 4114077), we must set it explicitly
579 // when we're testing reordering behavior. -- lwerner, 5/5/98
580 c->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_ON, status);
581
582 if (c->compare(s1,s2) != 0)
583 {
584 errln("Combining chars were not reordered");
585 }
586
587 delete c;
588 }
589
590 // @bug 4087241
591 //
592 // string comparison errors in Scandinavian collators
593 //
594 void CollationRegressionTest::Test4087241(/* char* par */)
595 {
596 UErrorCode status = U_ZERO_ERROR;
597 Locale da_DK("da", "DK");
598 RuleBasedCollator *c = NULL;
599
600 c = (RuleBasedCollator *) Collator::createInstance(da_DK, status);
601
602 if (c == NULL || U_FAILURE(status))
603 {
604 errln("Failed to create collator for da_DK locale");
605 delete c;
606 return;
607 }
608
609 c->setStrength(Collator::SECONDARY);
610
611 static const UChar tests[][CollationRegressionTest::MAX_TOKEN_LEN] =
612 {
613 {0x7a, 0}, {0x3c, 0}, {0x00E6, 0}, // z < ae
614 {0x61, 0x0308, 0}, {0x3c, 0}, {0x61, 0x030A, 0}, // a-umlaut < a-ring
615 {0x59, 0}, {0x3c, 0}, {0x75, 0x0308, 0}, // Y < u-umlaut
616 };
617
618 compareArray(*c, tests, UPRV_LENGTHOF(tests));
619
620 delete c;
621 }
622
623 // @bug 4087243
624 //
625 // CollationKey takes ignorable strings into account when it shouldn't
626 //
627 void CollationRegressionTest::Test4087243(/* char* par */)
628 {
629 RuleBasedCollator *c = (RuleBasedCollator *) en_us->clone();
630 c->setStrength(Collator::TERTIARY);
631
632 static const UChar tests[][CollationRegressionTest::MAX_TOKEN_LEN] =
633 {
634 {0x31, 0x32, 0x33, 0}, {0x3d, 0}, {0x31, 0x32, 0x33, 0x0001, 0} // 1 2 3 = 1 2 3 ctrl-A
635 };
636
637 compareArray(*c, tests, UPRV_LENGTHOF(tests));
638
639 delete c;
640 }
641
642 // @bug 4092260
643 //
644 // Mu/micro conflict
645 // Micro symbol and greek lowercase letter Mu should sort identically
646 //
647 void CollationRegressionTest::Test4092260(/* char* par */)
648 {
649 UErrorCode status = U_ZERO_ERROR;
650 Locale el("el", "");
651 Collator *c = NULL;
652
653 c = Collator::createInstance(el, status);
654
655 if (c == NULL || U_FAILURE(status))
656 {
657 errln("Failed to create collator for el locale.");
658 delete c;
659 return;
660 }
661
662 // These now have tertiary differences in UCA
663 c->setAttribute(UCOL_STRENGTH, UCOL_SECONDARY, status);
664
665 static const UChar tests[][CollationRegressionTest::MAX_TOKEN_LEN] =
666 {
667 {0x00B5, 0}, {0x3d, 0}, {0x03BC, 0}
668 };
669
670 compareArray(*c, tests, UPRV_LENGTHOF(tests));
671
672 delete c;
673 }
674
675 // @bug 4095316
676 //
677 void CollationRegressionTest::Test4095316(/* char* par */)
678 {
679 UErrorCode status = U_ZERO_ERROR;
680 Locale el_GR("el", "GR");
681 Collator *c = Collator::createInstance(el_GR, status);
682
683 if (c == NULL || U_FAILURE(status))
684 {
685 errln("Failed to create collator for el_GR locale");
686 delete c;
687 return;
688 }
689 // These now have tertiary differences in UCA
690 //c->setStrength(Collator::TERTIARY);
691 c->setAttribute(UCOL_STRENGTH, UCOL_SECONDARY, status);
692
693 static const UChar tests[][CollationRegressionTest::MAX_TOKEN_LEN] =
694 {
695 {0x03D4, 0}, {0x3d, 0}, {0x03AB, 0}
696 };
697
698 compareArray(*c, tests, UPRV_LENGTHOF(tests));
699
700 delete c;
701 }
702
703 // @bug 4101940
704 //
705 void CollationRegressionTest::Test4101940(/* char* par */)
706 {
707 UErrorCode status = U_ZERO_ERROR;
708 RuleBasedCollator *c = NULL;
709 UnicodeString rules = "&9 < a < b";
710 UnicodeString nothing = "";
711
712 c = new RuleBasedCollator(rules, status);
713
714 if (c == NULL || U_FAILURE(status))
715 {
716 errln("Failed to create RuleBasedCollator");
717 delete c;
718 return;
719 }
720
721 CollationElementIterator *i = c->createCollationElementIterator(nothing);
722 i->reset();
723
724 if (i->next(status) != CollationElementIterator::NULLORDER)
725 {
726 errln("next did not return NULLORDER");
727 }
728
729 delete i;
730 delete c;
731 }
732
733 // @bug 4103436
734 //
735 // Collator::compare not handling spaces properly
736 //
737 void CollationRegressionTest::Test4103436(/* char* par */)
738 {
739 RuleBasedCollator *c = (RuleBasedCollator *) en_us->clone();
740 c->setStrength(Collator::TERTIARY);
741
742 static const UChar tests[][CollationRegressionTest::MAX_TOKEN_LEN] =
743 {
744 {0x66, 0x69, 0x6c, 0x65, 0}, {0x3c, 0}, {0x66, 0x69, 0x6c, 0x65, 0x20, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0},
745 {0x66, 0x69, 0x6c, 0x65, 0}, {0x3c, 0}, {0x66, 0x69, 0x6c, 0x65, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0}
746 };
747
748 compareArray(*c, tests, UPRV_LENGTHOF(tests));
749
750 delete c;
751 }
752
753 // @bug 4114076
754 //
755 // Collation not Unicode conformant with Hangul syllables
756 //
757 void CollationRegressionTest::Test4114076(/* char* par */)
758 {
759 UErrorCode status = U_ZERO_ERROR;
760 RuleBasedCollator *c = (RuleBasedCollator *) en_us->clone();
761 c->setStrength(Collator::TERTIARY);
762
763 //
764 // With Canonical decomposition, Hangul syllables should get decomposed
765 // into Jamo, but Jamo characters should not be decomposed into
766 // conjoining Jamo
767 //
768 static const UChar test1[][CollationRegressionTest::MAX_TOKEN_LEN] =
769 {
770 {0xd4db, 0}, {0x3d, 0}, {0x1111, 0x1171, 0x11b6, 0}
771 };
772
773 c->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_ON, status);
774 compareArray(*c, test1, UPRV_LENGTHOF(test1));
775
776 // From UTR #15:
777 // *In earlier versions of Unicode, jamo characters like ksf
778 // had compatibility mappings to kf + sf. These mappings were
779 // removed in Unicode 2.1.9 to ensure that Hangul syllables are maintained.)
780 // That is, the following test is obsolete as of 2.1.9
781
782 //obsolete- // With Full decomposition, it should go all the way down to
783 //obsolete- // conjoining Jamo characters.
784 //obsolete- //
785 //obsolete- static const UChar test2[][CollationRegressionTest::MAX_TOKEN_LEN] =
786 //obsolete- {
787 //obsolete- {0xd4db, 0}, {0x3d, 0}, {0x1111, 0x116e, 0x1175, 0x11af, 0x11c2, 0}
788 //obsolete- };
789 //obsolete-
790 //obsolete- c->setDecomposition(Normalizer::DECOMP_COMPAT);
791 //obsolete- compareArray(*c, test2, UPRV_LENGTHOF(test2));
792
793 delete c;
794 }
795
796
797 // @bug 4124632
798 //
799 // Collator::getCollationKey was hanging on certain character sequences
800 //
801 void CollationRegressionTest::Test4124632(/* char* par */)
802 {
803 UErrorCode status = U_ZERO_ERROR;
804 Collator *coll = NULL;
805
806 coll = Collator::createInstance(Locale::getJapan(), status);
807
808 if (coll == NULL || U_FAILURE(status))
809 {
810 errln("Failed to create collator for Locale::JAPAN");
811 delete coll;
812 return;
813 }
814
815 static const UChar test[] = {0x41, 0x0308, 0x62, 0x63, 0};
816 CollationKey key;
817
818 coll->getCollationKey(test, key, status);
819
820 if (key.isBogus() || U_FAILURE(status))
821 {
822 errln("CollationKey creation failed.");
823 }
824
825 delete coll;
826 }
827
828 // @bug 4132736
829 //
830 // sort order of french words with multiple accents has errors
831 //
832 void CollationRegressionTest::Test4132736(/* char* par */)
833 {
834 UErrorCode status = U_ZERO_ERROR;
835
836 Collator *c = NULL;
837
838 c = Collator::createInstance(Locale::getCanadaFrench(), status);
839 c->setStrength(Collator::TERTIARY);
840
841 if (c == NULL || U_FAILURE(status))
842 {
843 errln("Failed to create a collator for Locale::getCanadaFrench()");
844 delete c;
845 return;
846 }
847
848 static const UChar test1[][CollationRegressionTest::MAX_TOKEN_LEN] =
849 {
850 {0x65, 0x0300, 0x65, 0x0301, 0}, {0x3c, 0}, {0x65, 0x0301, 0x65, 0x0300, 0},
851 {0x65, 0x0300, 0x0301, 0}, {0x3c, 0}, {0x65, 0x0301, 0x0300, 0}
852 };
853
854 compareArray(*c, test1, UPRV_LENGTHOF(test1));
855
856 delete c;
857 }
858
859 // @bug 4133509
860 //
861 // The sorting using java.text.CollationKey is not in the exact order
862 //
863 void CollationRegressionTest::Test4133509(/* char* par */)
864 {
865 static const UChar test1[][CollationRegressionTest::MAX_TOKEN_LEN] =
866 {
867 {0x45, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0}, {0x3c, 0}, {0x45, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x72, 0x45, 0x72, 0x72, 0x6f, 0x72, 0},
868 {0x47, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0}, {0x3c, 0}, {0x47, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0},
869 {0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0}, {0x3c, 0}, {0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0}
870 };
871
872 compareArray(*en_us, test1, UPRV_LENGTHOF(test1));
873 }
874
875 // @bug 4114077
876 //
877 // Collation with decomposition off doesn't work for Europe
878 //
879 void CollationRegressionTest::Test4114077(/* char* par */)
880 {
881 // Ensure that we get the same results with decomposition off
882 // as we do with it on....
883
884 UErrorCode status = U_ZERO_ERROR;
885 RuleBasedCollator *c = (RuleBasedCollator *) en_us->clone();
886 c->setStrength(Collator::TERTIARY);
887
888 static const UChar test1[][CollationRegressionTest::MAX_TOKEN_LEN] =
889 {
890 {0x00C0, 0}, {0x3d, 0}, {0x41, 0x0300, 0}, // Should be equivalent
891 {0x70, 0x00ea, 0x63, 0x68, 0x65, 0}, {0x3e, 0}, {0x70, 0x00e9, 0x63, 0x68, 0x00e9, 0},
892 {0x0204, 0}, {0x3d, 0}, {0x45, 0x030F, 0},
893 {0x01fa, 0}, {0x3d, 0}, {0x41, 0x030a, 0x0301, 0}, // a-ring-acute -> a-ring, acute
894 // -> a, ring, acute
895 {0x41, 0x0300, 0x0316, 0}, {0x3c, 0}, {0x41, 0x0316, 0x0300, 0} // No reordering --> unequal
896 };
897
898 c->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_OFF, status);
899 compareArray(*c, test1, UPRV_LENGTHOF(test1));
900
901 static const UChar test2[][CollationRegressionTest::MAX_TOKEN_LEN] =
902 {
903 {0x41, 0x0300, 0x0316, 0}, {0x3d, 0}, {0x41, 0x0316, 0x0300, 0} // Reordering --> equal
904 };
905
906 c->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_ON, status);
907 compareArray(*c, test2, UPRV_LENGTHOF(test2));
908
909 delete c;
910 }
911
912 // @bug 4141640
913 //
914 // Support for Swedish gone in 1.1.6 (Can't create Swedish collator)
915 //
916 void CollationRegressionTest::Test4141640(/* char* par */)
917 {
918 //
919 // Rather than just creating a Swedish collator, we might as well
920 // try to instantiate one for every locale available on the system
921 // in order to prevent this sort of bug from cropping up in the future
922 //
923 UErrorCode status = U_ZERO_ERROR;
924 int32_t i, localeCount;
925 const Locale *locales = Locale::getAvailableLocales(localeCount);
926
927 for (i = 0; i < localeCount; i += 1)
928 {
929 Collator *c = NULL;
930
931 status = U_ZERO_ERROR;
932 c = Collator::createInstance(locales[i], status);
933
934 if (c == NULL || U_FAILURE(status))
935 {
936 UnicodeString msg, localeName;
937
938 msg += "Could not create collator for locale ";
939 msg += locales[i].getName();
940
941 errln(msg);
942 }
943
944 delete c;
945 }
946 }
947
948 // @bug 4139572
949 //
950 // getCollationKey throws exception for spanish text
951 // Cannot reproduce this bug on 1.2, however it DOES fail on 1.1.6
952 //
953 void CollationRegressionTest::Test4139572(/* char* par */)
954 {
955 //
956 // Code pasted straight from the bug report
957 // (and then translated to C++ ;-)
958 //
959 // create spanish locale and collator
960 UErrorCode status = U_ZERO_ERROR;
961 Locale l("es", "es");
962 Collator *col = NULL;
963
964 col = Collator::createInstance(l, status);
965
966 if (col == NULL || U_FAILURE(status))
967 {
968 errln("Failed to create a collator for es_es locale.");
969 delete col;
970 return;
971 }
972
973 CollationKey key;
974
975 // this spanish phrase kills it!
976 col->getCollationKey("Nombre De Objeto", key, status);
977
978 if (key.isBogus() || U_FAILURE(status))
979 {
980 errln("Error creating CollationKey for \"Nombre De Ojbeto\"");
981 }
982
983 delete col;
984 }
985 /* HSYS : RuleBasedCollator::compare() performance enhancements
986 compare() does not create CollationElementIterator() anymore.*/
987
988 class My4146160Collator : public RuleBasedCollator
989 {
990 public:
991 My4146160Collator(RuleBasedCollator &rbc, UErrorCode &status);
992 ~My4146160Collator();
993
994 CollationElementIterator *createCollationElementIterator(const UnicodeString &text) const;
995
996 CollationElementIterator *createCollationElementIterator(const CharacterIterator &text) const;
997
998 static int32_t count;
999 };
1000
1001 int32_t My4146160Collator::count = 0;
1002
1003 My4146160Collator::My4146160Collator(RuleBasedCollator &rbc, UErrorCode &status)
1004 : RuleBasedCollator(rbc.getRules(), status)
1005 {
1006 }
1007
1008 My4146160Collator::~My4146160Collator()
1009 {
1010 }
1011
1012 CollationElementIterator *My4146160Collator::createCollationElementIterator(const UnicodeString &text) const
1013 {
1014 count += 1;
1015 return RuleBasedCollator::createCollationElementIterator(text);
1016 }
1017
1018 CollationElementIterator *My4146160Collator::createCollationElementIterator(const CharacterIterator &text) const
1019 {
1020 count += 1;
1021 return RuleBasedCollator::createCollationElementIterator(text);
1022 }
1023
1024 // @bug 4146160
1025 //
1026 // RuleBasedCollator doesn't use createCollationElementIterator internally
1027 //
1028 void CollationRegressionTest::Test4146160(/* char* par */)
1029 {
1030 #if 0
1031 //
1032 // Use a custom collator class whose createCollationElementIterator
1033 // methods increment a count....
1034 //
1035 UErrorCode status = U_ZERO_ERROR;
1036 CollationKey key;
1037
1038 My4146160Collator::count = 0;
1039 My4146160Collator *mc = NULL;
1040
1041 mc = new My4146160Collator(*en_us, status);
1042
1043 if (mc == NULL || U_FAILURE(status))
1044 {
1045 errln("Failed to create a My4146160Collator.");
1046 delete mc;
1047 return;
1048 }
1049
1050 mc->getCollationKey("1", key, status);
1051
1052 if (key.isBogus() || U_FAILURE(status))
1053 {
1054 errln("Failure to get a CollationKey from a My4146160Collator.");
1055 delete mc;
1056 return;
1057 }
1058
1059 if (My4146160Collator::count < 1)
1060 {
1061 errln("My4146160Collator::createCollationElementIterator not called for getCollationKey");
1062 }
1063
1064 My4146160Collator::count = 0;
1065 mc->compare("1", "2");
1066
1067 if (My4146160Collator::count < 1)
1068 {
1069 errln("My4146160Collator::createtCollationElementIterator not called for compare");
1070 }
1071
1072 delete mc;
1073 #endif
1074 }
1075
1076 void CollationRegressionTest::Test4179216() {
1077 // you can position a CollationElementIterator in the middle of
1078 // a contracting character sequence, yielding a bogus collation
1079 // element
1080 IcuTestErrorCode errorCode(*this, "Test4179216");
1081 RuleBasedCollator coll(en_us->getRules() + " & C < ch , cH , Ch , CH < cat < crunchy", errorCode);
1082 UnicodeString testText = "church church catcatcher runcrunchynchy";
1083 CollationElementIterator *iter = coll.createCollationElementIterator(testText);
1084
1085 // test that the "ch" combination works properly
1086 iter->setOffset(4, errorCode);
1087 int32_t elt4 = CollationElementIterator::primaryOrder(iter->next(errorCode));
1088
1089 iter->reset();
1090 int32_t elt0 = CollationElementIterator::primaryOrder(iter->next(errorCode));
1091
1092 iter->setOffset(5, errorCode);
1093 int32_t elt5 = CollationElementIterator::primaryOrder(iter->next(errorCode));
1094
1095 // Compares and prints only 16-bit primary weights.
1096 if (elt4 != elt0 || elt5 != elt0) {
1097 errln("The collation elements at positions 0 (0x%04x), "
1098 "4 (0x%04x), and 5 (0x%04x) don't match.",
1099 elt0, elt4, elt5);
1100 }
1101
1102 // test that the "cat" combination works properly
1103 iter->setOffset(14, errorCode);
1104 int32_t elt14 = CollationElementIterator::primaryOrder(iter->next(errorCode));
1105
1106 iter->setOffset(15, errorCode);
1107 int32_t elt15 = CollationElementIterator::primaryOrder(iter->next(errorCode));
1108
1109 iter->setOffset(16, errorCode);
1110 int32_t elt16 = CollationElementIterator::primaryOrder(iter->next(errorCode));
1111
1112 iter->setOffset(17, errorCode);
1113 int32_t elt17 = CollationElementIterator::primaryOrder(iter->next(errorCode));
1114
1115 iter->setOffset(18, errorCode);
1116 int32_t elt18 = CollationElementIterator::primaryOrder(iter->next(errorCode));
1117
1118 iter->setOffset(19, errorCode);
1119 int32_t elt19 = CollationElementIterator::primaryOrder(iter->next(errorCode));
1120
1121 // Compares and prints only 16-bit primary weights.
1122 if (elt14 != elt15 || elt14 != elt16 || elt14 != elt17
1123 || elt14 != elt18 || elt14 != elt19) {
1124 errln("\"cat\" elements don't match: elt14 = 0x%04x, "
1125 "elt15 = 0x%04x, elt16 = 0x%04x, elt17 = 0x%04x, "
1126 "elt18 = 0x%04x, elt19 = 0x%04x",
1127 elt14, elt15, elt16, elt17, elt18, elt19);
1128 }
1129
1130 // now generate a complete list of the collation elements,
1131 // first using next() and then using setOffset(), and
1132 // make sure both interfaces return the same set of elements
1133 iter->reset();
1134
1135 int32_t elt = iter->next(errorCode);
1136 int32_t count = 0;
1137 while (elt != CollationElementIterator::NULLORDER) {
1138 ++count;
1139 elt = iter->next(errorCode);
1140 }
1141
1142 LocalArray<UnicodeString> nextElements(new UnicodeString[count]);
1143 LocalArray<UnicodeString> setOffsetElements(new UnicodeString[count]);
1144 int32_t lastPos = 0;
1145
1146 iter->reset();
1147 elt = iter->next(errorCode);
1148 count = 0;
1149 while (elt != CollationElementIterator::NULLORDER) {
1150 nextElements[count++] = testText.tempSubStringBetween(lastPos, iter->getOffset());
1151 lastPos = iter->getOffset();
1152 elt = iter->next(errorCode);
1153 }
1154 int32_t nextElementsLength = count;
1155 count = 0;
1156 for (int32_t i = 0; i < testText.length(); ) {
1157 iter->setOffset(i, errorCode);
1158 lastPos = iter->getOffset();
1159 elt = iter->next(errorCode);
1160 setOffsetElements[count++] = testText.tempSubStringBetween(lastPos, iter->getOffset());
1161 i = iter->getOffset();
1162 }
1163 for (int32_t i = 0; i < nextElementsLength; i++) {
1164 if (nextElements[i] == setOffsetElements[i]) {
1165 logln(nextElements[i]);
1166 } else {
1167 errln(UnicodeString("Error: next() yielded ") + nextElements[i] +
1168 ", but setOffset() yielded " + setOffsetElements[i]);
1169 }
1170 }
1171 delete iter;
1172 }
1173
1174 // Ticket 7189
1175 //
1176 // nextSortKeyPart incorrect for EO_S1 collation
1177 static int32_t calcKeyIncremental(UCollator *coll, const UChar* text, int32_t len, uint8_t *keyBuf, int32_t /*keyBufLen*/, UErrorCode& status) {
1178 UCharIterator uiter;
1179 uint32_t state[2] = { 0, 0 };
1180 int32_t keyLen;
1181 int32_t count = 8;
1182
1183 uiter_setString(&uiter, text, len);
1184 keyLen = 0;
1185 while (TRUE) {
1186 int32_t keyPartLen = ucol_nextSortKeyPart(coll, &uiter, state, &keyBuf[keyLen], count, &status);
1187 if (U_FAILURE(status)) {
1188 return -1;
1189 }
1190 if (keyPartLen == 0) {
1191 break;
1192 }
1193 keyLen += keyPartLen;
1194 }
1195 return keyLen;
1196 }
1197
1198 void CollationRegressionTest::TestT7189() {
1199 UErrorCode status = U_ZERO_ERROR;
1200 UCollator *coll;
1201 uint32_t i;
1202
1203 static const UChar text1[][CollationRegressionTest::MAX_TOKEN_LEN] = {
1204 // "Achter De Hoven"
1205 { 0x41, 0x63, 0x68, 0x74, 0x65, 0x72, 0x20, 0x44, 0x65, 0x20, 0x48, 0x6F, 0x76, 0x65, 0x6E, 0x00 },
1206 // "ABC"
1207 { 0x41, 0x42, 0x43, 0x00 },
1208 // "HELLO world!"
1209 { 0x48, 0x45, 0x4C, 0x4C, 0x4F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x00 }
1210 };
1211
1212 static const UChar text2[][CollationRegressionTest::MAX_TOKEN_LEN] = {
1213 // "Achter de Hoven"
1214 { 0x41, 0x63, 0x68, 0x74, 0x65, 0x72, 0x20, 0x64, 0x65, 0x20, 0x48, 0x6F, 0x76, 0x65, 0x6E, 0x00 },
1215 // "abc"
1216 { 0x61, 0x62, 0x63, 0x00 },
1217 // "hello world!"
1218 { 0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x00 }
1219 };
1220
1221 // Open the collator
1222 coll = ucol_openFromShortString("EO_S1", FALSE, NULL, &status);
1223 if (U_FAILURE(status)) {
1224 errln("Failed to create a collator for short string EO_S1");
1225 return;
1226 }
1227
1228 for (i = 0; i < UPRV_LENGTHOF(text1); i++) {
1229 uint8_t key1[100], key2[100];
1230 int32_t len1, len2;
1231
1232 len1 = calcKeyIncremental(coll, text1[i], -1, key1, sizeof(key1), status);
1233 if (U_FAILURE(status)) {
1234 errln(UnicodeString("Failed to get a partial collation key for ") + text1[i]);
1235 break;
1236 }
1237 len2 = calcKeyIncremental(coll, text2[i], -1, key2, sizeof(key2), status);
1238 if (U_FAILURE(status)) {
1239 errln(UnicodeString("Failed to get a partial collation key for ") + text2[i]);
1240 break;
1241 }
1242
1243 if (len1 == len2 && uprv_memcmp(key1, key2, len1) == 0) {
1244 errln(UnicodeString("Failed: Identical key\n") + " text1: " + text1[i] + "\n" + " text2: " + text2[i] + "\n" + " key : " + TestUtility::hex(key1, len1));
1245 } else {
1246 logln(UnicodeString("Keys produced -\n") + " text1: " + text1[i] + "\n" + " key1 : " + TestUtility::hex(key1, len1) + "\n" + " text2: " + text2[i] + "\n" + " key2 : "
1247 + TestUtility::hex(key2, len2));
1248 }
1249 }
1250 ucol_close(coll);
1251 }
1252
1253 void CollationRegressionTest::TestCaseFirstCompression() {
1254 RuleBasedCollator *col = (RuleBasedCollator *) en_us->clone();
1255 UErrorCode status = U_ZERO_ERROR;
1256
1257 // default
1258 caseFirstCompressionSub(col, "default");
1259
1260 // Upper first
1261 col->setAttribute(UCOL_CASE_FIRST, UCOL_UPPER_FIRST, status);
1262 if (U_FAILURE(status)) {
1263 errln("Failed to set UCOL_UPPER_FIRST");
1264 return;
1265 }
1266 caseFirstCompressionSub(col, "upper first");
1267
1268 // Lower first
1269 col->setAttribute(UCOL_CASE_FIRST, UCOL_LOWER_FIRST, status);
1270 if (U_FAILURE(status)) {
1271 errln("Failed to set UCOL_LOWER_FIRST");
1272 return;
1273 }
1274 caseFirstCompressionSub(col, "lower first");
1275
1276 delete col;
1277 }
1278
1279 void CollationRegressionTest::caseFirstCompressionSub(Collator *col, UnicodeString opt) {
1280 const int32_t maxLength = 50;
1281
1282 UChar str1[maxLength];
1283 UChar str2[maxLength];
1284
1285 CollationKey key1, key2;
1286
1287 for (int32_t len = 1; len <= maxLength; len++) {
1288 int32_t i = 0;
1289 for (; i < len - 1; i++) {
1290 str1[i] = str2[i] = (UChar)0x61; // 'a'
1291 }
1292 str1[i] = (UChar)0x41; // 'A'
1293 str2[i] = (UChar)0x61; // 'a'
1294
1295 UErrorCode status = U_ZERO_ERROR;
1296 col->getCollationKey(str1, len, key1, status);
1297 col->getCollationKey(str2, len, key2, status);
1298
1299 UCollationResult cmpKey = key1.compareTo(key2, status);
1300 UCollationResult cmpCol = col->compare(str1, len, str2, len, status);
1301
1302 if (U_FAILURE(status)) {
1303 errln("Error in caseFirstCompressionSub");
1304 } else if (cmpKey != cmpCol) {
1305 errln((UnicodeString)"Inconsistent comparison(" + opt
1306 + "): str1=" + UnicodeString(str1, len) + ", str2=" + UnicodeString(str2, len)
1307 + ", cmpKey=" + cmpKey + ", cmpCol=" + cmpCol);
1308 }
1309 }
1310 }
1311
1312 void CollationRegressionTest::TestTrailingComment() {
1313 // ICU ticket #8070:
1314 // Check that the rule parser handles a comment without terminating end-of-line.
1315 IcuTestErrorCode errorCode(*this, "TestTrailingComment");
1316 RuleBasedCollator coll(UNICODE_STRING_SIMPLE("&c<b#comment1\n<a#comment2"), errorCode);
1317 UnicodeString a((UChar)0x61), b((UChar)0x62), c((UChar)0x63);
1318 assertTrue("c<b", coll.compare(c, b) < 0);
1319 assertTrue("b<a", coll.compare(b, a) < 0);
1320 }
1321
1322 void CollationRegressionTest::TestBeforeWithTooStrongAfter() {
1323 // ICU ticket #9959:
1324 // Forbid rules with a before-reset followed by a stronger relation.
1325 IcuTestErrorCode errorCode(*this, "TestBeforeWithTooStrongAfter");
1326 RuleBasedCollator before2(UNICODE_STRING_SIMPLE("&[before 2]x<<q<p"), errorCode);
1327 if(errorCode.isSuccess()) {
1328 errln("should forbid before-2-reset followed by primary relation");
1329 } else {
1330 errorCode.reset();
1331 }
1332 RuleBasedCollator before3(UNICODE_STRING_SIMPLE("&[before 3]x<<<q<<s<p"), errorCode);
1333 if(errorCode.isSuccess()) {
1334 errln("should forbid before-3-reset followed by primary or secondary relation");
1335 } else {
1336 errorCode.reset();
1337 }
1338 }
1339
1340 void CollationRegressionTest::compareArray(Collator &c,
1341 const UChar tests[][CollationRegressionTest::MAX_TOKEN_LEN],
1342 int32_t testCount)
1343 {
1344 int32_t i;
1345 Collator::EComparisonResult expectedResult = Collator::EQUAL;
1346
1347 for (i = 0; i < testCount; i += 3)
1348 {
1349 UnicodeString source(tests[i]);
1350 UnicodeString comparison(tests[i + 1]);
1351 UnicodeString target(tests[i + 2]);
1352
1353 if (comparison == "<")
1354 {
1355 expectedResult = Collator::LESS;
1356 }
1357 else if (comparison == ">")
1358 {
1359 expectedResult = Collator::GREATER;
1360 }
1361 else if (comparison == "=")
1362 {
1363 expectedResult = Collator::EQUAL;
1364 }
1365 else
1366 {
1367 UnicodeString bogus1("Bogus comparison string \"");
1368 UnicodeString bogus2("\"");
1369 errln(bogus1 + comparison + bogus2);
1370 }
1371
1372 Collator::EComparisonResult compareResult = c.compare(source, target);
1373
1374 CollationKey sourceKey, targetKey;
1375 UErrorCode status = U_ZERO_ERROR;
1376
1377 c.getCollationKey(source, sourceKey, status);
1378
1379 if (U_FAILURE(status))
1380 {
1381 errln("Couldn't get collationKey for source");
1382 continue;
1383 }
1384
1385 c.getCollationKey(target, targetKey, status);
1386
1387 if (U_FAILURE(status))
1388 {
1389 errln("Couldn't get collationKey for target");
1390 continue;
1391 }
1392
1393 Collator::EComparisonResult keyResult = sourceKey.compareTo(targetKey);
1394
1395 reportCResult( source, target, sourceKey, targetKey, compareResult, keyResult, compareResult, expectedResult );
1396
1397 }
1398 }
1399
1400 void CollationRegressionTest::assertEqual(CollationElementIterator &i1, CollationElementIterator &i2)
1401 {
1402 int32_t c1, c2, count = 0;
1403 UErrorCode status = U_ZERO_ERROR;
1404
1405 do
1406 {
1407 c1 = i1.next(status);
1408 c2 = i2.next(status);
1409
1410 if (c1 != c2)
1411 {
1412 UnicodeString msg, msg1(" ");
1413
1414 msg += msg1 + count;
1415 msg += ": strength(0x";
1416 appendHex(c1, 8, msg);
1417 msg += ") != strength(0x";
1418 appendHex(c2, 8, msg);
1419 msg += ")";
1420
1421 errln(msg);
1422 break;
1423 }
1424
1425 count += 1;
1426 }
1427 while (c1 != CollationElementIterator::NULLORDER);
1428 }
1429
1430 void CollationRegressionTest::runIndexedTest(int32_t index, UBool exec, const char* &name, char* /* par */)
1431 {
1432 if (exec)
1433 {
1434 logln("Collation Regression Tests: ");
1435 }
1436
1437 if(en_us == NULL) {
1438 dataerrln("Class collator not instantiated");
1439 name = "";
1440 return;
1441 }
1442 TESTCASE_AUTO_BEGIN;
1443 TESTCASE_AUTO(Test4048446);
1444 TESTCASE_AUTO(Test4051866);
1445 TESTCASE_AUTO(Test4053636);
1446 TESTCASE_AUTO(Test4054238);
1447 TESTCASE_AUTO(Test4054734);
1448 TESTCASE_AUTO(Test4054736);
1449 TESTCASE_AUTO(Test4058613);
1450 TESTCASE_AUTO(Test4059820);
1451 TESTCASE_AUTO(Test4060154);
1452 TESTCASE_AUTO(Test4062418);
1453 TESTCASE_AUTO(Test4065540);
1454 TESTCASE_AUTO(Test4066189);
1455 TESTCASE_AUTO(Test4066696);
1456 TESTCASE_AUTO(Test4076676);
1457 TESTCASE_AUTO(Test4078588);
1458 TESTCASE_AUTO(Test4079231);
1459 TESTCASE_AUTO(Test4081866);
1460 TESTCASE_AUTO(Test4087241);
1461 TESTCASE_AUTO(Test4087243);
1462 TESTCASE_AUTO(Test4092260);
1463 TESTCASE_AUTO(Test4095316);
1464 TESTCASE_AUTO(Test4101940);
1465 TESTCASE_AUTO(Test4103436);
1466 TESTCASE_AUTO(Test4114076);
1467 TESTCASE_AUTO(Test4114077);
1468 TESTCASE_AUTO(Test4124632);
1469 TESTCASE_AUTO(Test4132736);
1470 TESTCASE_AUTO(Test4133509);
1471 TESTCASE_AUTO(Test4139572);
1472 TESTCASE_AUTO(Test4141640);
1473 TESTCASE_AUTO(Test4146160);
1474 TESTCASE_AUTO(Test4179216);
1475 TESTCASE_AUTO(TestT7189);
1476 TESTCASE_AUTO(TestCaseFirstCompression);
1477 TESTCASE_AUTO(TestTrailingComment);
1478 TESTCASE_AUTO(TestBeforeWithTooStrongAfter);
1479 TESTCASE_AUTO_END;
1480 }
1481
1482 #endif /* #if !UCONFIG_NO_COLLATION */