]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-52_1/main/tests/collate/src/com/ibm/icu/dev/test/collator/CollationMiscTest.java
Clean up imports.
[Dictionary.git] / jars / icu4j-52_1 / main / tests / collate / src / com / ibm / icu / dev / test / collator / CollationMiscTest.java
1
2  /*
3  *******************************************************************************
4  * Copyright (C) 2002-2012, International Business Machines Corporation and    *
5  * others. All Rights Reserved.                                                *
6  *******************************************************************************
7  */
8
9 /**
10  * Port From:   ICU4C v2.1 : cintltest
11  * Source File: $ICU4CRoot/source/test/cintltest/cmsccoll.c
12  */
13
14 package com.ibm.icu.dev.test.collator;
15
16 import java.util.Arrays;
17 import java.util.Locale;
18 import java.util.Set;
19 import java.util.TreeSet;
20
21 import com.ibm.icu.dev.test.TestFmwk;
22 import com.ibm.icu.impl.ICUResourceBundle;
23 import com.ibm.icu.impl.ImplicitCEGenerator;
24 import com.ibm.icu.impl.Utility;
25 import com.ibm.icu.lang.UCharacter;
26 import com.ibm.icu.lang.UProperty;
27 import com.ibm.icu.lang.UScript;
28 import com.ibm.icu.text.CollationElementIterator;
29 import com.ibm.icu.text.CollationKey;
30 import com.ibm.icu.text.CollationKey.BoundMode;
31 import com.ibm.icu.text.Collator;
32 import com.ibm.icu.text.Collator.ReorderCodes;
33 import com.ibm.icu.text.Normalizer;
34 import com.ibm.icu.text.RawCollationKey;
35 import com.ibm.icu.text.RuleBasedCollator;
36 import com.ibm.icu.text.UTF16;
37 import com.ibm.icu.text.UnicodeSet;
38 import com.ibm.icu.text.UnicodeSetIterator;
39 import com.ibm.icu.util.ULocale;
40 import com.ibm.icu.util.UResourceBundle;
41
42 public class CollationMiscTest extends TestFmwk {
43
44     public static void main(String[] args) throws Exception {
45         new CollationMiscTest().run(args);
46         // new CollationMiscTest().TestLocaleRuleBasedCollators();
47     }
48
49     //private static final int NORM_BUFFER_TEST_LEN_ = 32;
50     private static final class Tester
51     {
52         int u;
53         String NFC;
54         String NFD;
55     }
56
57     private static final boolean hasCollationElements(Locale locale)
58     {
59         ICUResourceBundle rb = (ICUResourceBundle)UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_COLLATION_BASE_NAME,locale);
60         if (rb != null) {
61             try {
62                 String collkey = rb.getStringWithFallback("collations/default");
63                 ICUResourceBundle elements = rb.getWithFallback("collations/" + collkey);
64                 if (elements != null) {
65                     return true;
66                 }
67             } catch (Exception e) {
68             }
69         }
70         return false;
71     }
72
73     public void TestComposeDecompose()
74     {
75         Tester t[] = new Tester[0x30000];
76         t[0] = new Tester();
77         logln("Testing UCA extensively\n");
78         RuleBasedCollator coll;
79         try {
80             coll = (RuleBasedCollator)Collator.getInstance(Locale.ENGLISH);
81         }
82         catch (Exception e) {
83             warnln("Error opening collator\n");
84             return;
85         }
86
87         int noCases = 0;
88         for (int u = 0; u < 0x30000; u ++) {
89             String comp = UTF16.valueOf(u);
90             int len = comp.length();
91             t[noCases].NFC = Normalizer.normalize(u, Normalizer.NFC);
92             t[noCases].NFD = Normalizer.normalize(u, Normalizer.NFD);
93
94             if (t[noCases].NFC.length() != t[noCases].NFD.length()
95                 || (t[noCases].NFC.compareTo(t[noCases].NFD) != 0)
96                 || (len != t[noCases].NFD.length())
97                 || (comp.compareTo(t[noCases].NFD) != 0)) {
98                 t[noCases].u = u;
99                 if (len != t[noCases].NFD.length()
100                     || (comp.compareTo(t[noCases].NFD) != 0)) {
101                     t[noCases].NFC = comp;
102                 }
103                 noCases ++;
104                 t[noCases] = new Tester();
105             }
106         }
107
108         for (int u = 0; u < noCases; u ++) {
109             if (!coll.equals(t[u].NFC, t[u].NFD)) {
110                 errln("Failure: codePoint \\u" + Integer.toHexString(t[u].u)
111                       + " fails TestComposeDecompose in the UCA");
112                 CollationTest.doTest(this, coll, t[u].NFC, t[u].NFD, 0);
113             }
114         }
115
116         logln("Testing locales, number of cases = " + noCases);
117         Locale loc[] = Collator.getAvailableLocales();
118         for (int i = 0; i < loc.length; i ++) {
119             if (hasCollationElements(loc[i])) {
120                 logln("Testing locale " + loc[i].getDisplayName());
121                 coll = (RuleBasedCollator)Collator.getInstance(loc[i]);
122                 coll.setStrength(Collator.IDENTICAL);
123
124                 for (int u = 0; u < noCases; u ++) {
125                     if (!coll.equals(t[u].NFC, t[u].NFD)) {
126                         errln("Failure: codePoint \\u"
127                               + Integer.toHexString(t[u].u)
128                               + " fails TestComposeDecompose for locale "
129                               + loc[i].getDisplayName());
130                         // this tests for the iterators too
131                         CollationTest.doTest(this, coll, t[u].NFC, t[u].NFD,
132                                              0);
133                     }
134                 }
135             }
136         }
137     }
138
139     public void TestRuleOptions() {
140         // values here are hardcoded and are correct for the current UCA when
141         // the UCA changes, one might be forced to change these values.
142
143         /*
144          * These strings contain the last character before [variable top]
145          * and the first and second characters (by primary weights) after it.
146          * See FractionalUCA.txt. For example:
147             [last variable [0C FE, 05, 05]] # U+10A7F OLD SOUTH ARABIAN NUMERIC INDICATOR
148             [variable top = 0C FE]
149             [first regular [0D 0A, 05, 05]] # U+0060 GRAVE ACCENT
150            and
151             00B4; [0D 0C, 05, 05]
152          *
153          * Note: Starting with UCA 6.0, the [variable top] collation element
154          * is not the weight of any character or string,
155          * which means that LAST_VARIABLE_CHAR_STRING sorts before [last variable].
156          */
157         String LAST_VARIABLE_CHAR_STRING = "\\U00010A7F";
158         String FIRST_REGULAR_CHAR_STRING = "\\u0060";
159         String SECOND_REGULAR_CHAR_STRING = "\\u00B4";
160
161         /*
162          * This string has to match the character that has the [last regular] weight
163          * which changes with each UCA version.
164          * See the bottom of FractionalUCA.txt which says something like
165             [last regular [7A FE, 05, 05]] # U+1342E EGYPTIAN HIEROGLYPH AA032
166          *
167          * Note: Starting with UCA 6.0, the [last regular] collation element
168          * is not the weight of any character or string,
169          * which means that LAST_REGULAR_CHAR_STRING sorts before [last regular].
170          */
171         String LAST_REGULAR_CHAR_STRING = "\\U0001342E";
172
173         String[] rules = {
174             // cannot test this anymore, as [last primary ignorable] doesn't
175             // have a  code point associated to it anymore
176             // "&[before 3][last primary ignorable]<<<k",
177             // - all befores here amount to zero
178             "&[before 3][first tertiary ignorable]<<<a",
179             "&[before 3][last tertiary ignorable]<<<a",
180             "&[before 3][first secondary ignorable]<<<a",
181             "&[before 3][last secondary ignorable]<<<a",
182             // 'normal' befores
183             "&[before 3][first primary ignorable]<<<c<<<b &[first primary ignorable]<a",
184             // we don't have a code point that corresponds to the last primary
185             // ignorable
186             "&[before 3][last primary ignorable]<<<c<<<b &[last primary ignorable]<a",
187             "&[before 3][first variable]<<<c<<<b &[first variable]<a",
188             "&[last variable]<a &[before 3][last variable]<<<c<<<b ",
189             "&[first regular]<a &[before 1][first regular]<b",
190             "&[before 1][last regular]<b &[last regular]<a",
191             "&[before 1][first implicit]<b &[first implicit]<a",
192             "&[before 1][last implicit]<b &[last implicit]<a",
193             "&[last variable]<z&[last primary ignorable]<x&[last secondary ignorable]<<y&[last tertiary ignorable]<<<w&[top]<u",
194         };
195         String[][] data = {
196             // {"k", "\u20e3"},
197             {"\\u0000", "a"}, // you cannot go before first tertiary ignorable
198             {"\\u0000", "a"}, // you cannot go before last tertiary ignorable
199             {"\\u0000", "a"}, // you cannot go before first secondary ignorable
200             {"\\u0000", "a"}, // you cannot go before first secondary ignorable
201             {"c", "b", "\\u0332", "a"},
202             {"\\u0332", "\\u20e3", "c", "b", "a"},
203             {"c", "b", "\\u0009", "a", "\\u000a"},
204             {LAST_VARIABLE_CHAR_STRING, "c", "b", /* [last variable] */ "a", FIRST_REGULAR_CHAR_STRING},
205             {"b", FIRST_REGULAR_CHAR_STRING, "a", SECOND_REGULAR_CHAR_STRING},
206             // The character in the second ordering test string
207             // has to match the character that has the [last regular] weight
208             // which changes with each UCA version.
209             // See the bottom of FractionalUCA.txt which says something like
210             // [last regular [CE 27, 05, 05]] # U+1342E EGYPTIAN HIEROGLYPH AA032
211             {LAST_REGULAR_CHAR_STRING, "b", /* [last regular] */ "a", "\\u4e00"},
212             {"b", "\\u4e00", "a", "\\u4e01"},
213             {"b", "\\U0010FFFD", "a"},
214             {"\ufffb",  "w", "y", "\u20e3", "x", LAST_VARIABLE_CHAR_STRING, "z", "u"},
215         };
216
217         for (int i = 0; i< rules.length; i++) {
218             logln(String.format("rules[%d] = \"%s\"", i, rules[i]));
219             genericRulesStarter(rules[i], data[i]);
220         }
221     }
222
223     void genericRulesStarter(String rules, String[] s) {
224         genericRulesStarterWithResult(rules, s, -1);
225     }
226
227     void genericRulesStarterWithResult(String rules, String[] s, int result) {
228
229         RuleBasedCollator coll = null;
230         try {
231             coll = new RuleBasedCollator(rules);
232             // logln("Rules starter for " + rules);
233             genericOrderingTestWithResult(coll, s, result);
234         } catch (Exception e) {
235             warnln("Unable to open collator with rules " + rules);
236         }
237     }
238
239     void genericRulesStarterWithOptionsAndResult(String rules, String[] s, String[] atts, Object[] attVals, int result) {
240         RuleBasedCollator coll = null;
241         try {
242             coll = new RuleBasedCollator(rules);
243             genericOptionsSetter(coll, atts, attVals);
244             genericOrderingTestWithResult(coll, s, result);
245         } catch (Exception e) {
246             warnln("Unable to open collator with rules " + rules);
247         }
248     }
249     void genericOrderingTestWithResult(Collator coll, String[] s, int result) {
250         String t1 = "";
251         String t2 = "";
252
253         for(int i = 0; i < s.length - 1; i++) {
254             for(int j = i+1; j < s.length; j++) {
255                 t1 = Utility.unescape(s[i]);
256                 t2 = Utility.unescape(s[j]);
257                 // System.out.println(i + " " + j);
258                 CollationTest.doTest(this, (RuleBasedCollator)coll, t1, t2,
259                                      result);
260             }
261         }
262     }
263
264     void reportCResult(String source, String target, CollationKey sourceKey, CollationKey targetKey,
265                        int compareResult, int keyResult, int incResult, int expectedResult ) {
266         if (expectedResult < -1 || expectedResult > 1) {
267             errln("***** invalid call to reportCResult ****");
268             return;
269         }
270         boolean ok1 = (compareResult == expectedResult);
271         boolean ok2 = (keyResult == expectedResult);
272         boolean ok3 = (incResult == expectedResult);
273         if (ok1 && ok2 && ok3 /* synwee to undo && !isVerbose()*/) {
274             return;
275         } else {
276             String msg1 = ok1? "Ok: compare(\"" : "FAIL: compare(\"";
277             String msg2 = "\", \"";
278             String msg3 = "\") returned ";
279             String msg4 = "; expected ";
280             String sExpect = new String("");
281             String sResult = new String("");
282             sResult = appendCompareResult(compareResult, sResult);
283             sExpect = appendCompareResult(expectedResult, sExpect);
284             if (ok1) {
285                 // logln(msg1 + source + msg2 + target + msg3 + sResult);
286             } else {
287                 errln(msg1 + source + msg2 + target + msg3 + sResult + msg4 + sExpect);
288             }
289             msg1 = ok2 ? "Ok: key(\"" : "FAIL: key(\"";
290             msg2 = "\").compareTo(key(\"";
291             msg3 = "\")) returned ";
292             sResult = appendCompareResult(keyResult, sResult);
293             if (ok2) {
294                 // logln(msg1 + source + msg2 + target + msg3 + sResult);
295             } else {
296                 errln(msg1 + source + msg2 + target + msg3 + sResult + msg4 + sExpect);
297                 msg1 = "  ";
298                 msg2 = " vs. ";
299                 errln(msg1 + prettify(sourceKey) + msg2 + prettify(targetKey));
300             }
301             msg1 = ok3 ? "Ok: incCompare(\"" : "FAIL: incCompare(\"";
302             msg2 = "\", \"";
303             msg3 = "\") returned ";
304             sResult = appendCompareResult(incResult, sResult);
305             if (ok3) {
306                 // logln(msg1 + source + msg2 + target + msg3 + sResult);
307             } else {
308                 errln(msg1 + source + msg2 + target + msg3 + sResult + msg4 + sExpect);
309             }
310         }
311     }
312
313     String appendCompareResult(int result, String target) {
314         if (result == -1) {  //LESS
315             target += "LESS";
316         } else if (result == 0) {  //EQUAL
317             target += "EQUAL";
318         } else if (result == 1) {  //GREATER
319             target += "GREATER";
320         } else {
321             String huh = "?";
322             target += huh + result;
323         }
324         return target;
325     }
326
327     static String prettify(CollationKey sourceKey) {
328         int i;
329         byte[] bytes= sourceKey.toByteArray();
330         StringBuilder target = new StringBuilder("[");
331
332         for (i = 0; i < bytes.length; i++) {
333             String numStr = Integer.toHexString(bytes[i] & 0xff);
334             if (numStr.length() < 2) {
335                 target.append('0');
336             }
337             target.append(numStr).append(' ');
338         }
339         target.append(']');
340         return target.toString();
341     }
342
343     public void TestBeforePrefixFailure() {
344         String[] rules = {
345             "&g <<< a&[before 3]\uff41 <<< x",
346             "&\u30A7=\u30A7=\u3047=\uff6a&\u30A8=\u30A8=\u3048=\uff74&[before 3]\u30a7<<<\u30a9",
347             "&[before 3]\u30a7<<<\u30a9&\u30A7=\u30A7=\u3047=\uff6a&\u30A8=\u30A8=\u3048=\uff74",
348         };
349         String[][] data = {
350             {"x", "\uff41"},
351             {"\u30a9", "\u30a7"},
352             {"\u30a9", "\u30a7"},
353         };
354
355         for(int i = 0; i< rules.length; i++) {
356             genericRulesStarter(rules[i], data[i]);
357         }
358     }
359
360     public void TestContractionClosure() {
361         String[] rules = {
362             "&b=\u00e4\u00e4",
363             "&b=\u00C5",
364         };
365         String[][] data = {
366             { "b", "\u00e4\u00e4", "a\u0308a\u0308", "\u00e4a\u0308", "a\u0308\u00e4" },
367             { "b", "\u00C5", "A\u030A", "\u212B" },
368         };
369
370         for(int i = 0; i< rules.length; i++) {
371             genericRulesStarterWithResult(rules[i], data[i], 0);
372         }
373     }
374
375     public void TestPrefixCompose() {
376         String rule1 = "&\u30a7<<<\u30ab|\u30fc=\u30ac|\u30fc";
377
378         String string = rule1;
379         try {
380             RuleBasedCollator coll = new RuleBasedCollator(string);
381             logln("rule:" + coll.getRules());
382         } catch (Exception e) {
383             warnln("Error open RuleBasedCollator rule = " + string);
384         }
385     }
386
387     public void TestStrCollIdenticalPrefix() {
388         String rule = "&\ud9b0\udc70=\ud9b0\udc71";
389         String test[] = {
390             "ab\ud9b0\udc70",
391             "ab\ud9b0\udc71"
392         };
393         genericRulesStarterWithResult(rule, test, 0);
394     }
395
396     public void TestPrefix() {
397         String[] rules = {
398             "&z <<< z|a",
399             "&z <<< z|   a",
400             "[strength I]&a=\ud900\udc25&z<<<\ud900\udc25|a",
401         };
402         String[][] data = {
403             {"zz", "za"},
404             {"zz", "za"},
405             {"aa", "az", "\ud900\udc25z", "\ud900\udc25a", "zz"},
406         };
407
408         for(int i = 0; i<rules.length; i++) {
409             genericRulesStarter(rules[i], data[i]);
410         }
411     }
412
413     public void TestNewJapanese() {
414
415         String test1[] = {
416             "\u30b7\u30e3\u30fc\u30ec",
417             "\u30b7\u30e3\u30a4",
418             "\u30b7\u30e4\u30a3",
419             "\u30b7\u30e3\u30ec",
420             "\u3061\u3087\u3053",
421             "\u3061\u3088\u3053",
422             "\u30c1\u30e7\u30b3\u30ec\u30fc\u30c8",
423             "\u3066\u30fc\u305f",
424             "\u30c6\u30fc\u30bf",
425             "\u30c6\u30a7\u30bf",
426             "\u3066\u3048\u305f",
427             "\u3067\u30fc\u305f",
428             "\u30c7\u30fc\u30bf",
429             "\u30c7\u30a7\u30bf",
430             "\u3067\u3048\u305f",
431             "\u3066\u30fc\u305f\u30fc",
432             "\u30c6\u30fc\u30bf\u30a1",
433             "\u30c6\u30a7\u30bf\u30fc",
434             "\u3066\u3047\u305f\u3041",
435             "\u3066\u3048\u305f\u30fc",
436             "\u3067\u30fc\u305f\u30fc",
437             "\u30c7\u30fc\u30bf\u30a1",
438             "\u3067\u30a7\u305f\u30a1",
439             "\u30c7\u3047\u30bf\u3041",
440             "\u30c7\u30a8\u30bf\u30a2",
441             "\u3072\u3086",
442             "\u3073\u3085\u3042",
443             "\u3074\u3085\u3042",
444             "\u3073\u3085\u3042\u30fc",
445             "\u30d3\u30e5\u30a2\u30fc",
446             "\u3074\u3085\u3042\u30fc",
447             "\u30d4\u30e5\u30a2\u30fc",
448             "\u30d2\u30e5\u30a6",
449             "\u30d2\u30e6\u30a6",
450             "\u30d4\u30e5\u30a6\u30a2",
451             "\u3073\u3085\u30fc\u3042\u30fc",
452             "\u30d3\u30e5\u30fc\u30a2\u30fc",
453             "\u30d3\u30e5\u30a6\u30a2\u30fc",
454             "\u3072\u3085\u3093",
455             "\u3074\u3085\u3093",
456             "\u3075\u30fc\u308a",
457             "\u30d5\u30fc\u30ea",
458             "\u3075\u3045\u308a",
459             "\u3075\u30a5\u308a",
460             "\u3075\u30a5\u30ea",
461             "\u30d5\u30a6\u30ea",
462             "\u3076\u30fc\u308a",
463             "\u30d6\u30fc\u30ea",
464             "\u3076\u3045\u308a",
465             "\u30d6\u30a5\u308a",
466             "\u3077\u3046\u308a",
467             "\u30d7\u30a6\u30ea",
468             "\u3075\u30fc\u308a\u30fc",
469             "\u30d5\u30a5\u30ea\u30fc",
470             "\u3075\u30a5\u308a\u30a3",
471             "\u30d5\u3045\u308a\u3043",
472             "\u30d5\u30a6\u30ea\u30fc",
473             "\u3075\u3046\u308a\u3043",
474             "\u30d6\u30a6\u30ea\u30a4",
475             "\u3077\u30fc\u308a\u30fc",
476             "\u3077\u30a5\u308a\u30a4",
477             "\u3077\u3046\u308a\u30fc",
478             "\u30d7\u30a6\u30ea\u30a4",
479             "\u30d5\u30fd",
480             "\u3075\u309e",
481             "\u3076\u309d",
482             "\u3076\u3075",
483             "\u3076\u30d5",
484             "\u30d6\u3075",
485             "\u30d6\u30d5",
486             "\u3076\u309e",
487             "\u3076\u3077",
488             "\u30d6\u3077",
489             "\u3077\u309d",
490             "\u30d7\u30fd",
491             "\u3077\u3075",
492         };
493
494         String test2[] = {
495             "\u306f\u309d", // H\u309d
496             "\u30cf\u30fd", // K\u30fd
497             "\u306f\u306f", // HH
498             "\u306f\u30cf", // HK
499             "\u30cf\u30cf", // KK
500             "\u306f\u309e", // H\u309e
501             "\u30cf\u30fe", // K\u30fe
502             "\u306f\u3070", // HH\u309b
503             "\u30cf\u30d0", // KK\u309b
504             "\u306f\u3071", // HH\u309c
505             "\u30cf\u3071", // KH\u309c
506             "\u30cf\u30d1", // KK\u309c
507             "\u3070\u309d", // H\u309b\u309d
508             "\u30d0\u30fd", // K\u309b\u30fd
509             "\u3070\u306f", // H\u309bH
510             "\u30d0\u30cf", // K\u309bK
511             "\u3070\u309e", // H\u309b\u309e
512             "\u30d0\u30fe", // K\u309b\u30fe
513             "\u3070\u3070", // H\u309bH\u309b
514             "\u30d0\u3070", // K\u309bH\u309b
515             "\u30d0\u30d0", // K\u309bK\u309b
516             "\u3070\u3071", // H\u309bH\u309c
517             "\u30d0\u30d1", // K\u309bK\u309c
518             "\u3071\u309d", // H\u309c\u309d
519             "\u30d1\u30fd", // K\u309c\u30fd
520             "\u3071\u306f", // H\u309cH
521             "\u30d1\u30cf", // K\u309cK
522             "\u3071\u3070", // H\u309cH\u309b
523             "\u3071\u30d0", // H\u309cK\u309b
524             "\u30d1\u30d0", // K\u309cK\u309b
525             "\u3071\u3071", // H\u309cH\u309c
526             "\u30d1\u30d1", // K\u309cK\u309c
527         };
528
529         String[] att = { "strength", };
530         Object[] val = { new Integer(Collator.QUATERNARY), };
531
532         String[] attShifted = { "strength", "AlternateHandling"};
533         Object valShifted[] = { new Integer(Collator.QUATERNARY),
534                                 Boolean.TRUE };
535
536         genericLocaleStarterWithOptions(Locale.JAPANESE, test1, att, val);
537         genericLocaleStarterWithOptions(Locale.JAPANESE, test2, att, val);
538
539         genericLocaleStarterWithOptions(Locale.JAPANESE, test1, attShifted,
540                                         valShifted);
541         genericLocaleStarterWithOptions(Locale.JAPANESE, test2, attShifted,
542                                         valShifted);
543     }
544
545     void genericLocaleStarter(Locale locale, String s[]) {
546         RuleBasedCollator coll = null;
547         try {
548             coll = (RuleBasedCollator)Collator.getInstance(locale);
549
550         } catch (Exception e) {
551             warnln("Unable to open collator for locale " + locale);
552             return;
553         }
554         // logln("Locale starter for " + locale);
555         genericOrderingTest(coll, s);
556     }
557
558     void genericLocaleStarterWithOptions(Locale locale, String[] s, String[] attrs, Object[] values) {
559         genericLocaleStarterWithOptionsAndResult(locale, s, attrs, values, -1);
560     }
561
562     private void genericOptionsSetter(RuleBasedCollator coll, String[] attrs, Object[] values) {
563         for(int i = 0; i < attrs.length; i++) {
564             if (attrs[i].equals("strength")) {
565                 coll.setStrength(((Integer)values[i]).intValue());
566             }
567             else if (attrs[i].equals("decomp")) {
568                 coll.setDecomposition(((Integer)values[i]).intValue());
569             }
570             else if (attrs[i].equals("AlternateHandling")) {
571                 coll.setAlternateHandlingShifted(((Boolean)values[i]
572                                                   ).booleanValue());
573             }
574             else if (attrs[i].equals("NumericCollation")) {
575                 coll.setNumericCollation(((Boolean)values[i]).booleanValue());
576             }
577             else if (attrs[i].equals("UpperFirst")) {
578                 coll.setUpperCaseFirst(((Boolean)values[i]).booleanValue());
579             }
580             else if (attrs[i].equals("LowerFirst")) {
581                 coll.setLowerCaseFirst(((Boolean)values[i]).booleanValue());
582             }
583             else if (attrs[i].equals("CaseLevel")) {
584                 coll.setCaseLevel(((Boolean)values[i]).booleanValue());
585             }
586         }
587     }
588
589     void genericLocaleStarterWithOptionsAndResult(Locale locale, String[] s, String[] attrs, Object[] values, int result) {
590         RuleBasedCollator coll = null;
591         try {
592             coll = (RuleBasedCollator)Collator.getInstance(locale);
593         } catch (Exception e) {
594             warnln("Unable to open collator for locale " + locale);
595             return;
596         }
597         // logln("Locale starter for " +locale);
598
599         // logln("Setting attributes");
600         genericOptionsSetter(coll, attrs, values);
601
602         genericOrderingTestWithResult(coll, s, result);
603     }
604
605     void genericOrderingTest(Collator coll, String[] s) {
606         genericOrderingTestWithResult(coll, s, -1);
607     }
608
609     public void TestNonChars() {
610         String test[] = {
611             "\u0000",  /* ignorable */
612             "\uFFFE",  /* special merge-sort character with minimum non-ignorable weights */
613             "\uFDD0", "\uFDEF",
614             "\\U0001FFFE", "\\U0001FFFF",  /* UCA 6.0: noncharacters are treated like unassigned, */
615             "\\U0002FFFE", "\\U0002FFFF",  /* not like ignorable. */
616             "\\U0003FFFE", "\\U0003FFFF",
617             "\\U0004FFFE", "\\U0004FFFF",
618             "\\U0005FFFE", "\\U0005FFFF",
619             "\\U0006FFFE", "\\U0006FFFF",
620             "\\U0007FFFE", "\\U0007FFFF",
621             "\\U0008FFFE", "\\U0008FFFF",
622             "\\U0009FFFE", "\\U0009FFFF",
623             "\\U000AFFFE", "\\U000AFFFF",
624             "\\U000BFFFE", "\\U000BFFFF",
625             "\\U000CFFFE", "\\U000CFFFF",
626             "\\U000DFFFE", "\\U000DFFFF",
627             "\\U000EFFFE", "\\U000EFFFF",
628             "\\U000FFFFE", "\\U000FFFFF",
629             "\\U0010FFFE", "\\U0010FFFF",
630             "\uFFFF"  /* special character with maximum primary weight */
631         };
632         Collator coll = null;
633         try {
634             coll = Collator.getInstance(new Locale("en", "US"));
635         } catch (Exception e) {
636             warnln("Unable to open collator");
637             return;
638         }
639         // logln("Test non characters");
640
641         genericOrderingTestWithResult(coll, test, -1);
642     }
643
644     public void TestExtremeCompression() {
645         String[] test = new String[4];
646
647         for(int i = 0; i<4; i++) {
648             StringBuffer temp = new StringBuffer();
649             for (int j = 0; j < 2047; j++) {
650                 temp.append('a');
651             }
652             temp.append((char)('a' + i));
653             test[i] = temp.toString();
654         }
655
656         genericLocaleStarter(new Locale("en", "US"), test);
657     }
658
659     /**
660      * Tests surrogate support.
661      */
662     public void TestSurrogates() {
663         String test[] = {"z","\ud900\udc25", "\ud805\udc50", "\ud800\udc00y",
664                          "\ud800\udc00r", "\ud800\udc00f", "\ud800\udc00",
665                          "\ud800\udc00c", "\ud800\udc00b", "\ud800\udc00fa",
666                          "\ud800\udc00fb", "\ud800\udc00a", "c", "b"};
667
668         String rule = "&z < \ud900\udc25 < \ud805\udc50 < \ud800\udc00y "
669             + "< \ud800\udc00r < \ud800\udc00f << \ud800\udc00 "
670             + "< \ud800\udc00fa << \ud800\udc00fb < \ud800\udc00a "
671             + "< c < b";
672         genericRulesStarter(rule, test);
673     }
674
675     public void TestBocsuCoverage() {
676         String test = "\u0041\u0441\u4441\\U00044441\u4441\u0441\u0041";
677         Collator coll = Collator.getInstance();
678         coll.setStrength(Collator.IDENTICAL);
679         CollationKey key = coll.getCollationKey(test);
680         logln("source:" + key.getSourceString());
681     }
682
683     public void TestCyrillicTailoring() {
684         String test[] = {
685             "\u0410b",
686             "\u0410\u0306a",
687             "\u04d0A"
688         };
689         genericLocaleStarter(new Locale("en", ""), test);
690         genericRulesStarter("&\u0410 = \u0410", test);
691         genericRulesStarter("&Z < \u0410", test);
692         genericRulesStarter("&\u0410 = \u0410 < \u04d0", test);
693         genericRulesStarter("&Z < \u0410 < \u04d0", test);
694         genericRulesStarter("&\u0410 = \u0410 < \u0410\u0301", test);
695         genericRulesStarter("&Z < \u0410 < \u0410\u0301", test);
696     }
697
698     public void TestSuppressContractions() {
699         String testNoCont2[] = {
700             "\u0410\u0302a",
701             "\u0410\u0306b",
702             "\u0410c"
703         };
704         String testNoCont[] = {
705             "a\u0410",
706             "A\u0410\u0306",
707             "\uFF21\u0410\u0302"
708         };
709
710         genericRulesStarter("[suppressContractions [\u0400-\u047f]]", testNoCont);
711         genericRulesStarter("[suppressContractions [\u0400-\u047f]]", testNoCont2);
712     }
713
714     public void TestCase() {
715         String gRules = "\u0026\u0030\u003C\u0031\u002C\u2460\u003C\u0061\u002C\u0041";
716         String[] testCase = {
717             "1a", "1A", "\u2460a", "\u2460A"
718         };
719         int[][] caseTestResults = {
720             { -1, -1, -1, 0, -1, -1, 0, 0, -1 },
721             { 1, -1, -1, 0, -1, -1, 0, 0, 1 },
722             { -1, -1, -1, 0, 1, -1, 0, 0, -1 },
723             { 1, -1, 1, 0, -1, -1, 0, 0, 1 }
724
725         };
726         boolean[][] caseTestAttributes = {
727             { false, false},
728             { true, false},
729             { false, true},
730             { true, true}
731         };
732
733         int i,j,k;
734         Collator  myCollation;
735         try {
736             myCollation = Collator.getInstance(new Locale("en", "US"));
737         } catch (Exception e) {
738             warnln("ERROR: in creation of rule based collator ");
739             return;
740         }
741         // logln("Testing different case settings");
742         myCollation.setStrength(Collator.TERTIARY);
743
744         for(k = 0; k <4; k++) {
745             if (caseTestAttributes[k][0] == true) {
746                 // upper case first
747                 ((RuleBasedCollator)myCollation).setUpperCaseFirst(true);
748             }
749             else {
750                 // upper case first
751                 ((RuleBasedCollator)myCollation).setLowerCaseFirst(true);
752             }
753             ((RuleBasedCollator)myCollation).setCaseLevel(
754                                                           caseTestAttributes[k][1]);
755
756             // logln("Case first = " + caseTestAttributes[k][0] + ", Case level = " + caseTestAttributes[k][1]);
757             for (i = 0; i < 3 ; i++) {
758                 for(j = i+1; j<4; j++) {
759                     CollationTest.doTest(this,
760                                          (RuleBasedCollator)myCollation,
761                                          testCase[i], testCase[j],
762                                          caseTestResults[k][3*i+j-1]);
763                 }
764             }
765         }
766         try {
767             myCollation = new RuleBasedCollator(gRules);
768         } catch (Exception e) {
769             warnln("ERROR: in creation of rule based collator");
770             return;
771         }
772         // logln("Testing different case settings with custom rules");
773         myCollation.setStrength(Collator.TERTIARY);
774
775         for(k = 0; k<4; k++) {
776             if (caseTestAttributes[k][0] == true) {
777                 ((RuleBasedCollator)myCollation).setUpperCaseFirst(true);
778             }
779             else {
780                 ((RuleBasedCollator)myCollation).setUpperCaseFirst(false);
781             }
782             ((RuleBasedCollator)myCollation).setCaseLevel(
783                                                           caseTestAttributes[k][1]);
784             for (i = 0; i < 3 ; i++) {
785                 for(j = i+1; j<4; j++) {
786                     CollationTest.doTest(this,
787                                          (RuleBasedCollator)myCollation,
788                                          testCase[i], testCase[j],
789                                          caseTestResults[k][3*i+j-1]);
790                 }
791             }
792         }
793
794         {
795             String[] lowerFirst = {
796                 "h",
797                 "H",
798                 "ch",
799                 "Ch",
800                 "CH",
801                 "cha",
802                 "chA",
803                 "Cha",
804                 "ChA",
805                 "CHa",
806                 "CHA",
807                 "i",
808                 "I"
809             };
810
811             String[] upperFirst = {
812                 "H",
813                 "h",
814                 "CH",
815                 "Ch",
816                 "ch",
817                 "CHA",
818                 "CHa",
819                 "ChA",
820                 "Cha",
821                 "chA",
822                 "cha",
823                 "I",
824                 "i"
825             };
826             // logln("mixed case test");
827             // logln("lower first, case level off");
828             genericRulesStarter("[casefirst lower]&H<ch<<<Ch<<<CH", lowerFirst);
829             // logln("upper first, case level off");
830             genericRulesStarter("[casefirst upper]&H<ch<<<Ch<<<CH", upperFirst);
831             // logln("lower first, case level on");
832             genericRulesStarter("[casefirst lower][caselevel on]&H<ch<<<Ch<<<CH", lowerFirst);
833             // logln("upper first, case level on");
834             genericRulesStarter("[casefirst upper][caselevel on]&H<ch<<<Ch<<<CH", upperFirst);
835         }
836     }
837
838     public void TestIncompleteCnt() {
839         String[] cnt1 = {
840             "AA",
841             "AC",
842             "AZ",
843             "AQ",
844             "AB",
845             "ABZ",
846             "ABQ",
847             "Z",
848             "ABC",
849             "Q",
850             "B"
851         };
852
853         String[] cnt2 = {
854             "DA",
855             "DAD",
856             "DAZ",
857             "MAR",
858             "Z",
859             "DAVIS",
860             "MARK",
861             "DAV",
862             "DAVI"
863         };
864         RuleBasedCollator coll =  null;
865         String temp = " & Z < ABC < Q < B";
866         try {
867             coll = new RuleBasedCollator(temp);
868         } catch (Exception e) {
869             warnln("fail to create RuleBasedCollator");
870             return;
871         }
872
873         int size = cnt1.length;
874         for(int i = 0; i < size-1; i++) {
875             for(int j = i+1; j < size; j++) {
876                 String t1 = cnt1[i];
877                 String t2 = cnt1[j];
878                 CollationTest.doTest(this, coll, t1, t2, -1);
879             }
880         }
881
882         temp = " & Z < DAVIS < MARK <DAV";
883         try {
884             coll = new RuleBasedCollator(temp);
885         } catch (Exception e) {
886             warnln("fail to create RuleBasedCollator");
887             return;
888         }
889
890         size = cnt2.length;
891         for(int i = 0; i < size-1; i++) {
892             for(int j = i+1; j < size; j++) {
893                 String t1 = cnt2[i];
894                 String t2 = cnt2[j];
895                 CollationTest.doTest(this, coll, t1, t2, -1);
896             }
897         }
898     }
899
900     public void TestBlackBird() {
901         String[] shifted = {
902             "black bird",
903             "black-bird",
904             "blackbird",
905             "black Bird",
906             "black-Bird",
907             "blackBird",
908             "black birds",
909             "black-birds",
910             "blackbirds"
911         };
912         int[] shiftedTert = {
913             0,
914             0,
915             0,
916             -1,
917             0,
918             0,
919             -1,
920             0,
921             0
922         };
923         String[] nonignorable = {
924             "black bird",
925             "black Bird",
926             "black birds",
927             "black-bird",
928             "black-Bird",
929             "black-birds",
930             "blackbird",
931             "blackBird",
932             "blackbirds"
933         };
934         int i = 0, j = 0;
935         int size = 0;
936         Collator coll = Collator.getInstance(new Locale("en", "US"));
937         //ucol_setAttribute(coll, UCOL_NORMALIZATION_MODE, UCOL_OFF, &status);
938         //ucol_setAttribute(coll, UCOL_ALTERNATE_HANDLING, UCOL_NON_IGNORABLE, &status);
939         ((RuleBasedCollator)coll).setAlternateHandlingShifted(false);
940         size = nonignorable.length;
941         for(i = 0; i < size-1; i++) {
942             for(j = i+1; j < size; j++) {
943                 String t1 = nonignorable[i];
944                 String t2 = nonignorable[j];
945                 CollationTest.doTest(this, (RuleBasedCollator)coll, t1, t2, -1);
946             }
947         }
948         ((RuleBasedCollator)coll).setAlternateHandlingShifted(true);
949         coll.setStrength(Collator.QUATERNARY);
950         size = shifted.length;
951         for(i = 0; i < size-1; i++) {
952             for(j = i+1; j < size; j++) {
953                 String t1 = shifted[i];
954                 String t2 = shifted[j];
955                 CollationTest.doTest(this, (RuleBasedCollator)coll, t1, t2, -1);
956             }
957         }
958         coll.setStrength(Collator.TERTIARY);
959         size = shifted.length;
960         for(i = 1; i < size; i++) {
961             String t1 = shifted[i-1];
962             String t2 = shifted[i];
963             CollationTest.doTest(this, (RuleBasedCollator)coll, t1, t2,
964                                  shiftedTert[i]);
965         }
966     }
967
968     public void TestFunkyA() {
969         String[] testSourceCases = {
970             "\u0041\u0300\u0301",
971             "\u0041\u0300\u0316",
972             "\u0041\u0300",
973             "\u00C0\u0301",
974             // this would work with forced normalization
975             "\u00C0\u0316",
976         };
977
978         String[] testTargetCases = {
979             "\u0041\u0301\u0300",
980             "\u0041\u0316\u0300",
981             "\u00C0",
982             "\u0041\u0301\u0300",
983             // this would work with forced normalization
984             "\u0041\u0316\u0300",
985         };
986
987         int[] results = {
988             1,
989             0,
990             0,
991             1,
992             0
993         };
994
995         Collator  myCollation;
996         try {
997             myCollation = Collator.getInstance(new Locale("en", "US"));
998         } catch (Exception e) {
999             warnln("ERROR: in creation of rule based collator");
1000             return;
1001         }
1002         // logln("Testing some A letters, for some reason");
1003         myCollation.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
1004         myCollation.setStrength(Collator.TERTIARY);
1005         for (int i = 0; i < 4 ; i++)
1006             {
1007                 CollationTest.doTest(this, (RuleBasedCollator)myCollation,
1008                                      testSourceCases[i], testTargetCases[i],
1009                                      results[i]);
1010             }
1011     }
1012
1013     public void TestChMove() {
1014         String[] chTest = {
1015             "c",
1016             "C",
1017             "ca", "cb", "cx", "cy", "CZ",
1018             "c\u030C", "C\u030C",
1019             "h",
1020             "H",
1021             "ha", "Ha", "harly", "hb", "HB", "hx", "HX", "hy", "HY",
1022             "ch", "cH", "Ch", "CH",
1023             "cha", "charly", "che", "chh", "chch", "chr",
1024             "i", "I", "iarly",
1025             "r", "R",
1026             "r\u030C", "R\u030C",
1027             "s",
1028             "S",
1029             "s\u030C", "S\u030C",
1030             "z", "Z",
1031             "z\u030C", "Z\u030C"
1032         };
1033         Collator coll = null;
1034         try {
1035             coll = Collator.getInstance(new Locale("cs", ""));
1036         } catch (Exception e) {
1037             warnln("Cannot create Collator");
1038             return;
1039         }
1040         int size = chTest.length;
1041         for(int i = 0; i < size-1; i++) {
1042             for(int j = i+1; j < size; j++) {
1043                 String t1 = chTest[i];
1044                 String t2 = chTest[j];
1045                 CollationTest.doTest(this, (RuleBasedCollator)coll, t1, t2, -1);
1046             }
1047         }
1048     }
1049
1050     public void TestImplicitTailoring() {
1051         String rules[] = { "&[before 1]\u4e00 < b < c &[before 1]\u4e00 < d < e",
1052                            "&\u4e00 < a <<< A < b <<< B",
1053                            "&[before 1]\u4e00 < \u4e01 < \u4e02",
1054                            "&[before 1]\u4e01 < \u4e02 < \u4e03",
1055         };
1056         String cases[][] = {
1057             { "d", "e", "b", "c", "\u4e00"},
1058             { "\u4e00", "a", "A", "b", "B", "\u4e01"},
1059             { "\u4e01", "\u4e02", "\u4e00"},
1060             { "\u4e02", "\u4e03", "\u4e01"},
1061         };
1062
1063         int i = 0;
1064
1065         for(i = 0; i < rules.length; i++) {
1066             genericRulesStarter(rules[i], cases[i]);
1067         }
1068
1069     }
1070
1071     public void TestFCDProblem() {
1072         String s1 = "\u0430\u0306\u0325";
1073         String s2 = "\u04D1\u0325";
1074         Collator coll = null;
1075         try {
1076             coll = Collator.getInstance();
1077         } catch (Exception e) {
1078             warnln("Can't create collator");
1079             return;
1080         }
1081
1082         coll.setDecomposition(Collator.NO_DECOMPOSITION);
1083         CollationTest.doTest(this, (RuleBasedCollator)coll, s1, s2, 0);
1084         coll.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
1085         CollationTest.doTest(this, (RuleBasedCollator)coll, s1, s2, 0);
1086     }
1087
1088     public void TestEmptyRule() {
1089         String rulez = "";
1090         try {
1091             RuleBasedCollator coll = new RuleBasedCollator(rulez);
1092             logln("rule:" + coll.getRules());
1093         } catch (Exception e) {
1094             warnln(e.getMessage());
1095         }
1096     }
1097
1098     /* superseded by TestBeforePinyin, since Chinese collation rules have changed */
1099     /*
1100     public void TestJ784() {
1101         String[] data = {
1102             "A", "\u0101", "\u00e1", "\u01ce", "\u00e0",
1103             "E", "\u0113", "\u00e9", "\u011b", "\u00e8",
1104             "I", "\u012b", "\u00ed", "\u01d0", "\u00ec",
1105             "O", "\u014d", "\u00f3", "\u01d2", "\u00f2",
1106             "U", "\u016b", "\u00fa", "\u01d4", "\u00f9",
1107             "\u00fc", "\u01d6", "\u01d8", "\u01da", "\u01dc"
1108         };
1109         genericLocaleStarter(new Locale("zh", ""), data);
1110     }
1111     */
1112
1113     public void TestJ815() {
1114         String data[] = {
1115             "aa",
1116             "Aa",
1117             "ab",
1118             "Ab",
1119             "ad",
1120             "Ad",
1121             "ae",
1122             "Ae",
1123             "\u00e6",
1124             "\u00c6",
1125             "af",
1126             "Af",
1127             "b",
1128             "B"
1129         };
1130         genericLocaleStarter(new Locale("fr", ""), data);
1131         genericRulesStarter("[backwards 2]&A<<\u00e6/e<<<\u00c6/E", data);
1132     }
1133
1134     public void TestJ3087()
1135     {
1136         String rule[] = {"&h<H&CH=\u0427",
1137                          "&CH=\u0427&h<H",
1138                          "&CH=\u0427"};
1139         RuleBasedCollator rbc = null;
1140         CollationElementIterator iter1;
1141         CollationElementIterator iter2;
1142         for (int i = 0; i < rule.length; i ++) {
1143             try {
1144                 rbc = new RuleBasedCollator(rule[i]);
1145             } catch (Exception e) {
1146                 warnln(e.getMessage());
1147                 return;
1148             }
1149             iter1 = rbc.getCollationElementIterator("CH");
1150             iter2 = rbc.getCollationElementIterator("\u0427");
1151             int ce1 = CollationElementIterator.IGNORABLE;
1152             int ce2 = CollationElementIterator.IGNORABLE;
1153             while (ce1 != CollationElementIterator.NULLORDER
1154                    && ce2 != CollationElementIterator.NULLORDER) {
1155                 ce1 = iter1.next();
1156                 ce2 = iter2.next();
1157                 if (ce1 != ce2) {
1158                     errln("Error generating RuleBasedCollator with the rule "
1159                           + rule[i]);
1160                     errln("CH != \\u0427");
1161                 }
1162             }
1163         }
1164     }
1165
1166     public void DontTestJ831() { // Latvian does not use upper first
1167         String[] data = {
1168             "I",
1169             "i",
1170             "Y",
1171             "y"
1172         };
1173         genericLocaleStarter(new Locale("lv", ""), data);
1174     }
1175
1176     public void TestBefore() {
1177         String data[] = {
1178             "\u0101", "\u00e1", "\u01ce", "\u00e0", "A",
1179             "\u0113", "\u00e9", "\u011b", "\u00e8", "E",
1180             "\u012b", "\u00ed", "\u01d0", "\u00ec", "I",
1181             "\u014d", "\u00f3", "\u01d2", "\u00f2", "O",
1182             "\u016b", "\u00fa", "\u01d4", "\u00f9", "U",
1183             "\u01d6", "\u01d8", "\u01da", "\u01dc", "\u00fc"
1184         };
1185         genericRulesStarter(
1186                             "&[before 1]a<\u0101<\u00e1<\u01ce<\u00e0"
1187                             + "&[before 1]e<\u0113<\u00e9<\u011b<\u00e8"
1188                             + "&[before 1]i<\u012b<\u00ed<\u01d0<\u00ec"
1189                             + "&[before 1]o<\u014d<\u00f3<\u01d2<\u00f2"
1190                             + "&[before 1]u<\u016b<\u00fa<\u01d4<\u00f9"
1191                             + "&u<\u01d6<\u01d8<\u01da<\u01dc<\u00fc", data);
1192     }
1193
1194     public void TestRedundantRules() {
1195         String[] rules = {
1196             //"& a <<< b <<< c << d <<< e& [before 1] e <<< x",
1197             "& b <<< c <<< d << e <<< f& [before 3] f <<< x",
1198             "& a < b <<< c << d <<< e& [before 1] e <<< x",
1199             "& a < b < c < d& [before 1] c < m",
1200             "& a < b <<< c << d <<< e& [before 3] e <<< x",
1201             "& a < b <<< c << d <<< e& [before 2] e <<< x",
1202             "& a < b <<< c << d <<< e <<< f < g& [before 1] g < x",
1203             "& a <<< b << c < d& a < m",
1204             "&a<b<<b\u0301 &z<b",
1205             "&z<m<<<q<<<m",
1206             "&z<<<m<q<<<m",
1207             "& a < b < c < d& r < c",
1208             "& a < b < c < d& r < c",
1209             "& a < b < c < d& c < m",
1210             "& a < b < c < d& a < m"
1211         };
1212
1213         String[] expectedRules = {
1214             //"&\u2089<<<x",
1215             "&\u0252<<<x",
1216             "& a <<< x < b <<< c << d <<< e",
1217             "& a < b < m < c < d",
1218             "& a < b <<< c << d <<< x <<< e",
1219             "& a < b <<< c <<< x << d <<< e",
1220             "& a < b <<< c << d <<< e <<< f < x < g",
1221             "& a <<< b << c < m < d",
1222             "&a<b\u0301 &z<b",
1223             "&z<q<<<m",
1224             "&z<q<<<m",
1225             "& a < b < d& r < c",
1226             "& a < b < d& r < c",
1227             "& a < b < c < m < d",
1228             "& a < m < b < c < d"
1229         };
1230
1231         String[][] testdata = {
1232             //            {"\u2089", "x"},
1233             {"\u0252", "x"},
1234             {"a", "x", "b", "c", "d", "e"},
1235             {"a", "b", "m", "c", "d"},
1236             {"a", "b", "c", "d", "x", "e"},
1237             {"a", "b", "c", "x", "d", "e"},
1238             {"a", "b", "c", "d", "e", "f", "x", "g"},
1239             {"a", "b", "c", "m", "d"},
1240             {"a", "b\u0301", "z", "b"},
1241             {"z", "q", "m"},
1242             {"z", "q", "m"},
1243             {"a", "b", "d"},
1244             {"r", "c"},
1245             {"a", "b", "c", "m", "d"},
1246             {"a", "m", "b", "c", "d"}
1247         };
1248
1249         String rlz = "";
1250         for(int i = 0; i<rules.length; i++) {
1251             logln("testing rule " + rules[i] + ", expected to be" + expectedRules[i]);
1252             try {
1253                 rlz = rules[i];
1254                 Collator credundant = new RuleBasedCollator(rlz);
1255                 rlz = expectedRules[i];
1256                 Collator cresulting = new RuleBasedCollator(rlz);
1257                 logln(" credundant Rule:" + ((RuleBasedCollator)credundant).getRules());
1258                 logln(" cresulting Rule:" + ((RuleBasedCollator)cresulting).getRules());
1259             } catch (Exception e) {
1260                 warnln("Cannot create RuleBasedCollator");
1261             }
1262             //testAgainstUCA(cresulting, credundant, "expected", TRUE, &status);
1263             // logln("testing using data\n");
1264             genericRulesStarter(rules[i], testdata[i]);
1265         }
1266     }
1267
1268     public void TestExpansionSyntax() {
1269         String[] rules = {
1270             "&AE <<< a << b <<< c &d <<< f",
1271             "&AE <<< a <<< b << c << d < e < f <<< g",
1272             "&AE <<< B <<< C / D <<< F"
1273         };
1274
1275         String[] expectedRules = {
1276             "&A <<< a / E << b / E <<< c /E  &d <<< f",
1277             "&A <<< a / E <<< b / E << c / E << d / E < e < f <<< g",
1278             "&A <<< B / E <<< C / ED <<< F / E"
1279         };
1280
1281         String[][] testdata = {
1282             {"AE", "a", "b", "c"},
1283             {"AE", "a", "b", "c", "d", "e", "f", "g"},
1284             {"AE", "B", "C"} // / ED <<< F / E"},
1285         };
1286
1287         for(int i = 0; i<rules.length; i++) {
1288             // logln("testing rule " + rules[i] + ", expected to be " + expectedRules[i]);
1289             try {
1290                 String rlz = rules[i];
1291                 Collator credundant = new RuleBasedCollator(rlz);
1292                 rlz = expectedRules[i];
1293                 Collator cresulting = new RuleBasedCollator(rlz);
1294                 logln(" credundant Rule:" + ((RuleBasedCollator)credundant).getRules());
1295                 logln(" cresulting Rule:" + ((RuleBasedCollator)cresulting).getRules());
1296             } catch (Exception e) {
1297                 warnln(e.getMessage());
1298             }
1299             // testAgainstUCA still doesn't handle expansions correctly, so this is not run
1300             // as a hard error test, but only in information mode
1301             //testAgainstUCA(cresulting, credundant, "expected", FALSE, &status);
1302
1303             // logln("testing using data");
1304             genericRulesStarter(rules[i], testdata[i]);
1305         }
1306     }
1307
1308     public void TestHangulTailoring() {
1309         String[] koreanData = {
1310             "\uac00", "\u4f3d", "\u4f73", "\u5047", "\u50f9", "\u52a0", "\u53ef", "\u5475",
1311             "\u54e5", "\u5609", "\u5ac1", "\u5bb6", "\u6687", "\u67b6", "\u67b7", "\u67ef",
1312             "\u6b4c", "\u73c2", "\u75c2", "\u7a3c", "\u82db", "\u8304", "\u8857", "\u8888",
1313             "\u8a36", "\u8cc8", "\u8dcf", "\u8efb", "\u8fe6", "\u99d5",
1314             "\u4EEE", "\u50A2", "\u5496", "\u54FF", "\u5777", "\u5B8A", "\u659D", "\u698E",
1315             "\u6A9F", "\u73C8", "\u7B33", "\u801E", "\u8238", "\u846D", "\u8B0C"
1316         };
1317
1318         String rules =
1319             "&\uac00 <<< \u4f3d <<< \u4f73 <<< \u5047 <<< \u50f9 <<< \u52a0 <<< \u53ef <<< \u5475 "
1320             + "<<< \u54e5 <<< \u5609 <<< \u5ac1 <<< \u5bb6 <<< \u6687 <<< \u67b6 <<< \u67b7 <<< \u67ef "
1321             + "<<< \u6b4c <<< \u73c2 <<< \u75c2 <<< \u7a3c <<< \u82db <<< \u8304 <<< \u8857 <<< \u8888 "
1322             + "<<< \u8a36 <<< \u8cc8 <<< \u8dcf <<< \u8efb <<< \u8fe6 <<< \u99d5 "
1323             + "<<< \u4EEE <<< \u50A2 <<< \u5496 <<< \u54FF <<< \u5777 <<< \u5B8A <<< \u659D <<< \u698E "
1324             + "<<< \u6A9F <<< \u73C8 <<< \u7B33 <<< \u801E <<< \u8238 <<< \u846D <<< \u8B0C";
1325
1326         String rlz = rules;
1327
1328         Collator coll = null;
1329         try {
1330             coll = new RuleBasedCollator(rlz);
1331         } catch (Exception e) {
1332             warnln("Unable to open collator with rules" + rules);
1333             return;
1334         }
1335         // logln("Using start of korean rules\n");
1336         genericOrderingTest(coll, koreanData);
1337         // logln("Setting jamoSpecial to TRUE and testing once more\n");
1338
1339         // can't set jamo in icu4j
1340         // ((UCATableHeader *)coll->image)->jamoSpecial = TRUE; // don't try this at home
1341         // genericOrderingTest(coll, koreanData);
1342
1343         // no such locale in icu4j
1344         // logln("Using ko__LOTUS locale\n");
1345         // genericLocaleStarter(new Locale("ko__LOTUS", ""), koreanData);
1346     }
1347
1348     public void TestIncrementalNormalize() {
1349         Collator        coll = null;
1350         // logln("Test 1 ....");
1351         {
1352             /* Test 1.  Run very long unnormalized strings, to force overflow of*/
1353             /*          most buffers along the way.*/
1354
1355             try {
1356                 coll = Collator.getInstance(new Locale("en", "US"));
1357             } catch (Exception e) {
1358                 warnln("Cannot get default instance!");
1359                 return;
1360             }
1361             char baseA     =0x41;
1362             char ccMix[]   = {0x316, 0x321, 0x300};
1363             int          sLen;
1364             int          i;
1365             StringBuffer strA = new StringBuffer();
1366             StringBuffer strB = new StringBuffer();
1367
1368             coll.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
1369
1370             for (sLen = 1000; sLen<1001; sLen++) {
1371                 strA.delete(0, strA.length());
1372                 strA.append(baseA);
1373                 strB.delete(0, strB.length());
1374                 strB.append(baseA);
1375                 for (i=1; i< sLen; i++) {
1376                     strA.append(ccMix[i % 3]);
1377                     strB.insert(1, ccMix[i % 3]);
1378                 }
1379                 coll.setStrength(Collator.TERTIARY);   // Do test with default strength, which runs
1380                 CollationTest.doTest(this, (RuleBasedCollator)coll,
1381                                      strA.toString(), strB.toString(), 0);    //   optimized functions in the impl
1382                 coll.setStrength(Collator.IDENTICAL);   // Do again with the slow, general impl.
1383                 CollationTest.doTest(this, (RuleBasedCollator)coll,
1384                                      strA.toString(), strB.toString(), 0);
1385             }
1386         }
1387         /*  Test 2:  Non-normal sequence in a string that extends to the last character*/
1388         /*         of the string.  Checks a couple of edge cases.*/
1389         // logln("Test 2 ....");
1390         {
1391             String strA = "AA\u0300\u0316";
1392             String strB = "A\u00c0\u0316";
1393             coll.setStrength(Collator.TERTIARY);
1394             CollationTest.doTest(this, (RuleBasedCollator)coll, strA, strB, 0);
1395         }
1396         /*  Test 3:  Non-normal sequence is terminated by a surrogate pair.*/
1397         // logln("Test 3 ....");
1398         {
1399             String strA = "AA\u0300\u0316\uD800\uDC01";
1400             String strB = "A\u00c0\u0316\uD800\uDC00";
1401             coll.setStrength(Collator.TERTIARY);
1402             CollationTest.doTest(this, (RuleBasedCollator)coll, strA, strB, 1);
1403         }
1404         /*  Test 4:  Imbedded nulls do not terminate a string when length is specified.*/
1405         // logln("Test 4 ....");
1406         /*
1407          * not a valid test since string are null-terminated in java{
1408          char strA[] = {0x41, 0x00, 0x42};
1409          char strB[] = {0x41, 0x00, 0x00};
1410
1411          int result = coll.compare(new String(strA), new String(strB));
1412          if (result != 1) {
1413          errln("ERROR 1 in test 4\n");
1414          }
1415
1416          result = coll.compare(new String(strA, 0, 1), new String(strB, 0, 1));
1417          if (result != 0) {
1418          errln("ERROR 1 in test 4\n");
1419          }
1420
1421          CollationKey sortKeyA = coll.getCollationKey(new String(strA));
1422          CollationKey sortKeyB = coll.getCollationKey(new String(strB));
1423
1424          int r = sortKeyA.compareTo(sortKeyB);
1425          if (r <= 0) {
1426          errln("Error 4 in test 4\n");
1427          }
1428
1429          coll.setStrength(Collator.IDENTICAL);
1430          sortKeyA = coll.getCollationKey(new String(strA));
1431          sortKeyB = coll.getCollationKey(new String(strB));
1432
1433          r = sortKeyA.compareTo(sortKeyB);
1434          if (r <= 0) {
1435          errln("Error 7 in test 4\n");
1436          }
1437
1438          coll.setStrength(Collator.TERTIARY);
1439          }
1440         */
1441         /*  Test 5:  Null characters in non-normal source strings.*/
1442         // logln("Test 5 ....");
1443         /*
1444          * not a valid test since string are null-terminated in java{
1445          {
1446          char strA[] = {0x41, 0x41, 0x300, 0x316, 0x00, 0x42,};
1447          char strB[] = {0x41, 0x41, 0x300, 0x316, 0x00, 0x00,};
1448
1449
1450          int result = coll.compare(new String(strA, 0, 6), new String(strB, 0, 6));
1451          if (result < 0) {
1452          errln("ERROR 1 in test 5\n");
1453          }
1454          result = coll.compare(new String(strA, 0, 4), new String(strB, 0, 4));
1455          if (result != 0) {
1456          errln("ERROR 2 in test 5\n");
1457          }
1458
1459          CollationKey sortKeyA = coll.getCollationKey(new String(strA));
1460          CollationKey sortKeyB = coll.getCollationKey(new String(strB));
1461          int r = sortKeyA.compareTo(sortKeyB);
1462          if (r <= 0) {
1463          errln("Error 4 in test 5\n");
1464          }
1465
1466          coll.setStrength(Collator.IDENTICAL);
1467
1468          sortKeyA = coll.getCollationKey(new String(strA));
1469          sortKeyB = coll.getCollationKey(new String(strB));
1470          r = sortKeyA.compareTo(sortKeyB);
1471          if (r <= 0) {
1472          errln("Error 7 in test 5\n");
1473          }
1474
1475          coll.setStrength(Collator.TERTIARY);
1476          }
1477         */
1478         /*  Test 6:  Null character as base of a non-normal combining sequence.*/
1479         // logln("Test 6 ....");
1480         /*
1481          * not a valid test since string are null-terminated in java{
1482          {
1483          char strA[] = {0x41, 0x0, 0x300, 0x316, 0x41, 0x302,};
1484          char strB[] = {0x41, 0x0, 0x302, 0x316, 0x41, 0x300,};
1485
1486          int result = coll.compare(new String(strA, 0, 5), new String(strB, 0, 5));
1487          if (result != -1) {
1488          errln("Error 1 in test 6\n");
1489          }
1490          result = coll.compare(new String(strA, 0, 1), new String(strB, 0, 1));
1491          if (result != 0) {
1492          errln("Error 2 in test 6\n");
1493          }
1494          }
1495         */
1496     }
1497
1498     public void TestContraction() {
1499         String[] testrules = {
1500             "&A = AB / B",
1501             "&A = A\\u0306/\\u0306",
1502             "&c = ch / h",
1503         };
1504         String[] testdata = {
1505             "AB", "AB", "A\u0306", "ch"
1506         };
1507         String[] testdata2 = {
1508             "\u0063\u0067",
1509             "\u0063\u0068",
1510             "\u0063\u006C",
1511         };
1512         String[] testrules3 = {
1513             "&z < xyz &xyzw << B",
1514             "&z < xyz &xyz << B / w",
1515             "&z < ch &achm << B",
1516             "&z < ch &a << B / chm",
1517             "&\ud800\udc00w << B",
1518             "&\ud800\udc00 << B / w",
1519             "&a\ud800\udc00m << B",
1520             "&a << B / \ud800\udc00m",
1521         };
1522
1523         RuleBasedCollator  coll = null;
1524         for (int i = 0; i < testrules.length; i ++) {
1525             CollationElementIterator iter1 = null;
1526             int j = 0;
1527             // logln("Rule " + testrules[i] + " for testing\n");
1528             String rule = testrules[i];
1529             try {
1530                 coll = new RuleBasedCollator(rule);
1531             } catch (Exception e) {
1532                 warnln("Collator creation failed " + testrules[i]);
1533                 return;
1534             }
1535             try {
1536                 iter1 = coll.getCollationElementIterator(testdata[i]);
1537             } catch (Exception e) {
1538                 errln("Collation iterator creation failed\n");
1539                 return;
1540             }
1541             while (j < 2) {
1542                 CollationElementIterator iter2;
1543                 int ce;
1544                 try {
1545                     iter2 = coll.getCollationElementIterator(String.valueOf(testdata[i].charAt(j)));
1546
1547                 }catch (Exception e) {
1548                     errln("Collation iterator creation failed\n");
1549                     return;
1550                 }
1551                 ce = iter2.next();
1552                 while (ce != CollationElementIterator.NULLORDER) {
1553                     if (iter1.next() != ce) {
1554                         errln("Collation elements in contraction split does not match\n");
1555                         return;
1556                     }
1557                     ce = iter2.next();
1558                 }
1559                 j ++;
1560             }
1561             if (iter1.next() != CollationElementIterator.NULLORDER) {
1562                 errln("Collation elements not exhausted\n");
1563                 return;
1564             }
1565         }
1566         String rule = "& a < b < c < ch < d & c = ch / h";
1567         try {
1568             coll = new RuleBasedCollator(rule);
1569         } catch (Exception e) {
1570             errln("cannot create rulebased collator");
1571             return;
1572         }
1573
1574         if (coll.compare(testdata2[0], testdata2[1]) != -1) {
1575             errln("Expected " + testdata2[0] + " < " + testdata2[1]);
1576             return;
1577         }
1578         if (coll.compare(testdata2[1], testdata2[2]) != -1) {
1579             errln("Expected " + testdata2[1] + " < " + testdata2[2]);
1580             return;
1581         }
1582         for (int i = 0; i < testrules3.length; i += 2) {
1583             RuleBasedCollator          coll1, coll2;
1584             CollationElementIterator iter1, iter2;
1585             char               ch = 0x0042;
1586             int            ce;
1587             rule = testrules3[i];
1588             try {
1589                 coll1 = new RuleBasedCollator(rule);
1590             } catch (Exception e) {
1591                 errln("Fail: cannot create rulebased collator, rule:" + rule);
1592                 return;
1593             }
1594             rule = testrules3[i + 1];
1595             try {
1596                 coll2 = new RuleBasedCollator(rule);
1597             } catch (Exception e) {
1598                 errln("Collator creation failed " + testrules[i]);
1599                 return;
1600             }
1601             try {
1602                 iter1 = coll1.getCollationElementIterator(String.valueOf(ch));
1603                 iter2 = coll2.getCollationElementIterator(String.valueOf(ch));
1604             } catch (Exception e) {
1605                 errln("Collation iterator creation failed\n");
1606                 return;
1607             }
1608             ce = iter1.next();
1609
1610             while (ce != CollationElementIterator.NULLORDER) {
1611                 if (ce != iter2.next()) {
1612                     errln("CEs does not match\n");
1613                     return;
1614                 }
1615                 ce = iter1.next();
1616             }
1617             if (iter2.next() != CollationElementIterator.NULLORDER) {
1618                 errln("CEs not exhausted\n");
1619                 return;
1620             }
1621         }
1622     }
1623
1624     public void TestExpansion() {
1625         String[] testrules = {
1626             "&J << K / B & K << M",
1627             "&J << K / B << M"
1628         };
1629         String[] testdata = {
1630             "JA", "MA", "KA", "KC", "JC", "MC",
1631         };
1632
1633         Collator  coll;
1634         for (int i = 0; i < testrules.length; i++) {
1635             // logln("Rule " + testrules[i] + " for testing\n");
1636             String rule = testrules[i];
1637             try {
1638                 coll = new RuleBasedCollator(rule);
1639             } catch (Exception e) {
1640                 warnln("Collator creation failed " + testrules[i]);
1641                 return;
1642             }
1643
1644             for (int j = 0; j < 5; j ++) {
1645                 CollationTest.doTest(this, (RuleBasedCollator)coll,
1646                                      testdata[j], testdata[j + 1], -1);
1647             }
1648         }
1649     }
1650
1651     public void TestContractionEndCompare()
1652     {
1653         String rules = "&b=ch";
1654         String src = "bec";
1655         String tgt = "bech";
1656         Collator coll = null;
1657         try {
1658             coll = new RuleBasedCollator(rules);
1659         } catch (Exception e) {
1660             warnln("Collator creation failed " + rules);
1661             return;
1662         }
1663         CollationTest.doTest(this, (RuleBasedCollator)coll, src, tgt, 1);
1664     }
1665
1666     public void TestLocaleRuleBasedCollators() {
1667         if (getInclusion() < 5) {
1668             // not serious enough to run this
1669             return;
1670         }
1671         Locale locale[] = Collator.getAvailableLocales();
1672         String prevrule = null;
1673         for (int i = 0; i < locale.length; i ++) {
1674             Locale l = locale[i];
1675             try {
1676                 ICUResourceBundle rb = (ICUResourceBundle)UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_COLLATION_BASE_NAME,l);
1677                 String collkey = rb.getStringWithFallback("collations/default");
1678                 ICUResourceBundle elements = rb.getWithFallback("collations/" + collkey);
1679                 if (elements == null) {
1680                     continue;
1681                 }
1682                 String rule = null;
1683                 /*
1684                   Object[][] colldata = (Object[][])elements;
1685                   // %%CollationBin
1686                   if (colldata[0][1] instanceof byte[]){
1687                   rule = (String)colldata[1][1];
1688                   }
1689                   else {
1690                   rule = (String)colldata[0][1];
1691                   }
1692                 */
1693                 rule = elements.getString("Sequence");
1694
1695                 RuleBasedCollator col1 =
1696                     (RuleBasedCollator)Collator.getInstance(l);
1697                 if (!rule.equals(col1.getRules())) {
1698                     errln("Rules should be the same in the RuleBasedCollator and Locale");
1699                 }
1700                 if (rule != null && rule.length() > 0
1701                     && !rule.equals(prevrule)) {
1702                     RuleBasedCollator col2 = new RuleBasedCollator(rule);
1703                     if (!col1.equals(col2)) {
1704                         errln("Error creating RuleBasedCollator from " +
1705                               "locale rules for " + l.toString());
1706                     }
1707                 }
1708                 prevrule = rule;
1709             } catch (Exception e) {
1710                 warnln("Error retrieving resource bundle for testing: " + e.toString());
1711             }
1712         }
1713     }
1714
1715     public void TestOptimize() {
1716         /* this is not really a test - just trying out
1717          * whether copying of UCA contents will fail
1718          * Cannot really test, since the functionality
1719          * remains the same.
1720          */
1721         String rules[] = {
1722             "[optimize [\\uAC00-\\uD7FF]]"
1723         };
1724         String data[][] = {
1725             { "a", "b"}
1726         };
1727         int i = 0;
1728
1729         for(i = 0; i<rules.length; i++) {
1730             genericRulesStarter(rules[i], data[i]);
1731         }
1732     }
1733
1734     public void TestIdenticalCompare()
1735     {
1736         try {
1737             RuleBasedCollator coll
1738                 = new RuleBasedCollator("& \uD800\uDC00 = \uD800\uDC01");
1739             String strA = "AA\u0300\u0316\uD800\uDC01";
1740             String strB = "A\u00c0\u0316\uD800\uDC00";
1741             coll.setStrength(Collator.IDENTICAL);
1742             CollationTest.doTest(this, coll, strA, strB, 1);
1743         } catch (Exception e) {
1744             warnln(e.getMessage());
1745         }
1746     }
1747
1748     public void TestMergeSortKeys()
1749     {
1750         String cases[] = {"abc", "abcd", "abcde"};
1751         String prefix = "foo";
1752         String suffix = "egg";
1753         CollationKey mergedPrefixKeys[] = new CollationKey[cases.length];
1754         CollationKey mergedSuffixKeys[] = new CollationKey[cases.length];
1755
1756         Collator coll = Collator.getInstance(Locale.ENGLISH);
1757         genericLocaleStarter(Locale.ENGLISH, cases);
1758
1759         int strength = Collator.PRIMARY;
1760         while (strength <= Collator.IDENTICAL) {
1761             coll.setStrength(strength);
1762             CollationKey prefixKey = coll.getCollationKey(prefix);
1763             CollationKey suffixKey = coll.getCollationKey(suffix);
1764             for (int i = 0; i < cases.length; i ++) {
1765                 CollationKey key = coll.getCollationKey(cases[i]);
1766                 mergedPrefixKeys[i] = prefixKey.merge(key);
1767                 mergedSuffixKeys[i] = suffixKey.merge(key);
1768                 if (mergedPrefixKeys[i].getSourceString() != null
1769                     || mergedSuffixKeys[i].getSourceString() != null) {
1770                     errln("Merged source string error: expected null");
1771                 }
1772                 if (i > 0) {
1773                     if (mergedPrefixKeys[i-1].compareTo(mergedPrefixKeys[i])
1774                         >= 0) {
1775                         errln("Error while comparing prefixed keys @ strength "
1776                               + strength);
1777                         errln(prettify(mergedPrefixKeys[i-1]));
1778                         errln(prettify(mergedPrefixKeys[i]));
1779                     }
1780                     if (mergedSuffixKeys[i-1].compareTo(mergedSuffixKeys[i])
1781                         >= 0) {
1782                         errln("Error while comparing suffixed keys @ strength "
1783                               + strength);
1784                         errln(prettify(mergedSuffixKeys[i-1]));
1785                         errln(prettify(mergedSuffixKeys[i]));
1786                     }
1787                 }
1788             }
1789             if (strength == Collator.QUATERNARY) {
1790                 strength = Collator.IDENTICAL;
1791             }
1792             else {
1793                 strength ++;
1794             }
1795         }
1796     }
1797
1798     public void TestVariableTop()
1799     {
1800         // parseNextToken is not released as public so i create my own rules
1801         String rules = "& a < b < c < de < fg & hi = j";
1802         try {
1803             RuleBasedCollator coll = new RuleBasedCollator(rules);
1804             String tokens[] = {"a", "b", "c", "de", "fg", "hi", "j", "ab"};
1805             coll.setAlternateHandlingShifted(true);
1806             for (int i = 0; i < tokens.length; i ++) {
1807                 int varTopOriginal = coll.getVariableTop();
1808                 try {
1809                     int varTop = coll.setVariableTop(tokens[i]);
1810                     if (i > 4) {
1811                         errln("Token " + tokens[i] + " expected to fail");
1812                     }
1813                     if (varTop != coll.getVariableTop()) {
1814                         errln("Error setting and getting variable top");
1815                     }
1816                     CollationKey key1 = coll.getCollationKey(tokens[i]);
1817                     for (int j = 0; j < i; j ++) {
1818                         CollationKey key2 = coll.getCollationKey(tokens[j]);
1819                         if (key2.compareTo(key1) < 0) {
1820                             errln("Setting variable top shouldn't change the comparison sequence");
1821                         }
1822                         byte sortorder[] = key2.toByteArray();
1823                         if (sortorder.length > 0
1824                             && (key2.toByteArray())[0] > 1) {
1825                             errln("Primary sort order should be 0");
1826                         }
1827                     }
1828                 } catch (Exception e) {
1829                     CollationElementIterator iter
1830                         = coll.getCollationElementIterator(tokens[i]);
1831                     /*int ce =*/ iter.next();
1832                     int ce2 = iter.next();
1833                     if (ce2 == CollationElementIterator.NULLORDER) {
1834                         errln("Token " + tokens[i] + " not expected to fail");
1835                     }
1836                     if (coll.getVariableTop() != varTopOriginal) {
1837                         errln("When exception is thrown variable top should "
1838                               + "not be changed");
1839                     }
1840                 }
1841                 coll.setVariableTop(varTopOriginal);
1842                 if (varTopOriginal != coll.getVariableTop()) {
1843                     errln("Couldn't restore old variable top\n");
1844                 }
1845             }
1846
1847             // Testing calling with error set
1848             try {
1849                 coll.setVariableTop("");
1850                 errln("Empty string should throw an IllegalArgumentException");
1851             } catch (IllegalArgumentException e) {
1852                 logln("PASS: Empty string failed as expected");
1853             }
1854             try {
1855                 coll.setVariableTop(null);
1856                 errln("Null string should throw an IllegalArgumentException");
1857             } catch (IllegalArgumentException e) {
1858                 logln("PASS: null string failed as expected");
1859             }
1860         } catch (Exception e) {
1861             warnln("Error creating RuleBasedCollator");
1862         }
1863     }
1864
1865     public void TestUCARules()
1866     {
1867         try {
1868             // only root locale can have empty tailorings .. not English!
1869             RuleBasedCollator coll
1870                 = (RuleBasedCollator)Collator.getInstance(new Locale("","",""));
1871             String rule
1872                 = coll.getRules(false);
1873             if (!rule.equals("")) {
1874                 errln("Empty rule string should have empty rules " + rule);
1875             }
1876             rule = coll.getRules(true);
1877             if (rule.equals("")) {
1878                 errln("UCA rule string should not be empty");
1879             }
1880             coll = new RuleBasedCollator(rule);
1881         } catch (Exception e) {
1882             warnln(e.getMessage());
1883         }
1884     }
1885
1886     /**
1887      * Jitterbug 2726
1888      */
1889     public void TestShifted()
1890     {
1891         RuleBasedCollator collator = (RuleBasedCollator) Collator.getInstance();
1892         collator.setStrength(Collator.PRIMARY);
1893         collator.setAlternateHandlingShifted(true);
1894         CollationTest.doTest(this, collator, " a", "a", 0); // works properly
1895         CollationTest.doTest(this, collator, "a", "a ", 0); // inconsistent results
1896     }
1897
1898     /**
1899      * Test for CollationElementIterator previous and next for the whole set of
1900      * unicode characters with normalization on.
1901      */
1902     public void TestNumericCollation()
1903     {
1904         String basicTestStrings[] = {"hello1", "hello2", "hello123456"};
1905         String preZeroTestStrings[] = {"avery1",
1906                                        "avery01",
1907                                        "avery001",
1908                                        "avery0001"};
1909         String thirtyTwoBitNumericStrings[] = {"avery42949672960",
1910                                                "avery42949672961",
1911                                                "avery42949672962",
1912                                                "avery429496729610"};
1913
1914         String supplementaryDigits[] = {"\uD835\uDFCE", // 0
1915                                         "\uD835\uDFCF", // 1
1916                                         "\uD835\uDFD0", // 2
1917                                         "\uD835\uDFD1", // 3
1918                                         "\uD835\uDFCF\uD835\uDFCE", // 10
1919                                         "\uD835\uDFCF\uD835\uDFCF", // 11
1920                                         "\uD835\uDFCF\uD835\uDFD0", // 12
1921                                         "\uD835\uDFD0\uD835\uDFCE", // 20
1922                                         "\uD835\uDFD0\uD835\uDFCF", // 21
1923                                         "\uD835\uDFD0\uD835\uDFD0" // 22
1924         };
1925
1926         String foreignDigits[] = {"\u0661",
1927                                   "\u0662",
1928                                   "\u0663",
1929                                   "\u0661\u0660",
1930                                   "\u0661\u0662",
1931                                   "\u0661\u0663",
1932                                   "\u0662\u0660",
1933                                   "\u0662\u0662",
1934                                   "\u0662\u0663",
1935                                   "\u0663\u0660",
1936                                   "\u0663\u0662",
1937                                   "\u0663\u0663"
1938         };
1939         
1940         //Additional tests to cover bug reported in #9476
1941         String lastDigitDifferent[]={"2004","2005",
1942                                      "110005", "110006",
1943                                      "11005", "11006",
1944                                      "100000000005","100000000006"};
1945
1946         // Open our collator.
1947         RuleBasedCollator coll
1948             = (RuleBasedCollator)Collator.getInstance(Locale.ENGLISH);
1949         String att[] = {"NumericCollation"};
1950         Boolean val[] = {Boolean.TRUE};
1951         genericLocaleStarterWithOptions(Locale.ENGLISH, basicTestStrings, att,
1952                                         val);
1953         genericLocaleStarterWithOptions(Locale.ENGLISH,
1954                                         thirtyTwoBitNumericStrings, att, val);
1955         genericLocaleStarterWithOptions(Locale.ENGLISH, foreignDigits, att,
1956                                         val);
1957         genericLocaleStarterWithOptions(Locale.ENGLISH, supplementaryDigits,
1958                                         att, val);
1959
1960         // Setting up our collator to do digits.
1961         coll.setNumericCollation(true);
1962
1963         // Testing that prepended zeroes still yield the correct collation
1964         // behavior.
1965         // We expect that every element in our strings array will be equal.
1966         for (int i = 0; i < preZeroTestStrings.length - 1; i ++) {
1967             for (int j = i + 1; j < preZeroTestStrings.length; j ++) {
1968                 CollationTest.doTest(this, coll, preZeroTestStrings[i],
1969                                      preZeroTestStrings[j],0);
1970             }
1971         }
1972         
1973         //Testing that the behavior reported in #9476 is fixed
1974         //We expect comparisons between adjacent pairs will result in -1
1975         for (int i=0; i < lastDigitDifferent.length -1; i=i+2 ) {
1976             CollationTest.doTest(this, coll, lastDigitDifferent[i], lastDigitDifferent[i+1], -1);
1977         }
1978         
1979
1980         //cover setNumericCollationDefault, getNumericCollation
1981         assertTrue("The Numeric Collation setting is on", coll.getNumericCollation());
1982         coll.setNumericCollationDefault();
1983         logln("After set Numeric to default, the setting is: " + coll.getNumericCollation());
1984     }
1985
1986     public void Test3249()
1987     {
1988         String rule = "&x < a &z < a";
1989         try {
1990             RuleBasedCollator coll = new RuleBasedCollator(rule);
1991             if(coll!=null){
1992                 logln("Collator did not throw an exception");
1993             }
1994         } catch (Exception e) {
1995             warnln("Error creating RuleBasedCollator with " + rule + " failed");
1996         }
1997     }
1998
1999     public void TestTibetanConformance()
2000     {
2001         String test[] = {"\u0FB2\u0591\u0F71\u0061", "\u0FB2\u0F71\u0061"};
2002         try {
2003             Collator coll = Collator.getInstance();
2004             coll.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
2005             if (coll.compare(test[0], test[1]) != 0) {
2006                 errln("Tibetan comparison error");
2007             }
2008             CollationTest.doTest(this, (RuleBasedCollator)coll,
2009                                  test[0], test[1], 0);
2010         } catch (Exception e) {
2011             warnln("Error creating UCA collator");
2012         }
2013     }
2014
2015     public void TestJ3347()
2016     {
2017         try {
2018             Collator coll = Collator.getInstance(Locale.FRENCH);
2019             ((RuleBasedCollator)coll).setAlternateHandlingShifted(true);
2020             if (coll.compare("6", "!6") != 0) {
2021                 errln("Jitterbug 3347 failed");
2022             }
2023         } catch (Exception e) {
2024             warnln("Error creating UCA collator");
2025         }
2026     }
2027
2028     public void TestPinyinProblem()
2029     {
2030         String test[] = { "\u4E56\u4E56\u7761", "\u4E56\u5B69\u5B50" };
2031         genericLocaleStarter(new Locale("zh", "", "PINYIN"), test);
2032     }
2033
2034     static final long topByte = 0xFF000000L;
2035     static final long bottomByte = 0xFFL;
2036     static final long fourBytes = 0xFFFFFFFFL;
2037
2038     static final int MAX_INPUT = 0x220001; // 2 * Unicode range + 2
2039
2040     private void show(int i, ImplicitCEGenerator imp) {
2041         if (i >= 0 && i <= MAX_INPUT) {
2042             logln(Utility.hex(i) + "\t" + Utility.hex(imp.getImplicitFromRaw(i) & fourBytes));
2043         }
2044     }
2045
2046     private void throwError(String title, int cp, ImplicitCEGenerator imp) {
2047         throw new IllegalArgumentException(title + "\t" + Utility.hex(cp, 6) + "\t" + Utility.hex(imp.getImplicitFromRaw(cp) & fourBytes));
2048     }
2049
2050     private void throwError(String title, long ce) {
2051         errln(title + "\t" + Utility.hex(ce & fourBytes));
2052     }
2053
2054     public void TestImplicitGeneration()
2055     {
2056         logln("Start");
2057         try {
2058             ImplicitCEGenerator foo = new ImplicitCEGenerator(0xE0, 0xE4);
2059
2060             //int x = foo.getRawImplicit(0xF810);
2061             foo.getRawFromImplicit(0xE20303E7);
2062
2063             //int gap4 = foo.getGap4();
2064             //logln("Gap4: " + gap4);
2065             //int gap3 = foo.getGap3();
2066             //int minTrail = foo.getMinTrail();
2067             //int maxTrail = foo.getMaxTrail();
2068             long last = 0;
2069             long current;
2070             for (int i = 0; i <= MAX_INPUT; ++i) {
2071                 current = foo.getImplicitFromRaw(i) & fourBytes;
2072
2073                 // check that it round-trips AND that all intervening ones are illegal
2074                 int roundtrip = foo.getRawFromImplicit((int)current);
2075                 if (roundtrip != i) {
2076                     throwError("No roundtrip", i, foo);
2077                 }
2078                 if (last != 0) {
2079                     for (long j = last + 1; j < current; ++j) {
2080                         roundtrip = foo.getRawFromImplicit((int)j);
2081                         // raise an error if it *doesn't* find an error
2082                         if (roundtrip != -1) {
2083                             throwError("Fails to recognize illegal", j);
2084                         }
2085                     }
2086                 }
2087                 // now do other consistency checks
2088                 long lastBottom = last & bottomByte;
2089                 long currentBottom = current & bottomByte;
2090                 long lastTop = last & topByte;
2091                 long currentTop = current & topByte;
2092
2093                 // do some consistency checks
2094                 /*
2095                   long gap = current - last;
2096                   if (currentBottom != 0) { // if we are a 4-byte
2097                   // gap has to be at least gap4
2098                   // and gap from minTrail, maxTrail has to be at least gap4
2099                   if (gap <= gap4) foo.throwError("Failed gap4 between", i);
2100                   if (currentBottom < minTrail + gap4) foo.throwError("Failed gap4 before", i);
2101                   if (currentBottom > maxTrail - gap4) foo.throwError("Failed gap4 after", i);
2102                   } else { // we are a three-byte
2103                   gap = gap >> 8; // move gap down for comparison.
2104                   long current3Bottom = (current >> 8) & bottomByte;
2105                   if (gap <= gap3) foo.throwError("Failed gap3 between ", i);
2106                   if (current3Bottom < minTrail + gap3) foo.throwError("Failed gap3 before", i);
2107                   if (current3Bottom > maxTrail - gap3) foo.throwError("Failed gap3 after", i);
2108                   }
2109                 */
2110                 // print out some values for spot-checking
2111                 if (lastTop != currentTop || i == 0x10000 || i == 0x110000) {
2112                     show(i-3, foo);
2113                     show(i-2, foo);
2114                     show(i-1, foo);
2115                     if (i == 0) {
2116                         // do nothing
2117                     } else if (lastBottom == 0 && currentBottom != 0) {
2118                         logln("+ primary boundary, 4-byte CE's below");
2119                     } else if (lastTop != currentTop) {
2120                         logln("+ primary boundary");
2121                     }
2122                     show(i, foo);
2123                     show(i+1, foo);
2124                     show(i+2, foo);
2125                     logln("...");
2126                 }
2127                 last = current;
2128                 if(foo.getCodePointFromRaw(foo.getRawFromCodePoint(i)) != i) {
2129                     errln("No raw <-> code point roundtrip for "+Utility.hex(i));
2130                 }
2131             }
2132             show(MAX_INPUT-2, foo);
2133             show(MAX_INPUT-1, foo);
2134             show(MAX_INPUT, foo);
2135         } catch (Exception e) {
2136             e.printStackTrace();
2137             warnln(e.getMessage());
2138         } finally {
2139             logln("End");
2140         }
2141     }
2142
2143     /* supercedes TestJ784 */
2144     public void TestBeforePinyin() {
2145         String rules =
2146             "&[before 2]A << \u0101  <<< \u0100 << \u00E1 <<< \u00C1 << \u01CE <<< \u01CD << \u00E0 <<< \u00C0" +
2147             "&[before 2]e << \u0113 <<< \u0112 << \u00E9 <<< \u00C9 << \u011B <<< \u011A << \u00E8 <<< \u00C8" +
2148             "&[before 2] i << \u012B <<< \u012A << \u00ED <<< \u00CD << \u01D0 <<< \u01CF << \u00EC <<< \u00CC" +
2149             "&[before 2] o << \u014D <<< \u014C << \u00F3 <<< \u00D3 << \u01D2 <<< \u01D1 << \u00F2 <<< \u00D2" +
2150             "&[before 2]u << \u016B <<< \u016A << \u00FA <<< \u00DA << \u01D4 <<< \u01D3 << \u00F9 <<< \u00D9" +
2151             "&U << \u01D6 <<< \u01D5 << \u01D8 <<< \u01D7 << \u01DA <<< \u01D9 << \u01DC <<< \u01DB << \u00FC";
2152
2153         String test[] = {
2154             "l\u0101",
2155             "la",
2156             "l\u0101n",
2157             "lan ",
2158             "l\u0113",
2159             "le",
2160             "l\u0113n",
2161             "len"
2162         };
2163
2164         String test2[] = {
2165             "x\u0101",
2166             "x\u0100",
2167             "X\u0101",
2168             "X\u0100",
2169             "x\u00E1",
2170             "x\u00C1",
2171             "X\u00E1",
2172             "X\u00C1",
2173             "x\u01CE",
2174             "x\u01CD",
2175             "X\u01CE",
2176             "X\u01CD",
2177             "x\u00E0",
2178             "x\u00C0",
2179             "X\u00E0",
2180             "X\u00C0",
2181             "xa",
2182             "xA",
2183             "Xa",
2184             "XA",
2185             "x\u0101x",
2186             "x\u0100x",
2187             "x\u00E1x",
2188             "x\u00C1x",
2189             "x\u01CEx",
2190             "x\u01CDx",
2191             "x\u00E0x",
2192             "x\u00C0x",
2193             "xax",
2194             "xAx"
2195         };
2196         /* TODO: port builder fixes to before */
2197         genericRulesStarter(rules, test);
2198         genericLocaleStarter(new Locale("zh","",""), test);
2199         genericRulesStarter(rules, test2);
2200         genericLocaleStarter(new Locale("zh","",""), test2);
2201     }
2202
2203     public void TestUpperFirstQuaternary()
2204     {
2205       String tests[] = { "B", "b", "Bb", "bB" };
2206       String[] att = { "strength", "UpperFirst" };
2207       Object attVals[] = { new Integer(Collator.QUATERNARY), Boolean.TRUE };
2208       genericLocaleStarterWithOptions(new Locale("root","",""), tests, att, attVals);
2209     }
2210
2211     public void TestJ4960()
2212     {
2213         String tests[] = { "\\u00e2T", "aT" };
2214         String att[] = { "strength", "CaseLevel" };
2215         Object attVals[] = { new Integer(Collator.PRIMARY), Boolean.TRUE };
2216         String tests2[] = { "a", "A" };
2217         String rule = "&[first tertiary ignorable]=A=a";
2218         String att2[] = { "CaseLevel" };
2219         Object attVals2[] = { Boolean.TRUE };
2220         // Test whether we correctly ignore primary ignorables on case level when
2221         // we have only primary & case level
2222         genericLocaleStarterWithOptionsAndResult(new Locale("root", ""), tests, att, attVals, 0);
2223         // Test whether ICU4J will make case level for sortkeys that have primary strength
2224         // and case level
2225         genericLocaleStarterWithOptions(new Locale("root", ""), tests2, att, attVals);
2226         // Test whether completely ignorable letters have case level info (they shouldn't)
2227         genericRulesStarterWithOptionsAndResult(rule, tests2, att2, attVals2, 0);
2228     }
2229
2230     public void TestJB5298(){
2231         ULocale[] locales = Collator.getAvailableULocales();
2232         logln("Number of collator locales returned : " + locales.length);
2233         // double-check keywords
2234         String[] keywords = Collator.getKeywords();
2235         if (keywords.length != 1 || !keywords[0].equals("collation")) {
2236             throw new IllegalArgumentException("internal collation error");
2237         }
2238
2239         String[] values = Collator.getKeywordValues("collation");
2240         log("Collator.getKeywordValues returned: ");
2241         for(int i=0; i<values.length;i++){
2242             log(values[i]+", ");
2243         }
2244         logln("");
2245         logln("Number of collator values returned : " + values.length);
2246
2247         Set foundValues = new TreeSet(Arrays.asList(values));
2248
2249         for (int i = 0; i < locales.length; ++i) {
2250           for (int j = 0; j < values.length; ++j) {
2251             ULocale tryLocale = values[j].equals("standard")
2252             ? locales[i] : new ULocale(locales[i] + "@collation=" + values[j]);
2253             // only append if not standard
2254             ULocale canon = Collator.getFunctionalEquivalent("collation",tryLocale);
2255             if (!canon.equals(tryLocale)) {
2256                 continue; // has a different
2257             }else {// functional equivalent, so skip
2258                 logln(tryLocale + " : "+canon+", ");
2259             }
2260             String can = canon.toString();
2261             int idx = can.indexOf("@collation=");
2262             String val = idx >= 0 ? can.substring(idx+11, can.length()) : "";
2263             if(val.length()>0 && !foundValues.contains(val)){
2264                 errln("Unknown collation found "+ can);
2265             }
2266           }
2267         }
2268         logln(" ");
2269     }
2270
2271     public void
2272     TestJ5367()
2273     {
2274         String[] test = { "a", "y" };
2275         String rules = "&Ny << Y &[first secondary ignorable] <<< a";
2276         genericRulesStarter(rules, test);
2277     }
2278
2279     public void
2280     TestVI5913()
2281     {
2282
2283         String rules[] = {
2284                 "&a < \u00e2 <<< \u00c2",
2285                 "&a < \u1FF3 ",  // OMEGA WITH YPOGEGRAMMENI
2286                 "&s < \u0161 ",  // &s < s with caron
2287                 "&z < a\u00EA",  // &z < a+e with circumflex
2288         };
2289         String cases[][] = {
2290             { "\u1EAC", "A\u0323\u0302", "\u1EA0\u0302", "\u00C2\u0323", },
2291             { "\u1FA2", "\u03C9\u0313\u0300\u0345", "\u1FF3\u0313\u0300",
2292               "\u1F60\u0300\u0345", "\u1f62\u0345", "\u1FA0\u0300", },
2293             { "\u1E63\u030C", "s\u0323\u030C", "s\u030C\u0323"},
2294             { "a\u1EC7", //  a+ e with dot below and circumflex
2295               "a\u1EB9\u0302", // a + e with dot below + combining circumflex
2296               "a\u00EA\u0323", // a + e with circumflex + combining dot below
2297             }
2298         };
2299
2300
2301         for(int i = 0; i < rules.length; i++) {
2302
2303             RuleBasedCollator coll = null;
2304             try {
2305                 coll = new RuleBasedCollator(rules[i]);
2306             } catch (Exception e) {
2307                 warnln("Unable to open collator with rules " + rules[i]);
2308             }
2309
2310             logln("Test case["+i+"]:");
2311             CollationKey expectingKey = coll.getCollationKey(cases[i][0]);
2312             for (int j=1; j<cases[i].length; j++) {
2313                 CollationKey key = coll.getCollationKey(cases[i][j]);
2314                 if ( key.compareTo(expectingKey)!=0) {
2315                     errln("Error! Test case["+i+"]:"+"source:" + key.getSourceString());
2316                     errln("expecting:"+prettify(expectingKey)+ "got:"+  prettify(key));
2317                 }
2318                 logln("   Key:"+  prettify(key));
2319             }
2320         }
2321
2322
2323         RuleBasedCollator vi_vi = null;
2324         try {
2325             vi_vi = (RuleBasedCollator)Collator.getInstance(
2326                                                       new Locale("vi", ""));
2327             logln("VI sort:");
2328             CollationKey expectingKey = vi_vi.getCollationKey(cases[0][0]);
2329             for (int j=1; j<cases[0].length; j++) {
2330                 CollationKey key = vi_vi.getCollationKey(cases[0][j]);
2331                 if ( key.compareTo(expectingKey)!=0) {
2332                     // TODO (claireho): change the logln to errln after vi.res is up-to-date.
2333                     // errln("source:" + key.getSourceString());
2334                     // errln("expecting:"+prettify(expectingKey)+ "got:"+  prettify(key));
2335                     logln("Error!! in Vietnese sort - source:" + key.getSourceString());
2336                     logln("expecting:"+prettify(expectingKey)+ "got:"+  prettify(key));
2337                 }
2338                 // logln("source:" + key.getSourceString());
2339                 logln("   Key:"+  prettify(key));
2340             }
2341         } catch (Exception e) {
2342             warnln("Error creating Vietnese collator");
2343             return;
2344         }
2345
2346     }
2347
2348
2349     public void Test6179()
2350     {
2351         String rules[] = {
2352                 "&[last primary ignorable]<< a  &[first primary ignorable]<<b ",
2353                 "&[last secondary ignorable]<<< a &[first secondary ignorable]<<<b",
2354         };
2355         // defined in UCA5.1
2356         String firstPrimIgn = "\u0332";
2357         String lastPrimIgn = "\uD800\uDDFD";
2358         String firstVariable = "\u0009";
2359         byte[] secIgnKey = {1,1,4,0};
2360
2361         int i=0;
2362         {
2363
2364             RuleBasedCollator coll = null;
2365             try {
2366                 coll = new RuleBasedCollator(rules[i]);
2367             } catch (Exception e) {
2368                 warnln("Unable to open collator with rules " + rules[i]);
2369             }
2370
2371             logln("Test rule["+i+"]"+rules[i]);
2372
2373             CollationKey keyA = coll.getCollationKey("a");
2374             logln("Key for \"a\":"+  prettify(keyA));
2375             if (keyA.compareTo(coll.getCollationKey(lastPrimIgn))<=0) {
2376                 CollationKey key = coll.getCollationKey(lastPrimIgn);
2377                 logln("Collation key for 0xD800 0xDDFD: "+prettify(key));
2378                 errln("Error! String \"a\" must be greater than \uD800\uDDFD -"+
2379                       "[Last Primary Ignorable]");
2380             }
2381             if (keyA.compareTo(coll.getCollationKey(firstVariable))>=0) {
2382                 CollationKey key = coll.getCollationKey(firstVariable);
2383                 logln("Collation key for 0x0009: "+prettify(key));
2384                 errln("Error! String \"a\" must be less than 0x0009 - [First Variable]");
2385             }
2386             CollationKey keyB = coll.getCollationKey("b");
2387             logln("Key for \"b\":"+  prettify(keyB));
2388             if (keyB.compareTo(coll.getCollationKey(firstPrimIgn))<=0) {
2389                 CollationKey key = coll.getCollationKey(firstPrimIgn);
2390                 logln("Collation key for 0x0332: "+prettify(key));
2391                 errln("Error! String \"b\" must be greater than 0x0332 -"+
2392                       "[First Primary Ignorable]");
2393             }
2394             if (keyB.compareTo(coll.getCollationKey(firstVariable))>=0) {
2395                 CollationKey key = coll.getCollationKey(firstVariable);
2396                 logln("Collation key for 0x0009: "+prettify(key));
2397                 errln("Error! String \"b\" must be less than 0x0009 - [First Variable]");
2398             }
2399         }
2400         {
2401             i=1;
2402             RuleBasedCollator coll = null;
2403             try {
2404                 coll = new RuleBasedCollator(rules[i]);
2405             } catch (Exception e) {
2406                 warnln("Unable to open collator with rules " + rules[i]);
2407             }
2408
2409             logln("Test rule["+i+"]"+rules[i]);
2410
2411             CollationKey keyA = coll.getCollationKey("a");
2412             logln("Key for \"a\":"+  prettify(keyA));
2413             byte[] keyAInBytes = keyA.toByteArray();
2414             for (int j=0; j<keyAInBytes.length && j<secIgnKey.length; j++) {
2415                 if (keyAInBytes[j]!=secIgnKey[j]) {
2416                     if ((char)keyAInBytes[j]<=(char)secIgnKey[j]) {
2417                         logln("Error! String \"a\" must be greater than [Last Secondary Ignorable]");
2418                     }
2419                     break;
2420                 }
2421             }
2422             if (keyA.compareTo(coll.getCollationKey(firstVariable))>=0) {
2423                 errln("Error! String \"a\" must be less than 0x0009 - [First Variable]");
2424                 CollationKey key = coll.getCollationKey(firstVariable);
2425                 logln("Collation key for 0x0009: "+prettify(key));
2426             }
2427             CollationKey keyB = coll.getCollationKey("b");
2428             logln("Key for \"b\":"+  prettify(keyB));
2429             byte[] keyBInBytes = keyB.toByteArray();
2430             for (int j=0; j<keyBInBytes.length && j<secIgnKey.length; j++) {
2431                 if (keyBInBytes[j]!=secIgnKey[j]) {
2432                     if ((char)keyBInBytes[j]<=(char)secIgnKey[j]) {
2433                         errln("Error! String \"b\" must be greater than [Last Secondary Ignorable]");
2434                     }
2435                     break;
2436                 }
2437             }
2438             if (keyB.compareTo(coll.getCollationKey(firstVariable))>=0) {
2439                 CollationKey key = coll.getCollationKey(firstVariable);
2440                 logln("Collation key for 0x0009: "+prettify(key));
2441                 errln("Error! String \"b\" must be less than 0x0009 - [First Variable]");
2442             }
2443         }
2444     }
2445
2446     public void TestUCAPrecontext()
2447     {
2448         String rules[] = {
2449                 "& \u00B7<a ",
2450                 "& L\u00B7 << a", // 'a' is an expansion.
2451         };
2452         String cases[] = {
2453             "\u00B7",
2454             "\u0387",
2455             "a",
2456             "l",
2457             "L\u0332",
2458             "l\u00B7",
2459             "l\u0387",
2460             "L\u0387",
2461             "la\u0387",
2462             "La\u00b7",
2463         };
2464
2465         // Test en sort
2466         RuleBasedCollator en = null;
2467
2468         logln("EN sort:");
2469         try {
2470             en = (RuleBasedCollator)Collator.getInstance(
2471                     new Locale("en", ""));
2472             for (int j=0; j<cases.length; j++) {
2473                 CollationKey key = en.getCollationKey(cases[j]);
2474                 if (j>0) {
2475                     CollationKey prevKey = en.getCollationKey(cases[j-1]);
2476                     if (key.compareTo(prevKey)<0) {
2477                         errln("Error! EN test["+j+"]:source:" + cases[j]+
2478                         " is not >= previous test string.");
2479                     }
2480                 }
2481                 /*
2482                 if ( key.compareTo(expectingKey)!=0) {
2483                     errln("Error! Test case["+i+"]:"+"source:" + key.getSourceString());
2484                     errln("expecting:"+prettify(expectingKey)+ "got:"+  prettify(key));
2485                 }
2486                 */
2487                 logln("String:"+cases[j]+"   Key:"+  prettify(key));
2488             }
2489         } catch (Exception e) {
2490             warnln("Error creating English collator");
2491             return;
2492         }
2493
2494         // Test ja sort
2495         RuleBasedCollator ja = null;
2496         logln("JA sort:");
2497         try {
2498             ja = (RuleBasedCollator)Collator.getInstance(
2499                     new Locale("ja", ""));
2500             for (int j=0; j<cases.length; j++) {
2501                 CollationKey key = ja.getCollationKey(cases[j]);
2502                 if (j>0) {
2503                     CollationKey prevKey = ja.getCollationKey(cases[j-1]);
2504                     if (key.compareTo(prevKey)<0) {
2505                         errln("Error! JA test["+j+"]:source:" + cases[j]+
2506                         " is not >= previous test string.");
2507                     }
2508                 }
2509                 logln("String:"+cases[j]+"   Key:"+  prettify(key));
2510             }
2511         } catch (Exception e) {
2512             warnln("Error creating Japanese collator");
2513             return;
2514         }
2515         for(int i = 0; i < rules.length; i++) {
2516
2517             RuleBasedCollator coll = null;
2518             logln("Tailoring rule:"+rules[i]);
2519             try {
2520                 coll = new RuleBasedCollator(rules[i]);
2521             } catch (Exception e) {
2522                 warnln("Unable to open collator with rules " + rules[i]);
2523                 continue;
2524             }
2525
2526             for (int j=0; j<cases.length; j++) {
2527                 CollationKey key = coll.getCollationKey(cases[j]);
2528                 if (j>0) {
2529                     CollationKey prevKey = coll.getCollationKey(cases[j-1]);
2530                     if (i==1 && j==3) {
2531                         if (key.compareTo(prevKey)>0) {
2532                             errln("Error! Rule:"+rules[i]+" test["+j+"]:source:"+
2533                             cases[j]+" is not <= previous test string.");
2534                         }
2535                     }
2536                     else {
2537                         if (key.compareTo(prevKey)<0) {
2538                             errln("Error! Rule:"+rules[i]+" test["+j+"]:source:"+
2539                             cases[j]+" is not >= previous test string.");
2540                         }
2541                     }
2542                 }
2543                 logln("String:"+cases[j]+"   Key:"+  prettify(key));
2544             }
2545         }
2546     }
2547
2548
2549     /**
2550      * Stores a test case for collation testing.
2551      */
2552     private class OneTestCase {
2553         /** The first value to compare.  **/
2554         public String m_source_;
2555
2556         /** The second value to compare. **/
2557         public String m_target_;
2558
2559         /**
2560          *  0 if the two values sort equal,
2561          * -1 if the first value sorts before the second
2562          *  1 if the first value sorts after the first
2563          */
2564         public int m_result_;
2565
2566         public OneTestCase(String source, String target, int result) {
2567             m_source_ = source;
2568             m_target_ = target;
2569             m_result_ = result;
2570         }
2571     }
2572
2573     /**
2574      * Convenient function to test collation rules.
2575      * @param testCases
2576      * @param rules Collation rules in ICU format.  All the strings in this
2577      *     array represent the same rule, expressed in different forms.
2578      */
2579     private void doTestCollation(
2580         OneTestCase[] testCases, String[] rules) {
2581
2582         Collator  myCollation;
2583         for (String rule : rules) {
2584             try {
2585                 myCollation = new RuleBasedCollator(rule);
2586             } catch (Exception e) {
2587                 warnln("ERROR: in creation of rule based collator");
2588                 return;
2589             }
2590
2591             myCollation.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
2592             myCollation.setStrength(Collator.TERTIARY);
2593             for (OneTestCase testCase : testCases) {
2594                 CollationTest.doTest(this, (RuleBasedCollator)myCollation,
2595                                      testCase.m_source_,
2596                                      testCase.m_target_,
2597                                      testCase.m_result_);
2598             }
2599         }
2600     }
2601
2602      // Test cases to check whether the rules equivalent to
2603      // "&a<b<c<d &b<<k<<l<<m &k<<<x<<<y<<<z &a=1=2=3" are working fine.
2604     private OneTestCase[] m_rangeTestCases_ = {
2605         //               Left                  Right             Result
2606         new OneTestCase( "\u0061",             "\u0062",             -1 ),  // "a" < "b"
2607         new OneTestCase( "\u0062",             "\u0063",             -1 ),  // "b" < "c"
2608         new OneTestCase( "\u0061",             "\u0063",             -1 ),  // "a" < "c"
2609
2610         new OneTestCase( "\u0062",             "\u006b",             -1 ),  // "b" << "k"
2611         new OneTestCase( "\u006b",             "\u006c",             -1 ),  // "k" << "l"
2612         new OneTestCase( "\u0062",             "\u006c",             -1 ),  // "b" << "l"
2613         new OneTestCase( "\u0061",             "\u006c",             -1 ),  // "a" << "l"
2614         new OneTestCase( "\u0061",             "\u006d",             -1 ),  // "a" << "m"
2615
2616         new OneTestCase( "\u0079",             "\u006d",             -1 ),  // "y" < "f"
2617         new OneTestCase( "\u0079",             "\u0067",             -1 ),  // "y" < "g"
2618         new OneTestCase( "\u0061",             "\u0068",             -1 ),  // "y" < "h"
2619         new OneTestCase( "\u0061",             "\u0065",             -1 ),  // "g" < "e"
2620
2621         new OneTestCase( "\u0061",             "\u0031",              0 ),   // "a" == "1"
2622         new OneTestCase( "\u0061",             "\u0032",              0 ),   // "a" == "2"
2623         new OneTestCase( "\u0061",             "\u0033",              0 ),   // "a" == "3"
2624         new OneTestCase( "\u0061",             "\u0066",             -1 ),   // "a" < "f",
2625         new OneTestCase( "\u006c\u0061",       "\u006b\u0062",       -1 ),  // "la" < "kb"
2626         new OneTestCase( "\u0061\u0061\u0061", "\u0031\u0032\u0033",  0 ),  // "aaa" == "123"
2627         new OneTestCase( "\u0062",             "\u007a",             -1 ),  // "b" < "z"
2628         new OneTestCase( "\u0061\u007a\u0062", "\u0032\u0079\u006d", -1 ),  // "azm" < "2yc"
2629     };
2630
2631      // Test cases to check whether the rules equivalent to
2632      // "&\ufffe<\uffff<\U00010000<\U00010001<\U00010002
2633      //  &\U00010000<<\U00020001<<\U00020002<<\U00020002
2634      //  &\U00020001=\U0003001=\U0004001=\U0004002
2635      //  &\U00040008<\U00030008<\UU00020008"
2636      // are working fine.
2637     private OneTestCase[] m_rangeTestCasesSupplemental_ = {
2638         //               Left                Right               Result
2639         new OneTestCase( "\ufffe",           "\uffff",             -1 ),
2640         new OneTestCase( "\uffff",           "\ud800\udc00",       -1 ),  // U+FFFF < U+10000
2641         new OneTestCase( "\ud800\udc00",    "\ud800\udc01",        -1 ),  // U+10000 < U+10001
2642
2643         new OneTestCase( "\ufffe",           "\ud800\udc01",       -1 ),  // U+FFFE < U+10001
2644         new OneTestCase( "\ud800\udc01",    "\ud800\udc02",        -1 ),  // U+10001 < U+10002
2645         new OneTestCase( "\ud800\udc00",    "\ud840\udc02",        -1 ),  // U+10000 < U+10002
2646         new OneTestCase( "\ufffe",           "\u0d840\udc02",      -1 ),  // U+FFFF < U+10002
2647
2648     };
2649
2650     // Test cases in disjoint random code points.  To test only the compact syntax.
2651     // Rule:  &q<w<e<r &w<<t<<y<<u &t<<<i<<<o<<<p &o=a=s=d
2652     private OneTestCase[] m_qwertCollationTestCases_ = {
2653         new OneTestCase("q", "w" , -1),
2654         new OneTestCase("w", "e" , -1),
2655
2656         new OneTestCase("y", "u" , -1),
2657         new OneTestCase("q", "u" , -1),
2658
2659         new OneTestCase("t", "i" , -1),
2660         new OneTestCase("o", "p" , -1),
2661
2662         new OneTestCase("y", "e" , -1),
2663         new OneTestCase("i", "u" , -1),
2664
2665         new OneTestCase("quest", "were" , -1),
2666         new OneTestCase("quack", "quest", -1)
2667     };
2668
2669     // Tests the compact list with ASCII codepoints.
2670     public void TestSameStrengthList() {
2671         String[] rules = new String[] {
2672             // Normal
2673             "&a<b<c<d &b<<k<<l<<m &k<<<x<<<y<<<z &y<f<g<h<e &a=1=2=3",
2674
2675             // Lists
2676             "&a<*bcd &b<<*klm &k<<<*xyz &y<*fghe &a=*123",
2677
2678             // Lists with quoted characters
2679             "&'\u0061'<*bcd &b<<*klm &k<<<*xyz &y<*f'\u0067\u0068'e &a=*123",
2680         };
2681         doTestCollation(m_rangeTestCases_, rules);
2682     }
2683     
2684     public void TestSameStrengthListQuoted() {
2685         String[] rules = new String[] {
2686             "&'\u0061'<*bcd &b<<*klm &k<<<*xyz &y<*f'\u0067\u0068'e &a=1=2=3",
2687             "&'\u0061'<*b'\u0063'd &b<<*klm &k<<<*xyz &'\u0079'<*fgh'\u0065' " +
2688             "&a=*'\u0031\u0032\u0033'",
2689
2690             "&'\u0061'<*'\u0062'c'\u0064' &b<<*klm &k<<<*xyz  &y<*fghe " +
2691             "&a=*'\u0031\u0032\u0033'",
2692         };
2693         doTestCollation(m_rangeTestCases_, rules);
2694     }
2695
2696     // Tests the compact list with ASCII codepoints in non-codepoint order.
2697     public void TestSameStrengthListQwerty() {
2698         String[] rules = new String[] {
2699             "&q<w<e<r &w<<t<<y<<u &t<<<i<<<o<<<p &o=a=s=d",   // Normal
2700             "&q<*wer &w<<*tyu &t<<<*iop &o=*asd",             // Lists
2701         };
2702
2703         doTestCollation(m_qwertCollationTestCases_, rules);
2704     }
2705
2706     // Tests the compact list with supplemental codepoints.
2707     public void TestSameStrengthListWithSupplementalCharacters() {
2708         String[] rules = new String[] {
2709             // ** Rule without compact list syntax **
2710             // \ufffe < \uffff < \U00010000    < \U00010001  < \U00010002
2711             "&'\ufffe'<'\uffff'<'\ud800\udc00'<'\ud800\udc01'<'\ud800\udc02' " +
2712             // \U00010000    << \U00020001   << \U00020002       \U00020002
2713             "&'\ud800\udc00'<<'\ud840\udc01'<<'\ud840\udc02'<<'\ud840\udc02'  " +
2714             // \U00020001   = \U0003001    = \U0004001    = \U0004002
2715             "&'\ud840\udc01'='\ud880\udc01'='\ud8c0\udc01'='\ud8c0\udc02'" +
2716             // \U00040008   < \U00030008   < \U00020008
2717             "&'\ud8c0\udc08'<'\ud880\udc08'<'\ud840\udc08'",
2718
2719             // ** Rule with compact list syntax **
2720             // \ufffe <* \uffff\U00010000  \U00010001
2721             "&'\ufffe'<*'\uffff\ud800\udc00\ud800\udc01\ud800\udc02' " +
2722             // \U00010000   <<* \U00020001  \U00020002
2723             "&'\ud800\udc00'<<*'\ud840\udc01\ud840\udc02\ud840\udc03'  " +
2724             // \U00020001   =* \U0003001   \U0003002   \U0003003   \U0004001
2725             "&'\ud840\udc01'=*'\ud880\udc01\ud880\udc02\ud880\udc03\ud8c0\udc01' " +
2726             // \U00040008   <* \U00030008  \U00030009  \U0003000a  \U00020008
2727             "&'\ud8c0\udc08'<*'\ud880\udc08\ud880\udc09\ud880\udc0a\ud840\udc08'",
2728
2729         };
2730         doTestCollation(m_rangeTestCasesSupplemental_, rules);
2731     }
2732
2733
2734     // Tests the compact range syntax with ASCII codepoints.
2735     public void TestSameStrengthListRanges() {
2736         String[] rules = new String[] {
2737             // Ranges
2738             "&a<*b-d &b<<*k-m &k<<<*x-z &y<*f-he &a=*1-3",
2739
2740             // Ranges with quoted characters
2741             "&'\u0061'<*'\u0062'-'\u0064' &b<<*klm &k<<<*xyz " +
2742             "&'\u0079'<*'\u0066'-'\u0068e' &a=*123",
2743             "&'\u0061'<*'\u0062'-'\u0064' " +
2744             "&b<<*'\u006B'-m &k<<<*x-'\u007a' " +
2745             "&'\u0079'<*'\u0066'-h'\u0065' &a=*'\u0031\u0032\u0033'",
2746         };
2747
2748         doTestCollation(m_rangeTestCases_, rules);
2749     }
2750
2751     // Tests the compact range syntax with supplemental codepoints.
2752     public void TestSameStrengthListRangesWithSupplementalCharacters() {
2753         String[] rules = new String[] {
2754             // \ufffe <* \uffff\U00010000  \U00010001
2755             "&'\ufffe'<*'\uffff'-'\ud800\udc02' " +
2756             // \U00010000   <<* \U00020001   - \U00020003
2757             "&'\ud800\udc00'<<*'\ud840\udc01'-'\ud840\udc03'  " +
2758             // \U00020001   =* \U0003001   \U0004001
2759             "&'\ud840\udc01'=*'\ud880\udc01'-'\ud880\udc03\ud8c0\udc01' " +
2760             // \U00040008   <* \U00030008  \U00020008
2761             "&'\ud8c0\udc08'<*'\ud880\udc08'-'\ud880\udc0a\ud840\udc08'",
2762         };
2763         doTestCollation(m_rangeTestCasesSupplemental_, rules);
2764     }
2765
2766     // Tests the compact range syntax with special characters used as syntax characters in rules.
2767     public void TestSpecialCharacters() {
2768         String rules[] = new String[] {
2769                 // Normal
2770                 "&';'<'+'<','<'-'<'&'<'*'",
2771
2772                 // List
2773                 "&';'<*'+,-&*'",
2774
2775                 // Range
2776                 "&';'<*'+'-'-&*'",
2777
2778                 "&'\u003b'<'\u002b'<'\u002c'<'\u002d'<'\u0026'<'\u002a'",
2779
2780                 "&'\u003b'<*'\u002b\u002c\u002d\u0026\u002a'",
2781                 "&'\u003b'<*'\u002b\u002c\u002d\u0026\u002a'",
2782                 "&'\u003b'<*'\u002b'-'\u002d\u0026\u002a'",
2783                 "&'\u003b'<*'\u002b'-'\u002d\u0026\u002a'",
2784         };
2785         OneTestCase[] testCases = new OneTestCase[] {
2786             new OneTestCase("\u003b", "\u002b", -1), // ; < +
2787             new OneTestCase("\u002b", "\u002c", -1), // + < ,
2788             new OneTestCase("\u002c", "\u002d", -1), // , < -
2789             new OneTestCase("\u002d", "\u0026", -1), // - < &
2790         };
2791         doTestCollation(testCases, rules);
2792     }
2793     
2794     public void TestInvalidListsAndRanges() {
2795         String[] invalidRules = new String[] {
2796             // Range not in starred expression
2797             "&'\ufffe'<'\uffff'-'\ud800\udc02'",
2798             
2799             // Range without start
2800             "&a<*-c",
2801             
2802             // Range without end
2803             "&a<*b-",
2804                        
2805             // More than one hyphen
2806             "&a<*b-g-l",
2807             
2808             // Range in the wrong order
2809             "&a<*k-b",
2810         };
2811         for (String rule : invalidRules) {
2812             try {
2813                 Collator myCollation = new RuleBasedCollator(rule);
2814                 warnln("ERROR: Creation of collator didn't fail for " + rule + " when it should.");
2815                 CollationTest.doTest(this, (RuleBasedCollator)myCollation,
2816                         "x",
2817                         "y",
2818                         -1);
2819                
2820            } catch (Exception e) {
2821                 continue;
2822             }
2823            throw new IllegalArgumentException("ERROR: Invalid collator with rule " + rule + " worked fine.");
2824         }
2825     }
2826
2827     // This is the same example above with ' and space added.
2828     // They work a little different than expected.  Desired rules are commented out.
2829     public void TestQuoteAndSpace() {
2830         String rules[] = new String[] {
2831                 // These are working as expected.
2832                 "&';'<'+'<','<'-'<'&'<''<'*'<' '",
2833
2834                 // List.  Desired rule is 
2835                 // "&';'<*'+,-&''* '",
2836                 // but it doesn't work.  Instead, '' should be outside quotes as below.
2837                 "&';'<*'+,-&''''* '",
2838
2839                 // Range.  Similar issues here as well.  The following are working.
2840                 //"&';'<*'+'-'-&''* '",
2841                 //"&';'<*'+'-'-&'\\u0027'* '",
2842                 "&';'<*'+'-'-&''''* '",
2843                 //"&';'<*'+'-'-&'\\u0027'* '",
2844
2845                 // The following rules are not working.
2846                 // "&';'<'+'<','<'-'<'&'<\\u0027<'*'<' '", 
2847                 //"&'\u003b'<'\u002b'<'\u002c'<'\u002d'<'\u0026'<'\u0027'<\u002a'<'\u0020'",
2848                 //"&'\u003b'<'\u002b'<'\u002c'<'\u002d'<'\u0026'<\\u0027<\u002a'<'\u0020'",
2849         };
2850
2851         OneTestCase[] testCases = new OneTestCase[] {
2852             new OneTestCase("\u003b", "\u002b", -1), // ; < ,
2853             new OneTestCase("\u002b", "\u002c", -1), // ; < ,
2854             new OneTestCase("\u002c", "\u002d", -1), // , < -
2855             new OneTestCase("\u002d", "\u0026", -1), // - < &
2856             new OneTestCase("\u0026", "\u0027", -1), // & < '
2857             new OneTestCase("\u0027", "\u002a", -1), // ' < *
2858             // new OneTestCase("\u002a", "\u0020", -1), // * < <space>
2859         };
2860         doTestCollation(testCases, rules);
2861     }
2862
2863     /*
2864      * Tests the method public boolean equals(Object target) in CollationKey
2865      */
2866     public void TestCollationKeyEquals() {
2867         CollationKey ck = new CollationKey("", (byte[]) null);
2868
2869         // Tests when "if (!(target instanceof CollationKey))" is true
2870         if (ck.equals(new Object())) {
2871             errln("CollationKey.equals() was not suppose to return false "
2872                     + "since it is comparing to a non Collation Key object.");
2873         }
2874         if (ck.equals("")) {
2875             errln("CollationKey.equals() was not suppose to return false "
2876                     + "since it is comparing to a non Collation Key object.");
2877         }
2878         if (ck.equals(0)) {
2879             errln("CollationKey.equals() was not suppose to return false "
2880                     + "since it is comparing to a non Collation Key object.");
2881         }
2882         if (ck.equals(0.0)) {
2883             errln("CollationKey.equals() was not suppose to return false "
2884                     + "since it is comparing to a non Collation Key object.");
2885         }
2886
2887         // Tests when "if (target == null)" is true
2888         if (ck.equals((CollationKey) null)) {
2889             errln("CollationKey.equals() was not suppose to return false "
2890                     + "since it is comparing to a null Collation Key object.");
2891         }
2892     }
2893
2894     /*
2895      * Tests the method public int hashCode() in CollationKey
2896      */
2897     public void TestCollationKeyHashCode() {
2898         CollationKey ck = new CollationKey("", (byte[]) null);
2899
2900         // Tests when "if (m_key_ == null)" is true
2901         if (ck.hashCode() != 1) {
2902             errln("CollationKey.hashCode() was suppose to return 1 "
2903                     + "when m_key is null due a null parameter in the " + "constructor.");
2904         }
2905     }
2906
2907     /*
2908      * Tests the method public CollationKey getBound(int boundType, int noOfLevels)
2909      */
2910     public void TestGetBound() {
2911         CollationKey ck = new CollationKey("", (byte[]) null);
2912
2913         // Tests when "if (noOfLevels > Collator.PRIMARY)" is false
2914         // Tests when "default: " is true for "switch (boundType)"
2915         try {
2916             ck.getBound(BoundMode.COUNT, -1);
2917             errln("CollationKey.getBound(int,int) was suppose to return an "
2918                     + "exception for an invalid boundType value.");
2919         } catch (Exception e) {
2920         }
2921
2922         // Tests when "if (noOfLevels > 0)"
2923         byte b[] = {};
2924         CollationKey ck1 = new CollationKey("", b);
2925         try {
2926             ck1.getBound(0, 1);
2927             errln("CollationKey.getBound(int,int) was suppose to return an "
2928                     + "exception a value of noOfLevels that exceeds expected.");
2929         } catch (Exception e) {
2930         }
2931     }
2932
2933     /*
2934      * Tests the method public CollationKey merge(CollationKey source)
2935      */
2936     public void TestMerge() {
2937         byte b[] = {};
2938         CollationKey ck = new CollationKey("", b);
2939
2940         // Tests when "if (source == null || source.getLength() == 0)" is true
2941         try {
2942             ck.merge(null);
2943             errln("Collationkey.merge(CollationKey) was suppose to return " + "an exception for a null parameter.");
2944         } catch (Exception e) {
2945         }
2946         try {
2947             ck.merge(ck);
2948             errln("Collationkey.merge(CollationKey) was suppose to return " + "an exception for a null parameter.");
2949         } catch (Exception e) {
2950         }
2951     }
2952
2953     /* Test the method public int compareTo(RawCollationKey rhs) */
2954     public void TestRawCollationKeyCompareTo(){
2955         RawCollationKey rck = new RawCollationKey();
2956         byte[] b = {(byte) 10, (byte) 20};
2957         RawCollationKey rck100 = new RawCollationKey(b, 2);
2958
2959         if(rck.compareTo(rck) != 0){
2960             errln("RawCollatonKey.compareTo(RawCollationKey) was suppose to return 0 " +
2961                     "for two idential RawCollationKey objects.");
2962         }
2963
2964         if(rck.compareTo(rck100) == 0){
2965             errln("RawCollatonKey.compareTo(RawCollationKey) was not suppose to return 0 " +
2966                     "for two different RawCollationKey objects.");
2967         }
2968     }
2969
2970     /* Track7223: CollationElementIterator does not return correct order for Hungarian */
2971     public void TestHungarianTailoring(){
2972         String rules = new String("&DZ<dzs<<<Dzs<<<DZS" +
2973                                   "&G<gy<<<Gy<<<GY" +
2974                                   "&L<ly<<<Ly<<<LY" +
2975                                   "&N<ny<<<Ny<<<NY" +
2976                                   "&S<sz<<<Sz<<<SZ" +
2977                                   "&T<ty<<<Ty<<<TY" +
2978                                   "&Z<zs<<<Zs<<<ZS" +
2979                                   "&O<\u00f6<<<\u00d6<<\u0151<<<\u0150" +
2980                                   "&U<\u00fc<<<\u00dc<<\u0171<<<\u0171" +
2981                                   "&cs<<<ccs/cs" +
2982                                   "&Cs<<<Ccs/cs" +
2983                                   "&CS<<<CCS/CS" +
2984                                   "&dz<<<ddz/dz" +
2985                                   "&Dz<<<Ddz/dz" +
2986                                   "&DZ<<<DDZ/DZ" +
2987                                   "&dzs<<<ddzs/dzs" +
2988                                   "&Dzs<<<Ddzs/dzs" +
2989                                   "&DZS<<<DDZS/DZS" +
2990                                   "&gy<<<ggy/gy" +
2991                                   "&Gy<<<Ggy/gy" +
2992                                   "&GY<<<GGY/GY");
2993         RuleBasedCollator coll;
2994         try {
2995             String str1 = "ggy";
2996             String str2 = "GGY";
2997             coll = new RuleBasedCollator(rules);
2998             if (coll.compare("ggy", "GGY") >= 0) {
2999                   errln("TestHungarianTailoring.compare(" + str1 + ","+ str2 +
3000                         ") was suppose to return -1 ");
3001             }
3002             CollationKey sortKey1 = coll.getCollationKey(str1);
3003             CollationKey sortKey2 = coll.getCollationKey(str2);
3004             if (sortKey1.compareTo(sortKey2) >= 0) {
3005                   errln("TestHungarianTailoring getCollationKey(\"" + str1 +"\") was suppose "+
3006                         "less than getCollationKey(\""+ str2 + "\").");
3007                   errln("  getCollationKey(\"ggy\"):" + prettify(sortKey1) +
3008                         "  getCollationKey(\"GGY\"):" + prettify(sortKey2));
3009             }
3010
3011             CollationElementIterator iter1 = coll.getCollationElementIterator(str1);
3012             CollationElementIterator iter2 = coll.getCollationElementIterator(str2);
3013             int ce1, ce2;
3014             while((ce1 = iter1.next()) != CollationElementIterator.NULLORDER &&
3015                   (ce2 = iter2.next()) != CollationElementIterator.NULLORDER) {
3016                 if (ce1 > ce2) {
3017                   errln("TestHungarianTailoring.CollationElementIterator(" + str1 +
3018                       ","+ str2 + ") was suppose to return -1 ");
3019                 }
3020             }
3021           } catch (Exception e) {
3022               e.printStackTrace();
3023           }
3024      }
3025
3026     public void TestImport(){
3027         try{
3028             RuleBasedCollator vicoll = (RuleBasedCollator)Collator.getInstance(new ULocale("vi"));
3029             RuleBasedCollator escoll = (RuleBasedCollator)Collator.getInstance(new ULocale("es"));
3030             RuleBasedCollator viescoll = new RuleBasedCollator(vicoll.getRules() + escoll.getRules());
3031             RuleBasedCollator importviescoll = new RuleBasedCollator("[import vi][import es]");
3032
3033             UnicodeSet tailoredSet = viescoll.getTailoredSet();
3034             UnicodeSet importTailoredSet = importviescoll.getTailoredSet();
3035
3036             if(!tailoredSet.equals(importTailoredSet)){
3037                 warnln("Tailored set not equal");
3038             }
3039
3040             for (UnicodeSetIterator it = new UnicodeSetIterator(tailoredSet); it.next();) {
3041                 String t = it.getString();
3042                 CollationKey sk1 = viescoll.getCollationKey(t);
3043                 CollationKey sk2 = importviescoll.getCollationKey(t);
3044                 if(!sk1.equals(sk2)){
3045                     warnln("Collation key's not equal for " + t);
3046                 }
3047             }
3048
3049         }catch(Exception e){
3050             warnln("ERROR: in creation of rule based collator");
3051         }
3052     }
3053
3054     public void TestImportWithType(){
3055         try{
3056             RuleBasedCollator vicoll = (RuleBasedCollator)Collator.getInstance(new ULocale("vi"));
3057             RuleBasedCollator decoll = (RuleBasedCollator)Collator.getInstance(ULocale.forLanguageTag("de-u-co-phonebk"));
3058             RuleBasedCollator videcoll = new RuleBasedCollator(vicoll.getRules() + decoll.getRules());
3059             RuleBasedCollator importvidecoll = new RuleBasedCollator("[import vi][import de-u-co-phonebk]");
3060
3061             UnicodeSet tailoredSet = videcoll.getTailoredSet();
3062             UnicodeSet importTailoredSet = importvidecoll.getTailoredSet();
3063
3064             if(!tailoredSet.equals(importTailoredSet)){
3065                 warnln("Tailored set not equal");
3066             }
3067
3068             for (UnicodeSetIterator it = new UnicodeSetIterator(tailoredSet); it.next();) {
3069                 String t = it.getString();
3070                 CollationKey sk1 = videcoll.getCollationKey(t);
3071                 CollationKey sk2 = importvidecoll.getCollationKey(t);
3072                 if(!sk1.equals(sk2)){
3073                     warnln("Collation key's not equal for " + t);
3074                 }
3075             }
3076
3077         }catch(Exception e){
3078             warnln("ERROR: in creation of rule based collator");
3079         }
3080     }
3081
3082     /*
3083      * This test ensures that characters placed before a character in a different script have the same lead byte
3084      * in their collation key before and after script reordering.
3085      */
3086     public void TestBeforeRuleWithScriptReordering() throws Exception
3087     {
3088         /* build collator */
3089         String rules = "&[before 1]\u03b1 < \u0e01";
3090         int[] reorderCodes = {UScript.GREEK};
3091         int result;
3092         
3093         Collator myCollation = new RuleBasedCollator(rules);
3094         myCollation.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
3095         myCollation.setStrength(Collator.TERTIARY);
3096         
3097         String base = "\u03b1"; /* base */
3098         String before = "\u0e01"; /* ko kai */
3099
3100         /* check collation results - before rule applied but not script reordering */
3101         result = myCollation.compare(base, before);
3102         if (!(result > 0)) {
3103             errln("Collation result not correct before script reordering.");
3104         }
3105
3106         /* check the lead byte of the collation keys before script reordering */
3107         CollationKey baseKey = myCollation.getCollationKey(base);
3108         CollationKey beforeKey = myCollation.getCollationKey(before);
3109         byte[] baseKeyBytes = baseKey.toByteArray();
3110         byte[] beforeKeyBytes = beforeKey.toByteArray();
3111         if (baseKeyBytes[0] != beforeKeyBytes[0]) {
3112             errln("Different lead byte for sort keys using before rule and before script reordering. base character lead byte = " 
3113                     + baseKeyBytes[0] + ", before character lead byte = " + beforeKeyBytes[0]);
3114        }
3115
3116         /* reorder the scripts */
3117         myCollation.setReorderCodes(reorderCodes);
3118
3119         /* check collation results - before rule applied and after script reordering */
3120         result = myCollation.compare(base, before);
3121         if (!(result > 0)) {
3122             errln("Collation result not correct after script reordering.");
3123         }
3124         
3125         /* check the lead byte of the collation keys after script reordering */
3126         baseKey = myCollation.getCollationKey(base);
3127         beforeKey = myCollation.getCollationKey(before);
3128         baseKeyBytes = baseKey.toByteArray();
3129         beforeKeyBytes = beforeKey.toByteArray();
3130         if (baseKeyBytes[0] != beforeKeyBytes[0]) {
3131             errln("Different lead byte for sort keys using before rule and before script reordering. base character lead byte = " 
3132                     + baseKeyBytes[0] + ", before character lead byte = " + beforeKeyBytes[0]);
3133        }
3134     }
3135
3136     /*
3137      * Test that in a primary-compressed sort key all bytes except the first one are unchanged under script reordering.
3138      */
3139     public void TestNonLeadBytesDuringCollationReordering() throws Exception
3140     {
3141         Collator myCollation;
3142         byte[] baseKey;
3143         byte[] reorderKey;
3144         int[] reorderCodes = {UScript.GREEK};
3145         String testString = "\u03b1\u03b2\u03b3";
3146
3147         /* build collator tertiary */
3148         myCollation = new RuleBasedCollator("");
3149         myCollation.setStrength(Collator.TERTIARY);
3150         baseKey = myCollation.getCollationKey(testString).toByteArray();
3151
3152         myCollation.setReorderCodes(reorderCodes);
3153         reorderKey = myCollation.getCollationKey(testString).toByteArray();
3154         
3155         if (baseKey.length != reorderKey.length) {
3156             errln("Key lengths not the same during reordering.\n");
3157         }
3158         
3159         for (int i = 1; i < baseKey.length; i++) {
3160             if (baseKey[i] != reorderKey[i]) {
3161                 errln("Collation key bytes not the same at position " + i);
3162             }
3163         } 
3164
3165         /* build collator tertiary */
3166         myCollation = new RuleBasedCollator("");
3167         myCollation.setStrength(Collator.QUATERNARY);
3168         baseKey = myCollation.getCollationKey(testString).toByteArray();
3169
3170         myCollation.setReorderCodes(reorderCodes);
3171         reorderKey = myCollation.getCollationKey(testString).toByteArray();
3172         
3173         if (baseKey.length != reorderKey.length) {
3174             errln("Key lengths not the same during reordering.\n");
3175         }
3176         
3177         for (int i = 1; i < baseKey.length; i++) {
3178             if (baseKey[i] != reorderKey[i]) {
3179                 errln("Collation key bytes not the same at position " + i);
3180             }
3181         } 
3182     }
3183
3184     /*
3185      * Test reordering API.
3186      */
3187     public void TestReorderingAPI() throws Exception
3188     {
3189         Collator myCollation;
3190         int[] reorderCodes = {UScript.GREEK, UScript.HAN, ReorderCodes.PUNCTUATION};
3191         int[] duplicateReorderCodes = {UScript.CUNEIFORM, UScript.GREEK, ReorderCodes.CURRENCY, UScript.EGYPTIAN_HIEROGLYPHS};
3192         int[] reorderCodesStartingWithDefault = {ReorderCodes.DEFAULT, UScript.GREEK, UScript.HAN, ReorderCodes.PUNCTUATION};
3193         int[] retrievedReorderCodes;
3194         String greekString = "\u03b1";
3195         String punctuationString = "\u203e";
3196
3197         /* build collator tertiary */
3198         myCollation = new RuleBasedCollator("");
3199         myCollation.setStrength(Collator.TERTIARY);
3200
3201         /* set the reorderding */
3202         myCollation.setReorderCodes(reorderCodes);
3203         
3204         retrievedReorderCodes = myCollation.getReorderCodes();
3205         if (!Arrays.equals(reorderCodes, retrievedReorderCodes)) {
3206             errln("ERROR: retrieved reorder codes do not match set reorder codes.");
3207         }
3208         if (!(myCollation.compare(greekString, punctuationString) < 0)) {
3209             errln("ERROR: collation result should have been less.");
3210         }
3211         
3212         /* clear the reordering */
3213         myCollation.setReorderCodes(null);    
3214         retrievedReorderCodes = myCollation.getReorderCodes();
3215         if (retrievedReorderCodes.length != 0) {
3216             errln("ERROR: retrieved reorder codes was not null.");
3217         }
3218
3219         if (!(myCollation.compare(greekString, punctuationString) > 0)) {
3220             errln("ERROR: collation result should have been greater.");
3221         }
3222         
3223         // do it again with an empty but non-null array
3224         
3225         /* set the reorderding */
3226         myCollation.setReorderCodes(reorderCodes);
3227         
3228         retrievedReorderCodes = myCollation.getReorderCodes();
3229         if (!Arrays.equals(reorderCodes, retrievedReorderCodes)) {
3230             errln("ERROR: retrieved reorder codes do not match set reorder codes.");
3231         }
3232         if (!(myCollation.compare(greekString, punctuationString) < 0)) {
3233             errln("ERROR: collation result should have been less.");
3234         }
3235         
3236         /* clear the reordering */
3237         myCollation.setReorderCodes(new int[]{});    
3238         retrievedReorderCodes = myCollation.getReorderCodes();
3239         if (retrievedReorderCodes.length != 0) {
3240             errln("ERROR: retrieved reorder codes was not null.");
3241         }
3242
3243         if (!(myCollation.compare(greekString, punctuationString) > 0)) {
3244             errln("ERROR: collation result should have been greater.");
3245         }
3246         
3247         boolean gotException = false;
3248         /* set duplicates in the reorder codes */
3249         try {
3250             myCollation.setReorderCodes(duplicateReorderCodes);
3251         } catch (IllegalArgumentException e) {
3252             // expect exception on illegal arguments
3253             gotException = true;
3254         }
3255         if (!gotException) {
3256             errln("ERROR: exception was not thrown for illegal reorder codes argument.");            
3257         }
3258         
3259         /* set duplicate reorder codes */
3260         gotException = false;
3261         try {
3262             myCollation.setReorderCodes(reorderCodesStartingWithDefault);
3263         } catch (IllegalArgumentException e) {
3264             gotException = true;
3265         }
3266         if (!gotException) {
3267             errln("ERROR: reorder codes following a 'default' code should have thrown an exception but did not.");            
3268         }
3269     }
3270     
3271     /*
3272      * Test reordering API.
3273      */
3274     public void TestReorderingAPIWithRuleCreatedCollator() throws Exception
3275     {
3276         Collator myCollation;
3277         String rules = "[reorder Hani Grek]";
3278         int[] rulesReorderCodes = {UScript.HAN, UScript.GREEK};
3279         int[] reorderCodes = {UScript.GREEK, UScript.HAN, ReorderCodes.PUNCTUATION};
3280         int[] retrievedReorderCodes;
3281
3282         
3283         /* build collator tertiary */
3284         myCollation = new RuleBasedCollator(rules);
3285         myCollation.setStrength(Collator.TERTIARY);
3286
3287         retrievedReorderCodes = myCollation.getReorderCodes();
3288         if (!Arrays.equals(rulesReorderCodes, retrievedReorderCodes)) {
3289             errln("ERROR: retrieved reorder codes do not match set reorder codes.");
3290         }
3291         
3292         /* clear the reordering */
3293         myCollation.setReorderCodes(null);    
3294         retrievedReorderCodes = myCollation.getReorderCodes();
3295         if (retrievedReorderCodes.length != 0) {
3296             errln("ERROR: retrieved reorder codes was not null.");
3297         }
3298
3299         /* set the reorderding */
3300         myCollation.setReorderCodes(reorderCodes);
3301         
3302         retrievedReorderCodes = myCollation.getReorderCodes();
3303         if (!Arrays.equals(reorderCodes, retrievedReorderCodes)) {
3304             errln("ERROR: retrieved reorder codes do not match set reorder codes.");
3305         }
3306         
3307         /* reset the reordering */
3308         myCollation.setReorderCodes(ReorderCodes.DEFAULT);    
3309         retrievedReorderCodes = myCollation.getReorderCodes();
3310         if (!Arrays.equals(rulesReorderCodes, retrievedReorderCodes)) {
3311             errln("ERROR: retrieved reorder codes do not match set reorder codes.");
3312         }
3313     }
3314     
3315     public void TestSameLeadBytScriptReorder(){
3316         String[] testSourceCases = {
3317                 "\ud800\udf31", // Gothic
3318                 "\ud801\udc50", // Shavian
3319         };
3320
3321         String[] testTargetCases = {
3322                 "\u0100",   // Latin Extended-A
3323                 "\u2c74",   // Latin Extended-C
3324         };
3325
3326         int[] results = {
3327                 -1,
3328                 -1,
3329         };
3330
3331         Collator  myCollation;
3332         String rules = "[reorder Goth Latn]";
3333         try {
3334             myCollation = new RuleBasedCollator(rules);
3335         } catch (Exception e) {
3336             warnln("ERROR: in creation of rule based collator");
3337             return;
3338         }
3339         myCollation.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
3340         myCollation.setStrength(Collator.TERTIARY);
3341         for (int i = 0; i < testSourceCases.length ; i++)
3342         {
3343             CollationTest.doTest(this, (RuleBasedCollator)myCollation, 
3344                     testSourceCases[i], testTargetCases[i], 
3345                     results[i]);
3346         }
3347
3348         // ensure that the non-reordered and reordered collation is the same
3349         Collator nonReorderdCollator = RuleBasedCollator.getInstance();
3350         int nonReorderedResults = nonReorderdCollator.compare(testSourceCases[0], testSourceCases[1]);
3351         CollationTest.doTest(this, (RuleBasedCollator)myCollation, 
3352                 testSourceCases[0], testSourceCases[1], nonReorderedResults);   
3353      }
3354     
3355     public void TestEquivalentReorderingScripts() {
3356         int[] equivalentScriptsResult = {
3357                 UScript.BOPOMOFO,               //Bopo
3358                 UScript.LISU,                   //Lisu
3359                 UScript.LYCIAN,                 //Lyci
3360                 UScript.CARIAN,                 //Cari
3361                 UScript.LYDIAN,                 //Lydi
3362                 UScript.YI,                     //Yiii
3363                 UScript.OLD_ITALIC,             //Ital
3364                 UScript.GOTHIC,                 //Goth
3365                 UScript.DESERET,                //Dsrt
3366                 UScript.SHAVIAN,                //Shaw
3367                 UScript.OSMANYA,                //Osma
3368                 UScript.LINEAR_B,               //Linb
3369                 UScript.CYPRIOT,                //Cprt
3370                 UScript.OLD_SOUTH_ARABIAN,      //Sarb
3371                 UScript.AVESTAN,                //Avst
3372                 UScript.IMPERIAL_ARAMAIC,       //Armi
3373                 UScript.INSCRIPTIONAL_PARTHIAN, //Prti
3374                 UScript.INSCRIPTIONAL_PAHLAVI,  //Phli
3375                 UScript.UGARITIC,               //Ugar
3376                 UScript.OLD_PERSIAN,            //Xpeo
3377                 UScript.CUNEIFORM,              //Xsux
3378                 UScript.EGYPTIAN_HIEROGLYPHS,   //Egyp
3379                 UScript.PHONETIC_POLLARD,       //Plrd
3380                 UScript.SORA_SOMPENG,           //Sora
3381                 UScript.MEROITIC_CURSIVE,       //Merc
3382                 UScript.MEROITIC_HIEROGLYPHS    //Mero
3383         };
3384         Arrays.sort(equivalentScriptsResult);
3385         
3386         int[] equivalentScripts = RuleBasedCollator.getEquivalentReorderCodes(UScript.GOTHIC);
3387         Arrays.sort(equivalentScripts);
3388         boolean equal = Arrays.equals(equivalentScripts, equivalentScriptsResult);
3389         assertTrue("Script Equivalents for Reordering", equal);
3390         if (!equal) {
3391             StringBuilder s = new StringBuilder("    {");
3392             for (int code : equivalentScripts) {
3393                 s.append(" " + UCharacter.getPropertyValueName(UProperty.SCRIPT, code, UProperty.NameChoice.SHORT));
3394             }
3395             s.append(" } vs. {");
3396             for (int code : equivalentScriptsResult) {
3397                 s.append(" " + UCharacter.getPropertyValueName(UProperty.SCRIPT, code, UProperty.NameChoice.SHORT));
3398             }
3399             s.append(" }");
3400             errln(s.toString());
3401         }
3402
3403         equivalentScripts = RuleBasedCollator.getEquivalentReorderCodes(UScript.SHAVIAN);
3404         Arrays.sort(equivalentScripts);
3405         assertTrue("Script Equivalents for Reordering", Arrays.equals(equivalentScripts, equivalentScriptsResult));
3406     }
3407     
3408     public void TestGreekFirstReorderCloning() {
3409         String[] testSourceCases = {
3410             "\u0041",
3411             "\u03b1\u0041",
3412             "\u0061",
3413             "\u0041\u0061",
3414             "\u0391",
3415         };
3416
3417         String[] testTargetCases = {
3418             "\u03b1",
3419             "\u0041\u03b1",
3420             "\u0391",
3421             "\u0391\u03b1",
3422             "\u0391",
3423         };
3424
3425         int[] results = {
3426             1,
3427             -1,
3428             1,
3429             1,
3430             0
3431         };
3432
3433         Collator  originalCollation;
3434         Collator  myCollation;
3435         String rules = "[reorder Grek]";
3436         try {
3437             originalCollation = new RuleBasedCollator(rules);
3438         } catch (Exception e) {
3439             warnln("ERROR: in creation of rule based collator");
3440             return;
3441         }
3442         try {
3443             myCollation = (Collator) originalCollation.clone();
3444         } catch (Exception e) {
3445             warnln("ERROR: in creation of rule based collator");
3446             return;
3447         }
3448         myCollation.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
3449         myCollation.setStrength(Collator.TERTIARY);
3450         for (int i = 0; i < testSourceCases.length ; i++)
3451         {
3452             CollationTest.doTest(this, (RuleBasedCollator)myCollation, 
3453                                  testSourceCases[i], testTargetCases[i], 
3454                                  results[i]);
3455         }
3456     }
3457
3458     /*
3459      * Utility function to test one collation reordering test case.
3460      * @param testcases Array of test cases.
3461      * @param n_testcases Size of the array testcases.
3462      * @param str_rules Array of rules.  These rules should be specifying the same rule in different formats.
3463      * @param n_rules Size of the array str_rules.
3464      */
3465     private void doTestOneReorderingAPITestCase(OneTestCase testCases[], int reorderTokens[])
3466     {
3467         Collator myCollation = Collator.getInstance(ULocale.ENGLISH);
3468         myCollation.setReorderCodes(reorderTokens);
3469         
3470         for (OneTestCase testCase : testCases) {
3471             CollationTest.doTest(this, (RuleBasedCollator)myCollation,
3472                     testCase.m_source_,
3473                     testCase.m_target_,
3474                     testCase.m_result_);
3475         }
3476     }
3477
3478     public void TestGreekFirstReorder()
3479     {
3480         String[] strRules = {
3481             "[reorder Grek]"
3482         };
3483
3484         int[] apiRules = {
3485             UScript.GREEK
3486         };
3487         
3488         OneTestCase[] privateUseCharacterStrings = {
3489             new OneTestCase("\u0391", "\u0391", 0),
3490             new OneTestCase("\u0041", "\u0391", 1),
3491             new OneTestCase("\u03B1\u0041", "\u03B1\u0391", 1),
3492             new OneTestCase("\u0060", "\u0391", -1),
3493             new OneTestCase("\u0391", "\ue2dc", -1),
3494             new OneTestCase("\u0391", "\u0060", 1),
3495         };
3496
3497         /* Test rules creation */
3498         doTestCollation(privateUseCharacterStrings, strRules);
3499
3500         /* Test collation reordering API */
3501         doTestOneReorderingAPITestCase(privateUseCharacterStrings, apiRules);
3502     }
3503
3504     public void TestGreekLastReorder()
3505     {
3506         String[] strRules = {
3507             "[reorder Zzzz Grek]"
3508         };
3509
3510         int[] apiRules = {
3511             UScript.UNKNOWN, UScript.GREEK
3512         };
3513         
3514         OneTestCase[] privateUseCharacterStrings = {
3515             new OneTestCase("\u0391", "\u0391", 0),
3516             new OneTestCase("\u0041", "\u0391", -1),
3517             new OneTestCase("\u03B1\u0041", "\u03B1\u0391", -1),
3518             new OneTestCase("\u0060", "\u0391", -1),
3519             new OneTestCase("\u0391", "\ue2dc", 1),
3520         };
3521         
3522         /* Test rules creation */
3523         doTestCollation(privateUseCharacterStrings, strRules);
3524
3525         /* Test collation reordering API */
3526         doTestOneReorderingAPITestCase(privateUseCharacterStrings, apiRules);
3527     }
3528
3529     public void TestNonScriptReorder()
3530     {
3531         String[] strRules = {
3532             "[reorder Grek Symbol DIGIT Latn Punct space Zzzz cURRENCy]"
3533         };
3534
3535         int[] apiRules = {
3536             UScript.GREEK, ReorderCodes.SYMBOL, ReorderCodes.DIGIT, UScript.LATIN,
3537             ReorderCodes.PUNCTUATION, ReorderCodes.SPACE, UScript.UNKNOWN,
3538             ReorderCodes.CURRENCY
3539         };
3540
3541         OneTestCase[] privateUseCharacterStrings = {
3542             new OneTestCase("\u0391", "\u0041", -1),
3543             new OneTestCase("\u0041", "\u0391", 1),
3544             new OneTestCase("\u0060", "\u0041", -1),
3545             new OneTestCase("\u0060", "\u0391", 1),
3546             new OneTestCase("\u0024", "\u0041", 1),
3547         };
3548         
3549         /* Test rules creation */
3550         doTestCollation(privateUseCharacterStrings, strRules);
3551
3552         /* Test collation reordering API */
3553         doTestOneReorderingAPITestCase(privateUseCharacterStrings, apiRules);
3554     }
3555
3556     public void TestHaniReorder()
3557     {
3558         String[] strRules = {
3559             "[reorder Hani]"
3560         };
3561         int[] apiRules = {
3562             UScript.HAN
3563         };
3564
3565         OneTestCase[] privateUseCharacterStrings = {
3566             new OneTestCase("\u4e00", "\u0041", -1),
3567             new OneTestCase("\u4e00", "\u0060", 1),
3568             new OneTestCase("\uD86D\uDF40", "\u0041", -1),
3569             new OneTestCase("\uD86D\uDF40", "\u0060", 1),
3570             new OneTestCase("\u4e00", "\uD86D\uDF40", -1),
3571             new OneTestCase("\ufa27", "\u0041", -1),
3572             new OneTestCase("\uD869\uDF00", "\u0041", -1),
3573         };
3574         
3575         /* Test rules creation */
3576         doTestCollation(privateUseCharacterStrings, strRules);
3577
3578         /* Test collation reordering API */
3579         doTestOneReorderingAPITestCase(privateUseCharacterStrings, apiRules);
3580     }
3581     
3582     public void TestHaniReorderWithOtherRules()
3583     {
3584         String[] strRules = {
3585             "[reorder Hani]  &b<a"
3586         };
3587
3588         OneTestCase[] privateUseCharacterStrings = {
3589             new OneTestCase("\u4e00", "\u0041", -1),
3590             new OneTestCase("\u4e00", "\u0060", 1),
3591             new OneTestCase("\uD86D\uDF40", "\u0041", -1),
3592             new OneTestCase("\uD86D\uDF40", "\u0060", 1),
3593             new OneTestCase("\u4e00", "\uD86D\uDF40", -1),
3594             new OneTestCase("\ufa27", "\u0041", -1),
3595             new OneTestCase("\uD869\uDF00", "\u0041", -1),
3596             new OneTestCase("b", "a", -1),
3597         };
3598         
3599         /* Test rules creation */
3600         doTestCollation(privateUseCharacterStrings, strRules);
3601     }
3602     
3603     public void TestMultipleReorder()
3604     {
3605         String[] strRules = {
3606             "[reorder Grek Zzzz DIGIT Latn Hani]"
3607         };
3608
3609         int[] apiRules = {
3610             UScript.GREEK, UScript.UNKNOWN, ReorderCodes.DIGIT, UScript.LATIN, UScript.HAN
3611         };
3612         
3613         OneTestCase[] collationTestCases = {
3614             new OneTestCase("\u0391", "\u0041", -1),
3615             new OneTestCase("\u0031", "\u0041", -1),
3616             new OneTestCase("u0041", "\u4e00", -1),
3617         };
3618
3619         /* Test rules creation */
3620         doTestCollation(collationTestCases, strRules);
3621
3622         /* Test collation reordering API */
3623         doTestOneReorderingAPITestCase(collationTestCases, apiRules);
3624     }
3625     
3626     public void TestFrozeness()
3627     {
3628         Collator myCollation = Collator.getInstance(ULocale.CANADA);
3629         boolean exceptionCaught = false;
3630         
3631         myCollation.freeze();
3632         assertTrue("Collator not frozen.", myCollation.isFrozen());
3633
3634         try {
3635             myCollation.setStrength(Collator.SECONDARY);
3636         } catch (UnsupportedOperationException e) {
3637             // expected
3638             exceptionCaught = true;
3639         }
3640         assertTrue("Frozen collator allowed change.", exceptionCaught);
3641         exceptionCaught = false;
3642         
3643         try {
3644             myCollation.setReorderCodes(ReorderCodes.DEFAULT);
3645         } catch (UnsupportedOperationException e) {
3646             // expected
3647             exceptionCaught = true;
3648         }
3649         assertTrue("Frozen collator allowed change.", exceptionCaught);
3650         exceptionCaught = false;
3651         
3652         try {
3653             myCollation.setVariableTop(12);
3654         } catch (UnsupportedOperationException e) {
3655             // expected
3656             exceptionCaught = true;
3657         }
3658         assertTrue("Frozen collator allowed change.", exceptionCaught);
3659         exceptionCaught = false;
3660         
3661         Collator myClone = null;
3662         try {
3663             myClone = (Collator) myCollation.clone();
3664         } catch (CloneNotSupportedException e) {
3665             // should not happen - clone is implemented in Collator
3666             errln("ERROR: unable to clone collator.");
3667         }
3668         assertTrue("Clone not frozen as expected.", myClone.isFrozen());
3669         
3670         myClone = myClone.cloneAsThawed();
3671         assertFalse("Clone not thawed as expected.", myClone.isFrozen());        
3672     }
3673
3674     // Test case for Ticket#9409
3675     // Unknown collation type should be ignored, without printing stack trace
3676     public void TestUnknownCollationKeyword() {
3677         Collator coll1 = Collator.getInstance(new ULocale("en_US@collation=bogus"));
3678         Collator coll2 = Collator.getInstance(new ULocale("en_US"));
3679         assertEquals("Unknown collation keyword 'bogus' should be ignored", coll1, coll2);
3680     }
3681 }