UCharacterTest.java revision 7935b1839a081ed19ae0d33029ad3c09632a2caa
1/**
2*******************************************************************************
3* Copyright (C) 1996-2014, International Business Machines Corporation and
4* others. All Rights Reserved.
5*******************************************************************************
6*/
7
8package com.ibm.icu.dev.test.lang;
9
10import java.io.BufferedReader;
11import java.util.Arrays;
12import java.util.Locale;
13
14import com.ibm.icu.dev.test.TestFmwk;
15import com.ibm.icu.dev.test.TestUtil;
16import com.ibm.icu.impl.Norm2AllModes;
17import com.ibm.icu.impl.Normalizer2Impl;
18import com.ibm.icu.impl.PatternProps;
19import com.ibm.icu.impl.UCharacterName;
20import com.ibm.icu.impl.Utility;
21import com.ibm.icu.lang.UCharacter;
22import com.ibm.icu.lang.UCharacterCategory;
23import com.ibm.icu.lang.UCharacterDirection;
24import com.ibm.icu.lang.UCharacterEnums;
25import com.ibm.icu.lang.UProperty;
26import com.ibm.icu.lang.UScript;
27import com.ibm.icu.text.Normalizer2;
28import com.ibm.icu.text.UTF16;
29import com.ibm.icu.text.UnicodeSet;
30import com.ibm.icu.text.UnicodeSetIterator;
31import com.ibm.icu.util.RangeValueIterator;
32import com.ibm.icu.util.ULocale;
33import com.ibm.icu.util.ValueIterator;
34import com.ibm.icu.util.VersionInfo;
35
36/**
37* Testing class for UCharacter
38* Mostly following the test cases for ICU
39* @author Syn Wee Quek
40* @since nov 04 2000
41*/
42public final class UCharacterTest extends TestFmwk
43{
44    // private variables =============================================
45
46    /**
47    * ICU4J data version number
48    */
49    private final VersionInfo VERSION_ = VersionInfo.getInstance("7.0.0.0");
50
51    // constructor ===================================================
52
53    /**
54    * Constructor
55    */
56    public UCharacterTest()
57    {
58    }
59
60    // public methods ================================================
61
62    public static void main(String[] arg)
63    {
64        try
65        {
66            UCharacterTest test = new UCharacterTest();
67            test.run(arg);
68        }
69        catch (Exception e)
70        {
71        e.printStackTrace();
72        }
73    }
74
75    /**
76    * Testing the letter and number determination in UCharacter
77    */
78    public void TestLetterNumber()
79    {
80        for (int i = 0x0041; i < 0x005B; i ++)
81        if (!UCharacter.isLetter(i))
82            errln("FAIL \\u" + hex(i) + " expected to be a letter");
83
84        for (int i = 0x0660; i < 0x066A; i ++)
85        if (UCharacter.isLetter(i))
86            errln("FAIL \\u" + hex(i) + " expected not to be a letter");
87
88        for (int i = 0x0660; i < 0x066A; i ++)
89        if (!UCharacter.isDigit(i))
90            errln("FAIL \\u" + hex(i) + " expected to be a digit");
91
92        for (int i = 0x0041; i < 0x005B; i ++)
93            if (!UCharacter.isLetterOrDigit(i))
94                errln("FAIL \\u" + hex(i) + " expected not to be a digit");
95
96        for (int i = 0x0660; i < 0x066A; i ++)
97            if (!UCharacter.isLetterOrDigit(i))
98                errln("FAIL \\u" + hex(i) +
99                    "expected to be either a letter or a digit");
100
101        /*
102         * The following checks work only starting from Unicode 4.0.
103         * Check the version number here.
104         */
105        VersionInfo version =    UCharacter.getUnicodeVersion();
106        if(version.getMajor()<4 || version.equals(VersionInfo.getInstance(4, 0, 1))) {
107            return;
108        }
109
110
111
112        /*
113         * Sanity check:
114         * Verify that exactly the digit characters have decimal digit values.
115         * This assumption is used in the implementation of u_digit()
116         * (which checks nt=de)
117         * compared with the parallel java.lang.Character.digit()
118         * (which checks Nd).
119         *
120         * This was not true in Unicode 3.2 and earlier.
121         * Unicode 4.0 fixed discrepancies.
122         * Unicode 4.0.1 re-introduced problems in this area due to an
123         * unintentionally incomplete last-minute change.
124         */
125        String digitsPattern = "[:Nd:]";
126        String decimalValuesPattern = "[:Numeric_Type=Decimal:]";
127
128        UnicodeSet digits, decimalValues;
129
130        digits= new UnicodeSet(digitsPattern);
131        decimalValues=new UnicodeSet(decimalValuesPattern);
132
133
134        compareUSets(digits, decimalValues, "[:Nd:]", "[:Numeric_Type=Decimal:]", true);
135
136
137    }
138
139    /**
140    * Tests for space determination in UCharacter
141    */
142    public void TestSpaces()
143    {
144        int spaces[] = {0x0020, 0x00a0, 0x2000, 0x2001, 0x2005};
145        int nonspaces[] = {0x0061, 0x0062, 0x0063, 0x0064, 0x0074};
146        int whitespaces[] = {0x2008, 0x2009, 0x200a, 0x001c, 0x000c /* ,0x200b */}; // 0x200b was "Zs" in Unicode 4.0, but it is "Cf" in Unicode 4.1
147        int nonwhitespaces[] = {0x0061, 0x0062, 0x003c, 0x0028, 0x003f, 0x00a0, 0x2007, 0x202f, 0xfefe, 0x200b};
148
149        int size = spaces.length;
150        for (int i = 0; i < size; i ++)
151        {
152            if (!UCharacter.isSpaceChar(spaces[i]))
153            {
154                errln("FAIL \\u" + hex(spaces[i]) +
155                    " expected to be a space character");
156                break;
157            }
158
159            if (UCharacter.isSpaceChar(nonspaces[i]))
160            {
161                errln("FAIL \\u" + hex(nonspaces[i]) +
162                " expected not to be space character");
163                break;
164            }
165
166            if (!UCharacter.isWhitespace(whitespaces[i]))
167            {
168                errln("FAIL \\u" + hex(whitespaces[i]) +
169                        " expected to be a white space character");
170                break;
171            }
172            if (UCharacter.isWhitespace(nonwhitespaces[i]))
173            {
174                errln("FAIL \\u" + hex(nonwhitespaces[i]) +
175                            " expected not to be a space character");
176                break;
177            }
178            logln("Ok    \\u" + hex(spaces[i]) + " and \\u" +
179                  hex(nonspaces[i]) + " and \\u" + hex(whitespaces[i]) +
180                  " and \\u" + hex(nonwhitespaces[i]));
181        }
182
183        int patternWhiteSpace[] = {0x9, 0xd, 0x20, 0x85,
184                                0x200e, 0x200f, 0x2028, 0x2029};
185        int nonPatternWhiteSpace[] = {0x8, 0xe, 0x21, 0x86, 0xa0, 0xa1,
186                                   0x1680, 0x1681, 0x180e, 0x180f,
187                                   0x1FFF, 0x2000, 0x200a, 0x200b,
188                                   0x2010, 0x202f, 0x2030, 0x205f,
189                                   0x2060, 0x3000, 0x3001};
190        for (int i = 0; i < patternWhiteSpace.length; i ++) {
191            if (!PatternProps.isWhiteSpace(patternWhiteSpace[i])) {
192                errln("\\u" + Utility.hex(patternWhiteSpace[i], 4)
193                      + " expected to be a Pattern_White_Space");
194            }
195        }
196        for (int i = 0; i < nonPatternWhiteSpace.length; i ++) {
197            if (PatternProps.isWhiteSpace(nonPatternWhiteSpace[i])) {
198                errln("\\u" + Utility.hex(nonPatternWhiteSpace[i], 4)
199                      + " expected to be a non-Pattern_White_Space");
200            }
201        }
202
203        // TODO: propose public API for constants like uchar.h's U_GC_*_MASK
204        // (http://bugs.icu-project.org/trac/ticket/7461)
205        int GC_Z_MASK =
206            (1 << UCharacter.SPACE_SEPARATOR) |
207            (1 << UCharacter.LINE_SEPARATOR) |
208            (1 << UCharacter.PARAGRAPH_SEPARATOR);
209
210        // UCharacter.isWhitespace(c) should be the same as Character.isWhitespace().
211        // This uses logln() because Character.isWhitespace() differs between Java versions, thus
212        // it is not necessarily an error if there is a difference between
213        // particular Java and ICU versions.
214        // However, you need to run tests with -v to see the output.
215        // Also note that, at least as of Unicode 5.2,
216        // there are no supplementary white space characters.
217        for (int c = 0; c <= 0xffff; ++c) {
218            boolean j = Character.isWhitespace(c);
219            boolean i = UCharacter.isWhitespace(c);
220            boolean u = UCharacter.isUWhiteSpace(c);
221            boolean z = (UCharacter.getIntPropertyValue(c, UProperty.GENERAL_CATEGORY_MASK) &
222                         GC_Z_MASK) != 0;
223            if (j != i) {
224                logln(String.format(
225                    "isWhitespace(U+%04x) difference: JDK %5b ICU %5b Unicode WS %5b Z Separator %5b",
226                    c, j, i, u, z));
227            } else if (j || i || u || z) {
228                logln(String.format(
229                    "isWhitespace(U+%04x) FYI:        JDK %5b ICU %5b Unicode WS %5b Z Separator %5b",
230                    c, j, i, u, z));
231            }
232        }
233        for (char c = 0; c <= 0xff; ++c) {
234            boolean j = Character.isSpace(c);
235            boolean i = UCharacter.isSpace(c);
236            boolean z = (UCharacter.getIntPropertyValue(c, UProperty.GENERAL_CATEGORY_MASK) &
237                         GC_Z_MASK) != 0;
238            if (j != i) {
239                logln(String.format(
240                    "isSpace(U+%04x) difference: JDK %5b ICU %5b Z Separator %5b",
241                    (int)c, j, i, z));
242            } else if (j || i || z) {
243                logln(String.format(
244                    "isSpace(U+%04x) FYI:        JDK %5b ICU %5b Z Separator %5b",
245                    (int)c, j, i, z));
246            }
247        }
248    }
249
250    /**
251     * Test various implementations of Pattern_Syntax & Pattern_White_Space.
252     */
253    public void TestPatternProperties() {
254        UnicodeSet syn_pp = new UnicodeSet();
255        UnicodeSet syn_prop = new UnicodeSet("[:Pattern_Syntax:]");
256        UnicodeSet syn_list = new UnicodeSet(
257            "[!-/\\:-@\\[-\\^`\\{-~"+
258            "\u00A1-\u00A7\u00A9\u00AB\u00AC\u00AE\u00B0\u00B1\u00B6\u00BB\u00BF\u00D7\u00F7"+
259            "\u2010-\u2027\u2030-\u203E\u2041-\u2053\u2055-\u205E\u2190-\u245F\u2500-\u2775"+
260            "\u2794-\u2BFF\u2E00-\u2E7F\u3001-\u3003\u3008-\u3020\u3030\uFD3E\uFD3F\uFE45\uFE46]");
261        UnicodeSet ws_pp = new UnicodeSet();
262        UnicodeSet ws_prop = new UnicodeSet("[:Pattern_White_Space:]");
263        UnicodeSet ws_list = new UnicodeSet("[\\u0009-\\u000D\\ \\u0085\\u200E\\u200F\\u2028\\u2029]");
264        UnicodeSet syn_ws_pp = new UnicodeSet();
265        UnicodeSet syn_ws_prop = new UnicodeSet(syn_prop).addAll(ws_prop);
266        for(int c=0; c<=0xffff; ++c) {
267            if(PatternProps.isSyntax(c)) {
268                syn_pp.add(c);
269            }
270            if(PatternProps.isWhiteSpace(c)) {
271                ws_pp.add(c);
272            }
273            if(PatternProps.isSyntaxOrWhiteSpace(c)) {
274                syn_ws_pp.add(c);
275            }
276        }
277        compareUSets(syn_pp, syn_prop,
278                     "PatternProps.isSyntax()", "[:Pattern_Syntax:]", true);
279        compareUSets(syn_pp, syn_list,
280                     "PatternProps.isSyntax()", "[Pattern_Syntax ranges]", true);
281        compareUSets(ws_pp, ws_prop,
282                     "PatternProps.isWhiteSpace()", "[:Pattern_White_Space:]", true);
283        compareUSets(ws_pp, ws_list,
284                     "PatternProps.isWhiteSpace()", "[Pattern_White_Space ranges]", true);
285        compareUSets(syn_ws_pp, syn_ws_prop,
286                     "PatternProps.isSyntaxOrWhiteSpace()",
287                     "[[:Pattern_Syntax:][:Pattern_White_Space:]]", true);
288    }
289
290    /**
291    * Tests for defined and undefined characters
292    */
293    public void TestDefined()
294    {
295        int undefined[] = {0xfff1, 0xfff7, 0xfa6e};
296        int defined[] = {0x523E, 0x004f88, 0x00fffd};
297
298        int size = undefined.length;
299        for (int i = 0; i < size; i ++)
300        {
301            if (UCharacter.isDefined(undefined[i]))
302            {
303                errln("FAIL \\u" + hex(undefined[i]) +
304                            " expected not to be defined");
305                break;
306            }
307            if (!UCharacter.isDefined(defined[i]))
308            {
309                errln("FAIL \\u" + hex(defined[i]) + " expected defined");
310                break;
311            }
312        }
313    }
314
315    /**
316    * Tests for base characters and their cellwidth
317    */
318    public void TestBase()
319    {
320        int base[] = {0x0061, 0x000031, 0x0003d2};
321        int nonbase[] = {0x002B, 0x000020, 0x00203B};
322        int size = base.length;
323        for (int i = 0; i < size; i ++)
324        {
325            if (UCharacter.isBaseForm(nonbase[i]))
326            {
327                errln("FAIL \\u" + hex(nonbase[i]) +
328                            " expected not to be a base character");
329                break;
330            }
331            if (!UCharacter.isBaseForm(base[i]))
332            {
333                errln("FAIL \\u" + hex(base[i]) +
334                      " expected to be a base character");
335                break;
336            }
337        }
338    }
339
340    /**
341    * Tests for digit characters
342    */
343    public void TestDigits()
344    {
345        int digits[] = {0x0030, 0x000662, 0x000F23, 0x000ED5, 0x002160};
346
347        //special characters not in the properties table
348        int digits2[] = {0x3007, 0x004e00, 0x004e8c, 0x004e09, 0x0056d8,
349                         0x004e94, 0x00516d, 0x4e03, 0x00516b, 0x004e5d};
350        int nondigits[] = {0x0010, 0x000041, 0x000122, 0x0068FE};
351
352        int digitvalues[] = {0, 2, 3, 5, 1};
353        int digitvalues2[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
354
355        int size  = digits.length;
356        for (int i = 0; i < size; i ++) {
357            if (UCharacter.isDigit(digits[i]) &&
358                UCharacter.digit(digits[i]) != digitvalues[i])
359            {
360                errln("FAIL \\u" + hex(digits[i]) +
361                        " expected digit with value " + digitvalues[i]);
362                break;
363            }
364        }
365        size = nondigits.length;
366        for (int i = 0; i < size; i ++)
367            if (UCharacter.isDigit(nondigits[i]))
368            {
369                errln("FAIL \\u" + hex(nondigits[i]) + " expected nondigit");
370                break;
371            }
372
373        size = digits2.length;
374        for (int i = 0; i < 10; i ++) {
375            if (UCharacter.isDigit(digits2[i]) &&
376                UCharacter.digit(digits2[i]) != digitvalues2[i])
377            {
378                errln("FAIL \\u" + hex(digits2[i]) +
379                    " expected digit with value " + digitvalues2[i]);
380                break;
381            }
382        }
383    }
384
385    /**
386    *  Tests for numeric characters
387    */
388    public void TestNumeric()
389    {
390        if (UCharacter.getNumericValue(0x00BC) != -2) {
391            errln("Numeric value of 0x00BC expected to be -2");
392        }
393
394        for (int i = '0'; i < '9'; i ++) {
395            int n1 = UCharacter.getNumericValue(i);
396            double n2 = UCharacter.getUnicodeNumericValue(i);
397            if (n1 != n2 ||  n1 != (i - '0')) {
398                errln("Numeric value of " + (char)i + " expected to be " +
399                      (i - '0'));
400            }
401        }
402        for (int i = 'A'; i < 'F'; i ++) {
403            int n1 = UCharacter.getNumericValue(i);
404            double n2 = UCharacter.getUnicodeNumericValue(i);
405            if (n2 != UCharacter.NO_NUMERIC_VALUE ||  n1 != (i - 'A' + 10)) {
406                errln("Numeric value of " + (char)i + " expected to be " +
407                      (i - 'A' + 10));
408            }
409        }
410        for (int i = 0xFF21; i < 0xFF26; i ++) {
411            // testing full wideth latin characters A-F
412            int n1 = UCharacter.getNumericValue(i);
413            double n2 = UCharacter.getUnicodeNumericValue(i);
414            if (n2 != UCharacter.NO_NUMERIC_VALUE ||  n1 != (i - 0xFF21 + 10)) {
415                errln("Numeric value of " + (char)i + " expected to be " +
416                      (i - 0xFF21 + 10));
417            }
418        }
419        // testing han numbers
420        int han[] = {0x96f6, 0, 0x58f9, 1, 0x8cb3, 2, 0x53c3, 3,
421                     0x8086, 4, 0x4f0d, 5, 0x9678, 6, 0x67d2, 7,
422                     0x634c, 8, 0x7396, 9, 0x5341, 10, 0x62fe, 10,
423                     0x767e, 100, 0x4f70, 100, 0x5343, 1000, 0x4edf, 1000,
424                     0x824c, 10000, 0x5104, 100000000};
425        for (int i = 0; i < han.length; i += 2) {
426            if (UCharacter.getHanNumericValue(han[i]) != han[i + 1]) {
427                errln("Numeric value of \\u" +
428                      Integer.toHexString(han[i]) + " expected to be " +
429                      han[i + 1]);
430            }
431        }
432    }
433
434    /**
435    * Tests for version
436    */
437    public void TestVersion()
438    {
439        if (!UCharacter.getUnicodeVersion().equals(VERSION_))
440            errln("FAIL expected: " + VERSION_ + " got: " + UCharacter.getUnicodeVersion());
441    }
442
443    /**
444    * Tests for control characters
445    */
446    public void TestISOControl()
447    {
448        int control[] = {0x001b, 0x000097, 0x000082};
449        int noncontrol[] = {0x61, 0x000031, 0x0000e2};
450
451        int size = control.length;
452        for (int i = 0; i < size; i ++)
453        {
454            if (!UCharacter.isISOControl(control[i]))
455            {
456                errln("FAIL 0x" + Integer.toHexString(control[i]) +
457                        " expected to be a control character");
458                break;
459            }
460            if (UCharacter.isISOControl(noncontrol[i]))
461            {
462                errln("FAIL 0x" + Integer.toHexString(noncontrol[i]) +
463                        " expected to be not a control character");
464                break;
465            }
466
467            logln("Ok    0x" + Integer.toHexString(control[i]) + " and 0x" +
468                    Integer.toHexString(noncontrol[i]));
469        }
470    }
471
472    /**
473     * Test Supplementary
474     */
475    public void TestSupplementary()
476    {
477        for (int i = 0; i < 0x10000; i ++) {
478            if (UCharacter.isSupplementary(i)) {
479                errln("Codepoint \\u" + Integer.toHexString(i) +
480                      " is not supplementary");
481            }
482        }
483        for (int i = 0x10000; i < 0x10FFFF; i ++) {
484            if (!UCharacter.isSupplementary(i)) {
485                errln("Codepoint \\u" + Integer.toHexString(i) +
486                      " is supplementary");
487            }
488        }
489    }
490
491    /**
492     * Test mirroring
493     */
494    public void TestMirror()
495    {
496        if (!(UCharacter.isMirrored(0x28) && UCharacter.isMirrored(0xbb) &&
497              UCharacter.isMirrored(0x2045) && UCharacter.isMirrored(0x232a)
498              && !UCharacter.isMirrored(0x27) &&
499              !UCharacter.isMirrored(0x61) && !UCharacter.isMirrored(0x284)
500              && !UCharacter.isMirrored(0x3400))) {
501            errln("isMirrored() does not work correctly");
502        }
503
504        if (!(UCharacter.getMirror(0x3c) == 0x3e &&
505              UCharacter.getMirror(0x5d) == 0x5b &&
506              UCharacter.getMirror(0x208d) == 0x208e &&
507              UCharacter.getMirror(0x3017) == 0x3016 &&
508
509              UCharacter.getMirror(0xbb) == 0xab &&
510              UCharacter.getMirror(0x2215) == 0x29F5 &&
511              UCharacter.getMirror(0x29F5) == 0x2215 && /* large delta between the code points */
512
513              UCharacter.getMirror(0x2e) == 0x2e &&
514              UCharacter.getMirror(0x6f3) == 0x6f3 &&
515              UCharacter.getMirror(0x301c) == 0x301c &&
516              UCharacter.getMirror(0xa4ab) == 0xa4ab &&
517
518              /* see Unicode Corrigendum #6 at http://www.unicode.org/versions/corrigendum6.html */
519              UCharacter.getMirror(0x2018) == 0x2018 &&
520              UCharacter.getMirror(0x201b) == 0x201b &&
521              UCharacter.getMirror(0x301d) == 0x301d)) {
522            errln("getMirror() does not work correctly");
523        }
524
525        /* verify that Bidi_Mirroring_Glyph roundtrips */
526        UnicodeSet set=new UnicodeSet("[:Bidi_Mirrored:]");
527        UnicodeSetIterator iter=new UnicodeSetIterator(set);
528        int start, end, c2, c3;
529        while(iter.nextRange() && (start=iter.codepoint)>=0) {
530            end=iter.codepointEnd;
531            do {
532                c2=UCharacter.getMirror(start);
533                c3=UCharacter.getMirror(c2);
534                if(c3!=start) {
535                    errln("getMirror() does not roundtrip: U+"+hex(start)+"->U+"+hex(c2)+"->U+"+hex(c3));
536                }
537                c3=UCharacter.getBidiPairedBracket(start);
538                if(UCharacter.getIntPropertyValue(start, UProperty.BIDI_PAIRED_BRACKET_TYPE)==UCharacter.BidiPairedBracketType.NONE) {
539                    if(c3!=start) {
540                        errln("u_getBidiPairedBracket(U+"+hex(start)+") != self for bpt(c)==None");
541                    }
542                } else {
543                    if(c3!=c2) {
544                        errln("u_getBidiPairedBracket(U+"+hex(start)+") != U+"+hex(c2)+" = bmg(c)'");
545                    }
546                }
547            } while(++start<=end);
548        }
549
550        // verify that Unicode Corrigendum #6 reverts mirrored status of the following
551        if (UCharacter.isMirrored(0x2018) ||
552            UCharacter.isMirrored(0x201d) ||
553            UCharacter.isMirrored(0x201f) ||
554            UCharacter.isMirrored(0x301e)) {
555            errln("Unicode Corrigendum #6 conflict, one or more of 2018/201d/201f/301e has mirrored property");
556        }
557    }
558
559    /**
560    * Tests for printable characters
561    */
562    public void TestPrint()
563    {
564        int printable[] = {0x0042, 0x00005f, 0x002014};
565        int nonprintable[] = {0x200c, 0x00009f, 0x00001b};
566
567        int size = printable.length;
568        for (int i = 0; i < size; i ++)
569        {
570            if (!UCharacter.isPrintable(printable[i]))
571            {
572                errln("FAIL \\u" + hex(printable[i]) +
573                    " expected to be a printable character");
574                break;
575            }
576            if (UCharacter.isPrintable(nonprintable[i]))
577            {
578                errln("FAIL \\u" + hex(nonprintable[i]) +
579                        " expected not to be a printable character");
580                break;
581            }
582            logln("Ok    \\u" + hex(printable[i]) + " and \\u" +
583                    hex(nonprintable[i]));
584        }
585
586        // test all ISO 8 controls
587        for (int ch = 0; ch <= 0x9f; ++ ch) {
588            if (ch == 0x20) {
589                // skip ASCII graphic characters and continue with DEL
590                ch = 0x7f;
591            }
592            if (UCharacter.isPrintable(ch)) {
593                errln("Fail \\u" + hex(ch) +
594                    " is a ISO 8 control character hence not printable\n");
595            }
596        }
597
598        /* test all Latin-1 graphic characters */
599        for (int ch = 0x20; ch <= 0xff; ++ ch) {
600            if (ch == 0x7f) {
601                ch = 0xa0;
602            }
603            if (!UCharacter.isPrintable(ch)
604                && ch != 0x00AD/* Unicode 4.0 changed the defintion of soft hyphen to be a Cf*/) {
605                errln("Fail \\u" + hex(ch) +
606                      " is a Latin-1 graphic character\n");
607            }
608        }
609    }
610
611    /**
612    * Testing for identifier characters
613    */
614    public void TestIdentifier()
615    {
616        int unicodeidstart[] = {0x0250, 0x0000e2, 0x000061};
617        int nonunicodeidstart[] = {0x2000, 0x00000a, 0x002019};
618        int unicodeidpart[] = {0x005f, 0x000032, 0x000045};
619        int nonunicodeidpart[] = {0x2030, 0x0000a3, 0x000020};
620        int idignore[] = {0x0006, 0x0010, 0x206b};
621        int nonidignore[] = {0x0075, 0x0000a3, 0x000061};
622
623        int size = unicodeidstart.length;
624        for (int i = 0; i < size; i ++)
625        {
626            if (!UCharacter.isUnicodeIdentifierStart(unicodeidstart[i]))
627            {
628                errln("FAIL \\u" + hex(unicodeidstart[i]) +
629                    " expected to be a unicode identifier start character");
630                break;
631            }
632            if (UCharacter.isUnicodeIdentifierStart(nonunicodeidstart[i]))
633            {
634                errln("FAIL \\u" + hex(nonunicodeidstart[i]) +
635                        " expected not to be a unicode identifier start " +
636                        "character");
637                break;
638            }
639            if (!UCharacter.isUnicodeIdentifierPart(unicodeidpart[i]))
640            {
641                errln("FAIL \\u" + hex(unicodeidpart[i]) +
642                    " expected to be a unicode identifier part character");
643                break;
644            }
645            if (UCharacter.isUnicodeIdentifierPart(nonunicodeidpart[i]))
646            {
647                errln("FAIL \\u" + hex(nonunicodeidpart[i]) +
648                        " expected not to be a unicode identifier part " +
649                        "character");
650                break;
651            }
652            if (!UCharacter.isIdentifierIgnorable(idignore[i]))
653            {
654                errln("FAIL \\u" + hex(idignore[i]) +
655                        " expected to be a ignorable unicode character");
656                break;
657            }
658            if (UCharacter.isIdentifierIgnorable(nonidignore[i]))
659            {
660                errln("FAIL \\u" + hex(nonidignore[i]) +
661                    " expected not to be a ignorable unicode character");
662                break;
663            }
664            logln("Ok    \\u" + hex(unicodeidstart[i]) + " and \\u" +
665                    hex(nonunicodeidstart[i]) + " and \\u" +
666                    hex(unicodeidpart[i]) + " and \\u" +
667                    hex(nonunicodeidpart[i]) + " and \\u" +
668                    hex(idignore[i]) + " and \\u" + hex(nonidignore[i]));
669        }
670    }
671
672    /**
673    * Tests for the character types, direction.<br>
674    * This method reads in UnicodeData.txt file for testing purposes. A
675    * default path is provided relative to the src path, however the user
676    * could set a system property to change the directory path.<br>
677    * e.g. java -DUnicodeData="data_directory_path"
678    * com.ibm.icu.dev.test.lang.UCharacterTest
679    */
680    public void TestUnicodeData()
681    {
682        // this is the 2 char category types used in the UnicodeData file
683        final String TYPE =
684            "LuLlLtLmLoMnMeMcNdNlNoZsZlZpCcCfCoCsPdPsPePcPoSmScSkSoPiPf";
685
686        // directorionality types used in the UnicodeData file
687        // padded by spaces to make each type size 4
688        final String DIR =
689            "L   R   EN  ES  ET  AN  CS  B   S   WS  ON  LRE LRO AL  RLE RLO PDF NSM BN  FSI LRI RLI PDI ";
690
691        Normalizer2 nfc = Normalizer2.getNFCInstance();
692        Normalizer2 nfkc = Normalizer2.getNFKCInstance();
693
694        try
695        {
696            BufferedReader input = TestUtil.getDataReader("unicode/UnicodeData.txt");
697            int numErrors = 0;
698
699            for (;;) {
700                String s = input.readLine();
701                if(s == null) {
702                    break;
703                }
704                if(s.length()<4 || s.startsWith("#")) {
705                    continue;
706                }
707                String[] fields = s.split(";", -1);
708                assert (fields.length == 15 ) : "Number of fields is " + fields.length + ": " + s;
709
710                int ch = Integer.parseInt(fields[0], 16);
711
712                // testing the general category
713                int type = TYPE.indexOf(fields[2]);
714                if (type < 0)
715                    type = 0;
716                else
717                    type = (type >> 1) + 1;
718                if (UCharacter.getType(ch) != type)
719                {
720                    errln("FAIL \\u" + hex(ch) + " expected type " + type);
721                    break;
722                }
723
724                if (UCharacter.getIntPropertyValue(ch,
725                           UProperty.GENERAL_CATEGORY_MASK) != (1 << type)) {
726                    errln("error: getIntPropertyValue(\\u" +
727                          Integer.toHexString(ch) +
728                          ", UProperty.GENERAL_CATEGORY_MASK) != " +
729                          "getMask(getType(ch))");
730                }
731
732                // testing combining class
733                int cc = Integer.parseInt(fields[3]);
734                if (UCharacter.getCombiningClass(ch) != cc)
735                {
736                    errln("FAIL \\u" + hex(ch) + " expected combining " +
737                            "class " + cc);
738                    break;
739                }
740                if (nfkc.getCombiningClass(ch) != cc)
741                {
742                    errln("FAIL \\u" + hex(ch) + " expected NFKC combining " +
743                            "class " + cc);
744                    break;
745                }
746
747                // testing the direction
748                String d = fields[4];
749                if (d.length() == 1)
750                    d = d + "   ";
751
752                int dir = DIR.indexOf(d) >> 2;
753                if (UCharacter.getDirection(ch) != dir)
754                {
755                    errln("FAIL \\u" + hex(ch) +
756                        " expected direction " + dir + " but got " + UCharacter.getDirection(ch));
757                    break;
758                }
759
760                byte bdir = (byte)dir;
761                if (UCharacter.getDirectionality(ch) != bdir)
762                {
763                    errln("FAIL \\u" + hex(ch) +
764                        " expected directionality " + bdir + " but got " +
765                        UCharacter.getDirectionality(ch));
766                    break;
767                }
768
769                /* get Decomposition_Type & Decomposition_Mapping, field 5 */
770                int dt;
771                if(fields[5].length()==0) {
772                    /* no decomposition, except UnicodeData.txt omits Hangul syllable decompositions */
773                    if(ch==0xac00 || ch==0xd7a3) {
774                        dt=UCharacter.DecompositionType.CANONICAL;
775                    } else {
776                        dt=UCharacter.DecompositionType.NONE;
777                    }
778                } else {
779                    d=fields[5];
780                    dt=-1;
781                    if(d.charAt(0)=='<') {
782                        int end=d.indexOf('>', 1);
783                        if(end>=0) {
784                            dt=UCharacter.getPropertyValueEnum(UProperty.DECOMPOSITION_TYPE, d.substring(1, end));
785                            while(d.charAt(++end)==' ') {}  // skip spaces
786                            d=d.substring(end);
787                        }
788                    } else {
789                        dt=UCharacter.DecompositionType.CANONICAL;
790                    }
791                }
792                String dm;
793                if(dt>UCharacter.DecompositionType.NONE) {
794                    if(ch==0xac00) {
795                        dm="\u1100\u1161";
796                    } else if(ch==0xd7a3) {
797                        dm="\ud788\u11c2";
798                    } else {
799                        String[] dmChars=d.split(" +");
800                        StringBuilder dmb=new StringBuilder(dmChars.length);
801                        for(String dmc : dmChars) {
802                            dmb.appendCodePoint(Integer.parseInt(dmc, 16));
803                        }
804                        dm=dmb.toString();
805                    }
806                } else {
807                    dm=null;
808                }
809                if(dt<0) {
810                    errln(String.format("error in UnicodeData.txt: syntax error in U+%04lX decomposition field", ch));
811                    return;
812                }
813                int i=UCharacter.getIntPropertyValue(ch, UProperty.DECOMPOSITION_TYPE);
814                assertEquals(
815                        String.format("error: UCharacter.getIntPropertyValue(U+%04x, UProperty.DECOMPOSITION_TYPE) is wrong", ch),
816                        dt, i);
817                /* Expect Decomposition_Mapping=nfkc.getRawDecomposition(c). */
818                String mapping=nfkc.getRawDecomposition(ch);
819                assertEquals(
820                        String.format("error: nfkc.getRawDecomposition(U+%04x) is wrong", ch),
821                        dm, mapping);
822                /* For canonical decompositions only, expect Decomposition_Mapping=nfc.getRawDecomposition(c). */
823                if(dt!=UCharacter.DecompositionType.CANONICAL) {
824                    dm=null;
825                }
826                mapping=nfc.getRawDecomposition(ch);
827                assertEquals(
828                        String.format("error: nfc.getRawDecomposition(U+%04x) is wrong", ch),
829                        dm, mapping);
830                /* recompose */
831                if(dt==UCharacter.DecompositionType.CANONICAL
832                        && !UCharacter.hasBinaryProperty(ch, UProperty.FULL_COMPOSITION_EXCLUSION)) {
833                    int a=dm.codePointAt(0);
834                    int b=dm.codePointBefore(dm.length());
835                    int composite=nfc.composePair(a, b);
836                    assertEquals(
837                            String.format(
838                                    "error: nfc U+%04X decomposes to U+%04X+U+%04X "+
839                                    "but does not compose back (instead U+%04X)",
840                                    ch, a, b, composite),
841                            ch, composite);
842                    /*
843                     * Note: NFKC has fewer round-trip mappings than NFC,
844                     * so we can't just test nfkc.composePair(a, b) here without further data.
845                     */
846                }
847
848                // testing iso comment
849                try{
850                    String isocomment = fields[11];
851                    String comment = UCharacter.getISOComment(ch);
852                    if (comment == null) {
853                        comment = "";
854                    }
855                    if (!comment.equals(isocomment)) {
856                        errln("FAIL \\u" + hex(ch) +
857                            " expected iso comment " + isocomment);
858                        break;
859                    }
860                }catch(Exception e){
861                    if(e.getMessage().indexOf("unames.icu") >= 0){
862                        numErrors++;
863                    }else{
864                        throw e;
865                    }
866                }
867
868                String upper = fields[12];
869                int tempchar = ch;
870                if (upper.length() > 0) {
871                    tempchar = Integer.parseInt(upper, 16);
872                }
873                int resultCp = UCharacter.toUpperCase(ch);
874                if (resultCp != tempchar) {
875                    errln("FAIL \\u" + Utility.hex(ch, 4)
876                            + " expected uppercase \\u"
877                            + Utility.hex(tempchar, 4)
878                            + " but got \\u"
879                            + Utility.hex(resultCp, 4));
880                    break;
881                }
882
883                String lower = fields[13];
884                tempchar = ch;
885                if (lower.length() > 0) {
886                    tempchar = Integer.parseInt(lower, 16);
887                }
888                if (UCharacter.toLowerCase(ch) != tempchar) {
889                    errln("FAIL \\u" + Utility.hex(ch, 4)
890                            + " expected lowercase \\u"
891                            + Utility.hex(tempchar, 4));
892                    break;
893                }
894
895
896
897                String title = fields[14];
898                tempchar = ch;
899                if (title.length() > 0) {
900                    tempchar = Integer.parseInt(title, 16);
901                }
902                if (UCharacter.toTitleCase(ch) != tempchar) {
903                    errln("FAIL \\u" + Utility.hex(ch, 4)
904                            + " expected titlecase \\u"
905                            + Utility.hex(tempchar, 4));
906                    break;
907                }
908            }
909            input.close();
910            if(numErrors > 0){
911                warnln("Could not find unames.icu");
912            }
913        }
914        catch (Exception e)
915        {
916            e.printStackTrace();
917        }
918
919
920        if (UCharacter.UnicodeBlock.of(0x0041)
921                                        != UCharacter.UnicodeBlock.BASIC_LATIN
922            || UCharacter.getIntPropertyValue(0x41, UProperty.BLOCK)
923                              != UCharacter.UnicodeBlock.BASIC_LATIN.getID()) {
924            errln("UCharacter.UnicodeBlock.of(\\u0041) property failed! "
925                    + "Expected : "
926                    + UCharacter.UnicodeBlock.BASIC_LATIN.getID() + " got "
927                    + UCharacter.UnicodeBlock.of(0x0041));
928        }
929
930        // sanity check on repeated properties
931        for (int ch = 0xfffe; ch <= 0x10ffff;) {
932            int type = UCharacter.getType(ch);
933            if (UCharacter.getIntPropertyValue(ch,
934                                               UProperty.GENERAL_CATEGORY_MASK)
935                != (1 << type)) {
936                errln("error: UCharacter.getIntPropertyValue(\\u"
937                      + Integer.toHexString(ch)
938                      + ", UProperty.GENERAL_CATEGORY_MASK) != "
939                      + "getMask(getType())");
940            }
941            if (type != UCharacterCategory.UNASSIGNED) {
942                errln("error: UCharacter.getType(\\u" + Utility.hex(ch, 4)
943                        + " != UCharacterCategory.UNASSIGNED (returns "
944                        + UCharacterCategory.toString(UCharacter.getType(ch))
945                        + ")");
946            }
947            if ((ch & 0xffff) == 0xfffe) {
948                ++ ch;
949            }
950            else {
951                ch += 0xffff;
952            }
953        }
954
955        // test that PUA is not "unassigned"
956        for(int ch = 0xe000; ch <= 0x10fffd;) {
957            int type = UCharacter.getType(ch);
958            if (UCharacter.getIntPropertyValue(ch,
959                                               UProperty.GENERAL_CATEGORY_MASK)
960                != (1 << type)) {
961                errln("error: UCharacter.getIntPropertyValue(\\u"
962                      + Integer.toHexString(ch)
963                      + ", UProperty.GENERAL_CATEGORY_MASK) != "
964                      + "getMask(getType())");
965            }
966
967            if (type == UCharacterCategory.UNASSIGNED) {
968                errln("error: UCharacter.getType(\\u"
969                        + Utility.hex(ch, 4)
970                        + ") == UCharacterCategory.UNASSIGNED");
971            }
972            else if (type != UCharacterCategory.PRIVATE_USE) {
973                logln("PUA override: UCharacter.getType(\\u"
974                      + Utility.hex(ch, 4) + ")=" + type);
975            }
976            if (ch == 0xf8ff) {
977                ch = 0xf0000;
978            }
979            else if (ch == 0xffffd) {
980                ch = 0x100000;
981            }
982            else {
983                ++ ch;
984            }
985        }
986    }
987
988
989    /**
990    * Test for the character names
991    */
992    public void TestNames()
993    {
994        try{
995            int length = UCharacterName.INSTANCE.getMaxCharNameLength();
996            if (length < 83) { // Unicode 3.2 max char name length
997               errln("getMaxCharNameLength()=" + length + " is too short");
998            }
999
1000            int c[] = {0x0061,                //LATIN SMALL LETTER A
1001                       0x000284,              //LATIN SMALL LETTER DOTLESS J WITH STROKE AND HOOK
1002                       0x003401,              //CJK UNIFIED IDEOGRAPH-3401
1003                       0x007fed,              //CJK UNIFIED IDEOGRAPH-7FED
1004                       0x00ac00,              //HANGUL SYLLABLE GA
1005                       0x00d7a3,              //HANGUL SYLLABLE HIH
1006                       0x00d800, 0x00dc00,    //LINEAR B SYLLABLE B008 A
1007                       0xff08,                //FULLWIDTH LEFT PARENTHESIS
1008                       0x00ffe5,              //FULLWIDTH YEN SIGN
1009                       0x00ffff,              //null
1010                       0x0023456              //CJK UNIFIED IDEOGRAPH-23456
1011                       };
1012            String name[] = {
1013                             "LATIN SMALL LETTER A",
1014                             "LATIN SMALL LETTER DOTLESS J WITH STROKE AND HOOK",
1015                             "CJK UNIFIED IDEOGRAPH-3401",
1016                             "CJK UNIFIED IDEOGRAPH-7FED",
1017                             "HANGUL SYLLABLE GA",
1018                             "HANGUL SYLLABLE HIH",
1019                             "",
1020                             "",
1021                             "FULLWIDTH LEFT PARENTHESIS",
1022                             "FULLWIDTH YEN SIGN",
1023                             "",
1024                             "CJK UNIFIED IDEOGRAPH-23456"
1025                             };
1026            String oldname[] = {"", "", "",
1027                            "",
1028                            "", "", "", "", "", "",
1029                            "", ""};
1030            String extendedname[] = {"LATIN SMALL LETTER A",
1031                                 "LATIN SMALL LETTER DOTLESS J WITH STROKE AND HOOK",
1032                                 "CJK UNIFIED IDEOGRAPH-3401",
1033                                 "CJK UNIFIED IDEOGRAPH-7FED",
1034                                 "HANGUL SYLLABLE GA",
1035                                 "HANGUL SYLLABLE HIH",
1036                                 "<lead surrogate-D800>",
1037                                 "<trail surrogate-DC00>",
1038                                 "FULLWIDTH LEFT PARENTHESIS",
1039                                 "FULLWIDTH YEN SIGN",
1040                                 "<noncharacter-FFFF>",
1041                                 "CJK UNIFIED IDEOGRAPH-23456"};
1042
1043            int size = c.length;
1044            String str;
1045            int uc;
1046
1047            for (int i = 0; i < size; i ++)
1048            {
1049                // modern Unicode character name
1050                str = UCharacter.getName(c[i]);
1051                if ((str == null && name[i].length() > 0) ||
1052                    (str != null && !str.equals(name[i])))
1053                {
1054                    errln("FAIL \\u" + hex(c[i]) + " expected name " +
1055                            name[i]);
1056                    break;
1057                }
1058
1059                // 1.0 Unicode character name
1060                str = UCharacter.getName1_0(c[i]);
1061                if ((str == null && oldname[i].length() > 0) ||
1062                    (str != null && !str.equals(oldname[i])))
1063                {
1064                    errln("FAIL \\u" + hex(c[i]) + " expected 1.0 name " +
1065                            oldname[i]);
1066                    break;
1067                }
1068
1069                // extended character name
1070                str = UCharacter.getExtendedName(c[i]);
1071                if (str == null || !str.equals(extendedname[i]))
1072                {
1073                    errln("FAIL \\u" + hex(c[i]) + " expected extended name " +
1074                            extendedname[i]);
1075                    break;
1076                }
1077
1078                // retrieving unicode character from modern name
1079                uc = UCharacter.getCharFromName(name[i]);
1080                if (uc != c[i] && name[i].length() != 0)
1081                {
1082                    errln("FAIL " + name[i] + " expected character \\u" +
1083                          hex(c[i]));
1084                    break;
1085                }
1086
1087                //retrieving unicode character from 1.0 name
1088                uc = UCharacter.getCharFromName1_0(oldname[i]);
1089                if (uc != c[i] && oldname[i].length() != 0)
1090                {
1091                    errln("FAIL " + oldname[i] + " expected 1.0 character \\u" +
1092                          hex(c[i]));
1093                    break;
1094                }
1095
1096                //retrieving unicode character from 1.0 name
1097                uc = UCharacter.getCharFromExtendedName(extendedname[i]);
1098                if (uc != c[i] && i != 0 && (i == 1 || i == 6))
1099                {
1100                    errln("FAIL " + extendedname[i] +
1101                          " expected extended character \\u" + hex(c[i]));
1102                    break;
1103                }
1104            }
1105
1106            // test getName works with mixed-case names (new in 2.0)
1107            if (0x61 != UCharacter.getCharFromName("LATin smALl letTER A")) {
1108                errln("FAIL: 'LATin smALl letTER A' should result in character "
1109                      + "U+0061");
1110            }
1111
1112            if (getInclusion() >= 5) {
1113                // extra testing different from icu
1114                for (int i = UCharacter.MIN_VALUE; i < UCharacter.MAX_VALUE; i ++)
1115                {
1116                    str = UCharacter.getName(i);
1117                    if (str != null && UCharacter.getCharFromName(str) != i)
1118                    {
1119                        errln("FAIL \\u" + hex(i) + " " + str  +
1120                                            " retrieval of name and vice versa" );
1121                        break;
1122                    }
1123                }
1124            }
1125
1126            // Test getCharNameCharacters
1127            if (getInclusion() >= 10) {
1128                boolean map[] = new boolean[256];
1129
1130                UnicodeSet set = new UnicodeSet(1, 0); // empty set
1131                UnicodeSet dumb = new UnicodeSet(1, 0); // empty set
1132
1133                // uprv_getCharNameCharacters() will likely return more lowercase
1134                // letters than actual character names contain because
1135                // it includes all the characters in lowercased names of
1136                // general categories, for the full possible set of extended names.
1137                UCharacterName.INSTANCE.getCharNameCharacters(set);
1138
1139                // build set the dumb (but sure-fire) way
1140                Arrays.fill(map, false);
1141
1142                int maxLength = 0;
1143                for (int cp = 0; cp < 0x110000; ++ cp) {
1144                    String n = UCharacter.getExtendedName(cp);
1145                    int len = n.length();
1146                    if (len > maxLength) {
1147                        maxLength = len;
1148                    }
1149
1150                    for (int i = 0; i < len; ++ i) {
1151                        char ch = n.charAt(i);
1152                        if (!map[ch & 0xff]) {
1153                            dumb.add(ch);
1154                            map[ch & 0xff] = true;
1155                        }
1156                    }
1157                }
1158
1159                length = UCharacterName.INSTANCE.getMaxCharNameLength();
1160                if (length != maxLength) {
1161                    errln("getMaxCharNameLength()=" + length
1162                          + " differs from the maximum length " + maxLength
1163                          + " of all extended names");
1164                }
1165
1166                // compare the sets.  Where is my uset_equals?!!
1167                boolean ok = true;
1168                for (int i = 0; i < 256; ++ i) {
1169                    if (set.contains(i) != dumb.contains(i)) {
1170                        if (0x61 <= i && i <= 0x7a // a-z
1171                            && set.contains(i) && !dumb.contains(i)) {
1172                            // ignore lowercase a-z that are in set but not in dumb
1173                            ok = true;
1174                        }
1175                        else {
1176                            ok = false;
1177                            break;
1178                        }
1179                    }
1180                }
1181
1182                String pattern1 = set.toPattern(true);
1183                String pattern2 = dumb.toPattern(true);
1184
1185                if (!ok) {
1186                    errln("FAIL: getCharNameCharacters() returned " + pattern1
1187                          + " expected " + pattern2
1188                          + " (too many lowercase a-z are ok)");
1189                } else {
1190                    logln("Ok: getCharNameCharacters() returned " + pattern1);
1191                }
1192            }
1193            // improve code coverage
1194           String expected = "LATIN SMALL LETTER A|LATIN SMALL LETTER DOTLESS J WITH STROKE AND HOOK|"+
1195                             "CJK UNIFIED IDEOGRAPH-3401|CJK UNIFIED IDEOGRAPH-7FED|HANGUL SYLLABLE GA|"+
1196                             "HANGUL SYLLABLE HIH|LINEAR B SYLLABLE B008 A|FULLWIDTH LEFT PARENTHESIS|"+
1197                             "FULLWIDTH YEN SIGN|"+
1198                             "null|"+ // getName returns null because 0xFFFF does not have a name, but has an extended name!
1199                             "CJK UNIFIED IDEOGRAPH-23456";
1200           String separator= "|";
1201           String source = Utility.valueOf(c);
1202           String result = UCharacter.getName(source, separator);
1203           if(!result.equals(expected)){
1204               errln("UCharacter.getName did not return the expected result.\n\t Expected: "+ expected+"\n\t Got: "+ result);
1205           }
1206
1207        }catch(IllegalArgumentException e){
1208            if(e.getMessage().indexOf("unames.icu") >= 0){
1209                warnln("Could not find unames.icu");
1210            }else{
1211                throw e;
1212            }
1213        }
1214
1215    }
1216
1217    public void TestUCharFromNameUnderflow() {
1218        // Ticket #10889: Underflow crash when there is no dash.
1219        int c = UCharacter.getCharFromExtendedName("<NO BREAK SPACE>");
1220        if(c >= 0) {
1221            errln("UCharacter.getCharFromExtendedName(<NO BREAK SPACE>) = U+" + hex(c) +
1222                    " but should fail (-1)");
1223        }
1224
1225        // Test related edge cases.
1226        c = UCharacter.getCharFromExtendedName("<-00a0>");
1227        if(c >= 0) {
1228            errln("UCharacter.getCharFromExtendedName(<-00a0>) = U+" + hex(c) +
1229                    " but should fail (-1)");
1230        }
1231
1232        c = UCharacter.getCharFromExtendedName("<control->");
1233        if(c >= 0) {
1234            errln("UCharacter.getCharFromExtendedName(<control->) = U+" + hex(c) +
1235                    " but should fail (-1)");
1236        }
1237
1238        c = UCharacter.getCharFromExtendedName("<control-111111>");
1239        if(c >= 0) {
1240            errln("UCharacter.getCharFromExtendedName(<control-111111>) = U+" + hex(c) +
1241                    " but should fail (-1)");
1242        }
1243    }
1244
1245    /**
1246    * Testing name iteration
1247    */
1248    public void TestNameIteration()throws Exception
1249    {
1250        try {
1251            ValueIterator iterator = UCharacter.getExtendedNameIterator();
1252            ValueIterator.Element element = new ValueIterator.Element();
1253            ValueIterator.Element old     = new ValueIterator.Element();
1254            // testing subrange
1255            iterator.setRange(-10, -5);
1256            if (iterator.next(element)) {
1257                errln("Fail, expected iterator to return false when range is set outside the meaningful range");
1258            }
1259            iterator.setRange(0x110000, 0x111111);
1260            if (iterator.next(element)) {
1261                errln("Fail, expected iterator to return false when range is set outside the meaningful range");
1262            }
1263            try {
1264                iterator.setRange(50, 10);
1265                errln("Fail, expected exception when encountered invalid range");
1266            } catch (Exception e) {
1267            }
1268
1269            iterator.setRange(-10, 10);
1270            if (!iterator.next(element) || element.integer != 0) {
1271                errln("Fail, expected iterator to return 0 when range start limit is set outside the meaningful range");
1272            }
1273
1274            iterator.setRange(0x10FFFE, 0x200000);
1275            int last = 0;
1276            while (iterator.next(element)) {
1277                last = element.integer;
1278            }
1279            if (last != 0x10FFFF) {
1280                errln("Fail, expected iterator to return 0x10FFFF when range end limit is set outside the meaningful range");
1281            }
1282
1283            iterator = UCharacter.getNameIterator();
1284            iterator.setRange(0xF, 0x45);
1285            while (iterator.next(element)) {
1286                if (element.integer <= old.integer) {
1287                    errln("FAIL next returned a less codepoint \\u" +
1288                        Integer.toHexString(element.integer) + " than \\u" +
1289                        Integer.toHexString(old.integer));
1290                    break;
1291                }
1292                if (!UCharacter.getName(element.integer).equals(element.value))
1293                {
1294                    errln("FAIL next codepoint \\u" +
1295                        Integer.toHexString(element.integer) +
1296                        " does not have the expected name " +
1297                        UCharacter.getName(element.integer) +
1298                        " instead have the name " + (String)element.value);
1299                    break;
1300                }
1301                old.integer = element.integer;
1302            }
1303
1304            iterator.reset();
1305            iterator.next(element);
1306            if (element.integer != 0x20) {
1307                errln("FAIL reset in iterator");
1308            }
1309
1310            iterator.setRange(0, 0x110000);
1311            old.integer = 0;
1312            while (iterator.next(element)) {
1313                if (element.integer != 0 && element.integer <= old.integer) {
1314                    errln("FAIL next returned a less codepoint \\u" +
1315                        Integer.toHexString(element.integer) + " than \\u" +
1316                        Integer.toHexString(old.integer));
1317                    break;
1318                }
1319                if (!UCharacter.getName(element.integer).equals(element.value))
1320                {
1321                    errln("FAIL next codepoint \\u" +
1322                            Integer.toHexString(element.integer) +
1323                            " does not have the expected name " +
1324                            UCharacter.getName(element.integer) +
1325                            " instead have the name " + (String)element.value);
1326                    break;
1327                }
1328                for (int i = old.integer + 1; i < element.integer; i ++) {
1329                    if (UCharacter.getName(i) != null) {
1330                        errln("FAIL between codepoints are not null \\u" +
1331                                Integer.toHexString(old.integer) + " and " +
1332                                Integer.toHexString(element.integer) + " has " +
1333                                Integer.toHexString(i) + " with a name " +
1334                                UCharacter.getName(i));
1335                        break;
1336                    }
1337                }
1338                old.integer = element.integer;
1339            }
1340
1341            iterator = UCharacter.getExtendedNameIterator();
1342            old.integer = 0;
1343            while (iterator.next(element)) {
1344                if (element.integer != 0 && element.integer != old.integer) {
1345                    errln("FAIL next returned a codepoint \\u" +
1346                            Integer.toHexString(element.integer) +
1347                            " different from \\u" +
1348                            Integer.toHexString(old.integer));
1349                    break;
1350                }
1351                if (!UCharacter.getExtendedName(element.integer).equals(
1352                                                              element.value)) {
1353                    errln("FAIL next codepoint \\u" +
1354                        Integer.toHexString(element.integer) +
1355                        " name should be "
1356                        + UCharacter.getExtendedName(element.integer) +
1357                        " instead of " + (String)element.value);
1358                    break;
1359                }
1360                old.integer++;
1361            }
1362            iterator = UCharacter.getName1_0Iterator();
1363            old.integer = 0;
1364            while (iterator.next(element)) {
1365                logln(Integer.toHexString(element.integer) + " " +
1366                                                        (String)element.value);
1367                if (element.integer != 0 && element.integer <= old.integer) {
1368                    errln("FAIL next returned a less codepoint \\u" +
1369                        Integer.toHexString(element.integer) + " than \\u" +
1370                        Integer.toHexString(old.integer));
1371                    break;
1372                }
1373                if (!element.value.equals(UCharacter.getName1_0(
1374                                                            element.integer))) {
1375                    errln("FAIL next codepoint \\u" +
1376                            Integer.toHexString(element.integer) +
1377                            " name cannot be null");
1378                    break;
1379                }
1380                for (int i = old.integer + 1; i < element.integer; i ++) {
1381                    if (UCharacter.getName1_0(i) != null) {
1382                        errln("FAIL between codepoints are not null \\u" +
1383                            Integer.toHexString(old.integer) + " and " +
1384                            Integer.toHexString(element.integer) + " has " +
1385                            Integer.toHexString(i) + " with a name " +
1386                            UCharacter.getName1_0(i));
1387                        break;
1388                    }
1389                }
1390                old.integer = element.integer;
1391            }
1392        } catch(Exception e){
1393            // !!! wouldn't preflighting be simpler?  This looks like
1394            // it is effectively be doing that.  It seems that for every
1395            // true error the code will call errln, which will throw the error, which
1396            // this will catch, which this will then rethrow the error.  Just seems
1397            // cumbersome.
1398            if(e.getMessage().indexOf("unames.icu") >= 0){
1399                warnln("Could not find unames.icu");
1400            } else {
1401                errln(e.getMessage());
1402            }
1403        }
1404    }
1405
1406    /**
1407    * Testing the for illegal characters
1408    */
1409    public void TestIsLegal()
1410    {
1411        int illegal[] = {0xFFFE, 0x00FFFF, 0x005FFFE, 0x005FFFF, 0x0010FFFE,
1412                         0x0010FFFF, 0x110000, 0x00FDD0, 0x00FDDF, 0x00FDE0,
1413                         0x00FDEF, 0xD800, 0xDC00, -1};
1414        int legal[] = {0x61, 0x00FFFD, 0x0010000, 0x005FFFD, 0x0060000,
1415                       0x0010FFFD, 0xFDCF, 0x00FDF0};
1416        for (int count = 0; count < illegal.length; count ++) {
1417            if (UCharacter.isLegal(illegal[count])) {
1418                errln("FAIL \\u" + hex(illegal[count]) +
1419                        " is not a legal character");
1420            }
1421        }
1422
1423        for (int count = 0; count < legal.length; count ++) {
1424            if (!UCharacter.isLegal(legal[count])) {
1425                errln("FAIL \\u" + hex(legal[count]) +
1426                                                   " is a legal character");
1427            }
1428        }
1429
1430        String illegalStr = "This is an illegal string ";
1431        String legalStr = "This is a legal string ";
1432
1433        for (int count = 0; count < illegal.length; count ++) {
1434            StringBuffer str = new StringBuffer(illegalStr);
1435            if (illegal[count] < 0x10000) {
1436                str.append((char)illegal[count]);
1437            }
1438            else {
1439                char lead = UTF16.getLeadSurrogate(illegal[count]);
1440                char trail = UTF16.getTrailSurrogate(illegal[count]);
1441                str.append(lead);
1442                str.append(trail);
1443            }
1444            if (UCharacter.isLegal(str.toString())) {
1445                errln("FAIL " + hex(str.toString()) +
1446                      " is not a legal string");
1447            }
1448        }
1449
1450        for (int count = 0; count < legal.length; count ++) {
1451            StringBuffer str = new StringBuffer(legalStr);
1452            if (legal[count] < 0x10000) {
1453                str.append((char)legal[count]);
1454            }
1455            else {
1456                char lead = UTF16.getLeadSurrogate(legal[count]);
1457                char trail = UTF16.getTrailSurrogate(legal[count]);
1458                str.append(lead);
1459                str.append(trail);
1460            }
1461            if (!UCharacter.isLegal(str.toString())) {
1462                errln("FAIL " + hex(str.toString()) + " is a legal string");
1463            }
1464        }
1465    }
1466
1467    /**
1468     * Test getCodePoint
1469     */
1470    public void TestCodePoint()
1471    {
1472        int ch = 0x10000;
1473        for (char i = 0xD800; i < 0xDC00; i ++) {
1474            for (char j = 0xDC00; j <= 0xDFFF; j ++) {
1475                if (UCharacter.getCodePoint(i, j) != ch) {
1476                    errln("Error getting codepoint for surrogate " +
1477                          "characters \\u"
1478                          + Integer.toHexString(i) + " \\u" +
1479                          Integer.toHexString(j));
1480                }
1481                ch ++;
1482            }
1483        }
1484        try
1485        {
1486            UCharacter.getCodePoint((char)0xD7ff, (char)0xDC00);
1487            errln("Invalid surrogate characters should not form a " +
1488                  "supplementary");
1489        } catch(Exception e) {
1490        }
1491        for (char i = 0; i < 0xFFFF; i++) {
1492            if (i == 0xFFFE ||
1493                (i >= 0xD800 && i <= 0xDFFF) ||
1494                (i >= 0xFDD0 && i <= 0xFDEF)) {
1495                // not a character
1496                try {
1497                    UCharacter.getCodePoint(i);
1498                    errln("Not a character is not a valid codepoint");
1499                } catch (Exception e) {
1500                }
1501            }
1502            else {
1503                if (UCharacter.getCodePoint(i) != i) {
1504                    errln("A valid codepoint should return itself");
1505                }
1506            }
1507        }
1508    }
1509
1510    /**
1511    * This method is a little different from the type test in icu4c.
1512    * But combined with testUnicodeData, they basically do the same thing.
1513    */
1514    public void TestIteration()
1515    {
1516        int limit     = 0;
1517        int prevtype  = -1;
1518        int shouldBeDir;
1519        int test[][]={{0x41, UCharacterCategory.UPPERCASE_LETTER},
1520                        {0x308, UCharacterCategory.NON_SPACING_MARK},
1521                        {0xfffe, UCharacterCategory.GENERAL_OTHER_TYPES},
1522                        {0xe0041, UCharacterCategory.FORMAT},
1523                        {0xeffff, UCharacterCategory.UNASSIGNED}};
1524
1525        // default Bidi classes for unassigned code points, from the DerivedBidiClass.txt header
1526        int defaultBidi[][]={
1527            { 0x0590, UCharacterDirection.LEFT_TO_RIGHT },
1528            { 0x0600, UCharacterDirection.RIGHT_TO_LEFT },
1529            { 0x07C0, UCharacterDirection.RIGHT_TO_LEFT_ARABIC },
1530            { 0x08A0, UCharacterDirection.RIGHT_TO_LEFT },
1531            { 0x0900, UCharacterDirection.RIGHT_TO_LEFT_ARABIC },  /* Unicode 6.1 changes U+08A0..U+08FF from R to AL */
1532            { 0x20A0, UCharacterDirection.LEFT_TO_RIGHT },
1533            { 0x20D0, UCharacterDirection.EUROPEAN_NUMBER_TERMINATOR },  /* Unicode 6.3 changes the currency symbols block U+20A0..U+20CF to default to ET not L */
1534            { 0xFB1D, UCharacterDirection.LEFT_TO_RIGHT },
1535            { 0xFB50, UCharacterDirection.RIGHT_TO_LEFT },
1536            { 0xFE00, UCharacterDirection.RIGHT_TO_LEFT_ARABIC },
1537            { 0xFE70, UCharacterDirection.LEFT_TO_RIGHT },
1538            { 0xFF00, UCharacterDirection.RIGHT_TO_LEFT_ARABIC },
1539            { 0x10800, UCharacterDirection.LEFT_TO_RIGHT },
1540            { 0x11000, UCharacterDirection.RIGHT_TO_LEFT },
1541            { 0x1E800, UCharacterDirection.LEFT_TO_RIGHT },  /* new default-R range in Unicode 5.2: U+1E800 - U+1EFFF */
1542            { 0x1EE00, UCharacterDirection.RIGHT_TO_LEFT },
1543            { 0x1EF00, UCharacterDirection.RIGHT_TO_LEFT_ARABIC },  /* Unicode 6.1 changes U+1EE00..U+1EEFF from R to AL */
1544            { 0x1F000, UCharacterDirection.RIGHT_TO_LEFT },
1545            { 0x110000, UCharacterDirection.LEFT_TO_RIGHT }
1546        };
1547
1548        RangeValueIterator iterator = UCharacter.getTypeIterator();
1549        RangeValueIterator.Element result = new RangeValueIterator.Element();
1550        while (iterator.next(result)) {
1551            if (result.start != limit) {
1552                errln("UCharacterIteration failed: Ranges not continuous " +
1553                        "0x" + Integer.toHexString(result.start));
1554            }
1555
1556            limit = result.limit;
1557            if (result.value == prevtype) {
1558                errln("Type of the next set of enumeration should be different");
1559            }
1560            prevtype = result.value;
1561
1562            for (int i = result.start; i < limit; i ++) {
1563                int temptype = UCharacter.getType(i);
1564                if (temptype != result.value) {
1565                    errln("UCharacterIteration failed: Codepoint \\u" +
1566                            Integer.toHexString(i) + " should be of type " +
1567                            temptype + " not " + result.value);
1568                }
1569            }
1570
1571            for (int i = 0; i < test.length; ++ i) {
1572                if (result.start <= test[i][0] && test[i][0] < result.limit) {
1573                    if (result.value != test[i][1]) {
1574                        errln("error: getTypes() has range ["
1575                              + Integer.toHexString(result.start) + ", "
1576                              + Integer.toHexString(result.limit)
1577                              + "] with type " + result.value
1578                              + " instead of ["
1579                              + Integer.toHexString(test[i][0]) + ", "
1580                              + Integer.toHexString(test[i][1]));
1581                    }
1582                }
1583            }
1584
1585            // LineBreak.txt specifies:
1586            //   #  - Assigned characters that are not listed explicitly are given the value
1587            //   #    "AL".
1588            //   #  - Unassigned characters are given the value "XX".
1589            //
1590            // PUA characters are listed explicitly with "XX".
1591            // Verify that no assigned character has "XX".
1592            if (result.value != UCharacterCategory.UNASSIGNED
1593                && result.value != UCharacterCategory.PRIVATE_USE) {
1594                int c = result.start;
1595                while (c < result.limit) {
1596                    if (0 == UCharacter.getIntPropertyValue(c,
1597                                                UProperty.LINE_BREAK)) {
1598                        logln("error UProperty.LINE_BREAK(assigned \\u"
1599                              + Utility.hex(c, 4) + ")=XX");
1600                    }
1601                    ++ c;
1602                }
1603            }
1604
1605            /*
1606             * Verify default Bidi classes.
1607             * For recent Unicode versions, see UCD.html.
1608             *
1609             * For older Unicode versions:
1610             * See table 3-7 "Bidirectional Character Types" in UAX #9.
1611             * http://www.unicode.org/reports/tr9/
1612             *
1613             * See also DerivedBidiClass.txt for Cn code points!
1614             *
1615             * Unicode 4.0.1/Public Review Issue #28 (http://www.unicode.org/review/resolved-pri.html)
1616             * changed some default values.
1617             * In particular, non-characters and unassigned Default Ignorable Code Points
1618             * change from L to BN.
1619             *
1620             * UCD.html version 4.0.1 does not yet reflect these changes.
1621             */
1622            if (result.value == UCharacterCategory.UNASSIGNED
1623                || result.value == UCharacterCategory.PRIVATE_USE) {
1624                int c = result.start;
1625                for (int i = 0; i < defaultBidi.length && c < result.limit;
1626                     ++ i) {
1627                    if (c < defaultBidi[i][0]) {
1628                        while (c < result.limit && c < defaultBidi[i][0]) {
1629                            // TODO change to public UCharacter.isNonCharacter(c) once it's available
1630                            if(com.ibm.icu.impl.UCharacterUtility.isNonCharacter(c) || UCharacter.hasBinaryProperty(c, UProperty.DEFAULT_IGNORABLE_CODE_POINT)) {
1631                                shouldBeDir=UCharacter.BOUNDARY_NEUTRAL;
1632                            } else {
1633                                shouldBeDir=defaultBidi[i][1];
1634                            }
1635
1636                            if (UCharacter.getDirection(c) != shouldBeDir
1637                                || UCharacter.getIntPropertyValue(c,
1638                                                          UProperty.BIDI_CLASS)
1639                                   != shouldBeDir) {
1640                                errln("error: getDirection(unassigned/PUA "
1641                                      + Integer.toHexString(c)
1642                                      + ") should be "
1643                                      + shouldBeDir);
1644                            }
1645                            ++ c;
1646                        }
1647                    }
1648                }
1649            }
1650        }
1651
1652        iterator.reset();
1653        if (iterator.next(result) == false || result.start != 0) {
1654            System.out.println("result " + result.start);
1655            errln("UCharacterIteration reset() failed");
1656        }
1657    }
1658
1659    /**
1660     * Testing getAge
1661     */
1662    public void TestGetAge()
1663    {
1664        int ages[] = {0x41,    1, 1, 0, 0,
1665                      0xffff,  1, 1, 0, 0,
1666                      0x20ab,  2, 0, 0, 0,
1667                      0x2fffe, 2, 0, 0, 0,
1668                      0x20ac,  2, 1, 0, 0,
1669                      0xfb1d,  3, 0, 0, 0,
1670                      0x3f4,   3, 1, 0, 0,
1671                      0x10300, 3, 1, 0, 0,
1672                      0x220,   3, 2, 0, 0,
1673                      0xff60,  3, 2, 0, 0};
1674        for (int i = 0; i < ages.length; i += 5) {
1675            VersionInfo age = UCharacter.getAge(ages[i]);
1676            if (age != VersionInfo.getInstance(ages[i + 1], ages[i + 2],
1677                                               ages[i + 3], ages[i + 4])) {
1678                errln("error: getAge(\\u" + Integer.toHexString(ages[i]) +
1679                      ") == " + age.toString() + " instead of " +
1680                      ages[i + 1] + "." + ages[i + 2] + "." + ages[i + 3] +
1681                      "." + ages[i + 4]);
1682            }
1683        }
1684
1685        int[] valid_tests = {
1686                UCharacter.MIN_VALUE, UCharacter.MIN_VALUE+1,
1687                UCharacter.MAX_VALUE-1, UCharacter.MAX_VALUE};
1688        int[] invalid_tests = {
1689                UCharacter.MIN_VALUE-1, UCharacter.MIN_VALUE-2,
1690                UCharacter.MAX_VALUE+1, UCharacter.MAX_VALUE+2};
1691
1692        for(int i=0; i< valid_tests.length; i++){
1693            try{
1694                UCharacter.getAge(valid_tests[i]);
1695            } catch(Exception e){
1696                errln("UCharacter.getAge(int) was not suppose to have " +
1697                        "an exception. Value passed: " + valid_tests[i]);
1698            }
1699        }
1700
1701        for(int i=0; i< invalid_tests.length; i++){
1702            try{
1703                UCharacter.getAge(invalid_tests[i]);
1704                errln("UCharacter.getAge(int) was suppose to have " +
1705                        "an exception. Value passed: " + invalid_tests[i]);
1706            } catch(Exception e){
1707            }
1708        }
1709    }
1710
1711    /**
1712     * Test binary non core properties
1713     */
1714    public void TestAdditionalProperties()
1715    {
1716        // test data for hasBinaryProperty()
1717        int props[][] = { // code point, property
1718            { 0x0627, UProperty.ALPHABETIC, 1 },
1719            { 0x1034a, UProperty.ALPHABETIC, 1 },
1720            { 0x2028, UProperty.ALPHABETIC, 0 },
1721
1722            { 0x0066, UProperty.ASCII_HEX_DIGIT, 1 },
1723            { 0x0067, UProperty.ASCII_HEX_DIGIT, 0 },
1724
1725            { 0x202c, UProperty.BIDI_CONTROL, 1 },
1726            { 0x202f, UProperty.BIDI_CONTROL, 0 },
1727
1728            { 0x003c, UProperty.BIDI_MIRRORED, 1 },
1729            { 0x003d, UProperty.BIDI_MIRRORED, 0 },
1730
1731            /* see Unicode Corrigendum #6 at http://www.unicode.org/versions/corrigendum6.html */
1732            { 0x2018, UProperty.BIDI_MIRRORED, 0 },
1733            { 0x201d, UProperty.BIDI_MIRRORED, 0 },
1734            { 0x201f, UProperty.BIDI_MIRRORED, 0 },
1735            { 0x301e, UProperty.BIDI_MIRRORED, 0 },
1736
1737            { 0x058a, UProperty.DASH, 1 },
1738            { 0x007e, UProperty.DASH, 0 },
1739
1740            { 0x0c4d, UProperty.DIACRITIC, 1 },
1741            { 0x3000, UProperty.DIACRITIC, 0 },
1742
1743            { 0x0e46, UProperty.EXTENDER, 1 },
1744            { 0x0020, UProperty.EXTENDER, 0 },
1745
1746            { 0xfb1d, UProperty.FULL_COMPOSITION_EXCLUSION, 1 },
1747            { 0x1d15f, UProperty.FULL_COMPOSITION_EXCLUSION, 1 },
1748            { 0xfb1e, UProperty.FULL_COMPOSITION_EXCLUSION, 0 },
1749
1750            { 0x110a, UProperty.NFD_INERT, 1 },      /* Jamo L */
1751            { 0x0308, UProperty.NFD_INERT, 0 },
1752
1753            { 0x1164, UProperty.NFKD_INERT, 1 },     /* Jamo V */
1754            { 0x1d79d, UProperty.NFKD_INERT, 0 },   /* math compat version of xi */
1755
1756            { 0x0021, UProperty.NFC_INERT, 1 },      /* ! */
1757            { 0x0061, UProperty.NFC_INERT, 0 },     /* a */
1758            { 0x00e4, UProperty.NFC_INERT, 0 },     /* a-umlaut */
1759            { 0x0102, UProperty.NFC_INERT, 0 },     /* a-breve */
1760            { 0xac1c, UProperty.NFC_INERT, 0 },     /* Hangul LV */
1761            { 0xac1d, UProperty.NFC_INERT, 1 },      /* Hangul LVT */
1762
1763            { 0x1d79d, UProperty.NFKC_INERT, 0 },   /* math compat version of xi */
1764            { 0x2a6d6, UProperty.NFKC_INERT, 1 },    /* Han, last of CJK ext. B */
1765
1766            { 0x00e4, UProperty.SEGMENT_STARTER, 1 },
1767            { 0x0308, UProperty.SEGMENT_STARTER, 0 },
1768            { 0x110a, UProperty.SEGMENT_STARTER, 1 }, /* Jamo L */
1769            { 0x1164, UProperty.SEGMENT_STARTER, 0 },/* Jamo V */
1770            { 0xac1c, UProperty.SEGMENT_STARTER, 1 }, /* Hangul LV */
1771            { 0xac1d, UProperty.SEGMENT_STARTER, 1 }, /* Hangul LVT */
1772
1773            { 0x0044, UProperty.HEX_DIGIT, 1 },
1774            { 0xff46, UProperty.HEX_DIGIT, 1 },
1775            { 0x0047, UProperty.HEX_DIGIT, 0 },
1776
1777            { 0x30fb, UProperty.HYPHEN, 1 },
1778            { 0xfe58, UProperty.HYPHEN, 0 },
1779
1780            { 0x2172, UProperty.ID_CONTINUE, 1 },
1781            { 0x0307, UProperty.ID_CONTINUE, 1 },
1782            { 0x005c, UProperty.ID_CONTINUE, 0 },
1783
1784            { 0x2172, UProperty.ID_START, 1 },
1785            { 0x007a, UProperty.ID_START, 1 },
1786            { 0x0039, UProperty.ID_START, 0 },
1787
1788            { 0x4db5, UProperty.IDEOGRAPHIC, 1 },
1789            { 0x2f999, UProperty.IDEOGRAPHIC, 1 },
1790            { 0x2f99, UProperty.IDEOGRAPHIC, 0 },
1791
1792            { 0x200c, UProperty.JOIN_CONTROL, 1 },
1793            { 0x2029, UProperty.JOIN_CONTROL, 0 },
1794
1795            { 0x1d7bc, UProperty.LOWERCASE, 1 },
1796            { 0x0345, UProperty.LOWERCASE, 1 },
1797            { 0x0030, UProperty.LOWERCASE, 0 },
1798
1799            { 0x1d7a9, UProperty.MATH, 1 },
1800            { 0x2135, UProperty.MATH, 1 },
1801            { 0x0062, UProperty.MATH, 0 },
1802
1803            { 0xfde1, UProperty.NONCHARACTER_CODE_POINT, 1 },
1804            { 0x10ffff, UProperty.NONCHARACTER_CODE_POINT, 1 },
1805            { 0x10fffd, UProperty.NONCHARACTER_CODE_POINT, 0 },
1806
1807            { 0x0022, UProperty.QUOTATION_MARK, 1 },
1808            { 0xff62, UProperty.QUOTATION_MARK, 1 },
1809            { 0xd840, UProperty.QUOTATION_MARK, 0 },
1810
1811            { 0x061f, UProperty.TERMINAL_PUNCTUATION, 1 },
1812            { 0xe003f, UProperty.TERMINAL_PUNCTUATION, 0 },
1813
1814            { 0x1d44a, UProperty.UPPERCASE, 1 },
1815            { 0x2162, UProperty.UPPERCASE, 1 },
1816            { 0x0345, UProperty.UPPERCASE, 0 },
1817
1818            { 0x0020, UProperty.WHITE_SPACE, 1 },
1819            { 0x202f, UProperty.WHITE_SPACE, 1 },
1820            { 0x3001, UProperty.WHITE_SPACE, 0 },
1821
1822            { 0x0711, UProperty.XID_CONTINUE, 1 },
1823            { 0x1d1aa, UProperty.XID_CONTINUE, 1 },
1824            { 0x007c, UProperty.XID_CONTINUE, 0 },
1825
1826            { 0x16ee, UProperty.XID_START, 1 },
1827            { 0x23456, UProperty.XID_START, 1 },
1828            { 0x1d1aa, UProperty.XID_START, 0 },
1829
1830            /*
1831             * Version break:
1832             * The following properties are only supported starting with the
1833             * Unicode version indicated in the second field.
1834             */
1835            { -1, 0x320, 0 },
1836
1837            { 0x180c, UProperty.DEFAULT_IGNORABLE_CODE_POINT, 1 },
1838            { 0xfe02, UProperty.DEFAULT_IGNORABLE_CODE_POINT, 1 },
1839            { 0x1801, UProperty.DEFAULT_IGNORABLE_CODE_POINT, 0 },
1840
1841            { 0x0149, UProperty.DEPRECATED, 1 },         /* changed in Unicode 5.2 */
1842            { 0x0341, UProperty.DEPRECATED, 0 },        /* changed in Unicode 5.2 */
1843            { 0xe0041, UProperty.DEPRECATED, 1 },       /* Changed from Unicode 5 to 5.1 */
1844            { 0xe0100, UProperty.DEPRECATED, 0 },
1845
1846            { 0x00a0, UProperty.GRAPHEME_BASE, 1 },
1847            { 0x0a4d, UProperty.GRAPHEME_BASE, 0 },
1848            { 0xff9d, UProperty.GRAPHEME_BASE, 1 },
1849            { 0xff9f, UProperty.GRAPHEME_BASE, 0 },      /* changed from Unicode 3.2 to 4  and again 5 to 5.1 */
1850
1851            { 0x0300, UProperty.GRAPHEME_EXTEND, 1 },
1852            { 0xff9d, UProperty.GRAPHEME_EXTEND, 0 },
1853            { 0xff9f, UProperty.GRAPHEME_EXTEND, 1 },   /* changed from Unicode 3.2 to 4 and again 5 to 5.1 */
1854            { 0x0603, UProperty.GRAPHEME_EXTEND, 0 },
1855
1856            { 0x0a4d, UProperty.GRAPHEME_LINK, 1 },
1857            { 0xff9f, UProperty.GRAPHEME_LINK, 0 },
1858
1859            { 0x2ff7, UProperty.IDS_BINARY_OPERATOR, 1 },
1860            { 0x2ff3, UProperty.IDS_BINARY_OPERATOR, 0 },
1861
1862            { 0x2ff3, UProperty.IDS_TRINARY_OPERATOR, 1 },
1863            { 0x2f03, UProperty.IDS_TRINARY_OPERATOR, 0 },
1864
1865            { 0x0ec1, UProperty.LOGICAL_ORDER_EXCEPTION, 1 },
1866            { 0xdcba, UProperty.LOGICAL_ORDER_EXCEPTION, 0 },
1867
1868            { 0x2e9b, UProperty.RADICAL, 1 },
1869            { 0x4e00, UProperty.RADICAL, 0 },
1870
1871            { 0x012f, UProperty.SOFT_DOTTED, 1 },
1872            { 0x0049, UProperty.SOFT_DOTTED, 0 },
1873
1874            { 0xfa11, UProperty.UNIFIED_IDEOGRAPH, 1 },
1875            { 0xfa12, UProperty.UNIFIED_IDEOGRAPH, 0 },
1876
1877            { -1, 0x401, 0 }, /* version break for Unicode 4.0.1 */
1878
1879            { 0x002e, UProperty.S_TERM, 1 },
1880            { 0x0061, UProperty.S_TERM, 0 },
1881
1882            { 0x180c, UProperty.VARIATION_SELECTOR, 1 },
1883            { 0xfe03, UProperty.VARIATION_SELECTOR, 1 },
1884            { 0xe01ef, UProperty.VARIATION_SELECTOR, 1 },
1885            { 0xe0200, UProperty.VARIATION_SELECTOR, 0 },
1886
1887            /* enum/integer type properties */
1888            /* test default Bidi classes for unassigned code points */
1889            { 0x0590, UProperty.BIDI_CLASS, UCharacterDirection.RIGHT_TO_LEFT },
1890            { 0x05cf, UProperty.BIDI_CLASS, UCharacterDirection.RIGHT_TO_LEFT },
1891            { 0x05ed, UProperty.BIDI_CLASS, UCharacterDirection.RIGHT_TO_LEFT },
1892            { 0x07f2, UProperty.BIDI_CLASS, UCharacterDirection.DIR_NON_SPACING_MARK }, /* Nko, new in Unicode 5.0 */
1893            { 0x07fe, UProperty.BIDI_CLASS, UCharacterDirection.RIGHT_TO_LEFT }, /* unassigned R */
1894            { 0x089f, UProperty.BIDI_CLASS, UCharacterDirection.RIGHT_TO_LEFT },
1895            { 0xfb37, UProperty.BIDI_CLASS, UCharacterDirection.RIGHT_TO_LEFT },
1896            { 0xfb42, UProperty.BIDI_CLASS, UCharacterDirection.RIGHT_TO_LEFT },
1897            { 0x10806, UProperty.BIDI_CLASS, UCharacterDirection.RIGHT_TO_LEFT },
1898            { 0x10909, UProperty.BIDI_CLASS, UCharacterDirection.RIGHT_TO_LEFT },
1899            { 0x10fe4, UProperty.BIDI_CLASS, UCharacterDirection.RIGHT_TO_LEFT },
1900
1901            { 0x061d, UProperty.BIDI_CLASS, UCharacterDirection.RIGHT_TO_LEFT_ARABIC },
1902            { 0x063f, UProperty.BIDI_CLASS, UCharacterDirection.RIGHT_TO_LEFT_ARABIC },
1903            { 0x070e, UProperty.BIDI_CLASS, UCharacterDirection.RIGHT_TO_LEFT_ARABIC },
1904            { 0x0775, UProperty.BIDI_CLASS, UCharacterDirection.RIGHT_TO_LEFT_ARABIC },
1905            { 0xfbc2, UProperty.BIDI_CLASS, UCharacterDirection.RIGHT_TO_LEFT_ARABIC },
1906            { 0xfd90, UProperty.BIDI_CLASS, UCharacterDirection.RIGHT_TO_LEFT_ARABIC },
1907            { 0xfefe, UProperty.BIDI_CLASS, UCharacterDirection.RIGHT_TO_LEFT_ARABIC },
1908
1909            { 0x02AF, UProperty.BLOCK, UCharacter.UnicodeBlock.IPA_EXTENSIONS.getID() },
1910            { 0x0C4E, UProperty.BLOCK, UCharacter.UnicodeBlock.TELUGU.getID()},
1911            { 0x155A, UProperty.BLOCK, UCharacter.UnicodeBlock.UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS.getID() },
1912            { 0x1717, UProperty.BLOCK, UCharacter.UnicodeBlock.TAGALOG.getID() },
1913            { 0x1900, UProperty.BLOCK, UCharacter.UnicodeBlock.LIMBU.getID() },
1914            { 0x1CBF, UProperty.BLOCK, UCharacter.UnicodeBlock.NO_BLOCK.getID()},
1915            { 0x3040, UProperty.BLOCK, UCharacter.UnicodeBlock.HIRAGANA.getID()},
1916            { 0x1D0FF, UProperty.BLOCK, UCharacter.UnicodeBlock.BYZANTINE_MUSICAL_SYMBOLS.getID()},
1917            { 0x50000, UProperty.BLOCK, UCharacter.UnicodeBlock.NO_BLOCK.getID() },
1918            { 0xEFFFF, UProperty.BLOCK, UCharacter.UnicodeBlock.NO_BLOCK.getID() },
1919            { 0x10D0FF, UProperty.BLOCK, UCharacter.UnicodeBlock.SUPPLEMENTARY_PRIVATE_USE_AREA_B.getID() },
1920
1921            /* UProperty.CANONICAL_COMBINING_CLASS tested for assigned characters in TestUnicodeData() */
1922            { 0xd7d7, UProperty.CANONICAL_COMBINING_CLASS, 0 },
1923
1924            { 0x00A0, UProperty.DECOMPOSITION_TYPE, UCharacter.DecompositionType.NOBREAK },
1925            { 0x00A8, UProperty.DECOMPOSITION_TYPE, UCharacter.DecompositionType.COMPAT },
1926            { 0x00bf, UProperty.DECOMPOSITION_TYPE, UCharacter.DecompositionType.NONE },
1927            { 0x00c0, UProperty.DECOMPOSITION_TYPE, UCharacter.DecompositionType.CANONICAL },
1928            { 0x1E9B, UProperty.DECOMPOSITION_TYPE, UCharacter.DecompositionType.CANONICAL },
1929            { 0xBCDE, UProperty.DECOMPOSITION_TYPE, UCharacter.DecompositionType.CANONICAL },
1930            { 0xFB5D, UProperty.DECOMPOSITION_TYPE, UCharacter.DecompositionType.MEDIAL },
1931            { 0x1D736, UProperty.DECOMPOSITION_TYPE, UCharacter.DecompositionType.FONT },
1932            { 0xe0033, UProperty.DECOMPOSITION_TYPE, UCharacter.DecompositionType.NONE },
1933
1934            { 0x0009, UProperty.EAST_ASIAN_WIDTH, UCharacter.EastAsianWidth.NEUTRAL },
1935            { 0x0020, UProperty.EAST_ASIAN_WIDTH, UCharacter.EastAsianWidth.NARROW },
1936            { 0x00B1, UProperty.EAST_ASIAN_WIDTH, UCharacter.EastAsianWidth.AMBIGUOUS },
1937            { 0x20A9, UProperty.EAST_ASIAN_WIDTH, UCharacter.EastAsianWidth.HALFWIDTH },
1938            { 0x2FFB, UProperty.EAST_ASIAN_WIDTH, UCharacter.EastAsianWidth.WIDE },
1939            { 0x3000, UProperty.EAST_ASIAN_WIDTH, UCharacter.EastAsianWidth.FULLWIDTH },
1940            { 0x35bb, UProperty.EAST_ASIAN_WIDTH, UCharacter.EastAsianWidth.WIDE },
1941            { 0x58bd, UProperty.EAST_ASIAN_WIDTH, UCharacter.EastAsianWidth.WIDE },
1942            { 0xD7A3, UProperty.EAST_ASIAN_WIDTH, UCharacter.EastAsianWidth.WIDE },
1943            { 0xEEEE, UProperty.EAST_ASIAN_WIDTH, UCharacter.EastAsianWidth.AMBIGUOUS },
1944            { 0x1D198, UProperty.EAST_ASIAN_WIDTH, UCharacter.EastAsianWidth.NEUTRAL },
1945            { 0x20000, UProperty.EAST_ASIAN_WIDTH, UCharacter.EastAsianWidth.WIDE },
1946            { 0x2F8C7, UProperty.EAST_ASIAN_WIDTH, UCharacter.EastAsianWidth.WIDE },
1947            { 0x3a5bd, UProperty.EAST_ASIAN_WIDTH, UCharacter.EastAsianWidth.WIDE },
1948            { 0x5a5bd, UProperty.EAST_ASIAN_WIDTH, UCharacter.EastAsianWidth.NEUTRAL },
1949            { 0xFEEEE, UProperty.EAST_ASIAN_WIDTH, UCharacter.EastAsianWidth.AMBIGUOUS },
1950            { 0x10EEEE, UProperty.EAST_ASIAN_WIDTH, UCharacter.EastAsianWidth.AMBIGUOUS },
1951
1952            /* UProperty.GENERAL_CATEGORY tested for assigned characters in TestUnicodeData() */
1953            { 0xd7c7, UProperty.GENERAL_CATEGORY, 0 },
1954            { 0xd7d7, UProperty.GENERAL_CATEGORY, UCharacterEnums.ECharacterCategory.OTHER_LETTER },     /* changed in Unicode 5.2 */
1955
1956            { 0x0444, UProperty.JOINING_GROUP, UCharacter.JoiningGroup.NO_JOINING_GROUP },
1957            { 0x0639, UProperty.JOINING_GROUP, UCharacter.JoiningGroup.AIN },
1958            { 0x072A, UProperty.JOINING_GROUP, UCharacter.JoiningGroup.DALATH_RISH },
1959            { 0x0647, UProperty.JOINING_GROUP, UCharacter.JoiningGroup.HEH },
1960            { 0x06C1, UProperty.JOINING_GROUP, UCharacter.JoiningGroup.HEH_GOAL },
1961
1962            { 0x200C, UProperty.JOINING_TYPE, UCharacter.JoiningType.NON_JOINING },
1963            { 0x200D, UProperty.JOINING_TYPE, UCharacter.JoiningType.JOIN_CAUSING },
1964            { 0x0639, UProperty.JOINING_TYPE, UCharacter.JoiningType.DUAL_JOINING },
1965            { 0x0640, UProperty.JOINING_TYPE, UCharacter.JoiningType.JOIN_CAUSING },
1966            { 0x06C3, UProperty.JOINING_TYPE, UCharacter.JoiningType.RIGHT_JOINING },
1967            { 0x0300, UProperty.JOINING_TYPE, UCharacter.JoiningType.TRANSPARENT },
1968            { 0x070F, UProperty.JOINING_TYPE, UCharacter.JoiningType.TRANSPARENT },
1969            { 0xe0033, UProperty.JOINING_TYPE, UCharacter.JoiningType.TRANSPARENT },
1970
1971            /* TestUnicodeData() verifies that no assigned character has "XX" (unknown) */
1972            { 0xe7e7, UProperty.LINE_BREAK, UCharacter.LineBreak.UNKNOWN },
1973            { 0x10fffd, UProperty.LINE_BREAK, UCharacter.LineBreak.UNKNOWN },
1974            { 0x0028, UProperty.LINE_BREAK, UCharacter.LineBreak.OPEN_PUNCTUATION },
1975            { 0x232A, UProperty.LINE_BREAK, UCharacter.LineBreak.CLOSE_PUNCTUATION },
1976            { 0x3401, UProperty.LINE_BREAK, UCharacter.LineBreak.IDEOGRAPHIC },
1977            { 0x4e02, UProperty.LINE_BREAK, UCharacter.LineBreak.IDEOGRAPHIC },
1978            { 0x20004, UProperty.LINE_BREAK, UCharacter.LineBreak.IDEOGRAPHIC },
1979            { 0xf905, UProperty.LINE_BREAK, UCharacter.LineBreak.IDEOGRAPHIC },
1980            { 0xdb7e, UProperty.LINE_BREAK, UCharacter.LineBreak.SURROGATE },
1981            { 0xdbfd, UProperty.LINE_BREAK, UCharacter.LineBreak.SURROGATE },
1982            { 0xdffc, UProperty.LINE_BREAK, UCharacter.LineBreak.SURROGATE },
1983            { 0x2762, UProperty.LINE_BREAK, UCharacter.LineBreak.EXCLAMATION },
1984            { 0x002F, UProperty.LINE_BREAK, UCharacter.LineBreak.BREAK_SYMBOLS },
1985            { 0x1D49C, UProperty.LINE_BREAK, UCharacter.LineBreak.ALPHABETIC },
1986            { 0x1731, UProperty.LINE_BREAK, UCharacter.LineBreak.ALPHABETIC },
1987
1988            /* UProperty.NUMERIC_TYPE tested in TestNumericProperties() */
1989
1990            /* UProperty.SCRIPT tested in TestUScriptCodeAPI() */
1991
1992            { 0x10ff, UProperty.HANGUL_SYLLABLE_TYPE, 0 },
1993            { 0x1100, UProperty.HANGUL_SYLLABLE_TYPE, UCharacter.HangulSyllableType.LEADING_JAMO },
1994            { 0x1111, UProperty.HANGUL_SYLLABLE_TYPE, UCharacter.HangulSyllableType.LEADING_JAMO },
1995            { 0x1159, UProperty.HANGUL_SYLLABLE_TYPE, UCharacter.HangulSyllableType.LEADING_JAMO },
1996            { 0x115a, UProperty.HANGUL_SYLLABLE_TYPE, UCharacter.HangulSyllableType.LEADING_JAMO },     /* changed in Unicode 5.2 */
1997            { 0x115e, UProperty.HANGUL_SYLLABLE_TYPE, UCharacter.HangulSyllableType.LEADING_JAMO },     /* changed in Unicode 5.2 */
1998            { 0x115f, UProperty.HANGUL_SYLLABLE_TYPE, UCharacter.HangulSyllableType.LEADING_JAMO },
1999
2000            { 0xa95f, UProperty.HANGUL_SYLLABLE_TYPE, 0 },
2001            { 0xa960, UProperty.HANGUL_SYLLABLE_TYPE, UCharacter.HangulSyllableType.LEADING_JAMO },     /* changed in Unicode 5.2 */
2002            { 0xa97c, UProperty.HANGUL_SYLLABLE_TYPE, UCharacter.HangulSyllableType.LEADING_JAMO },     /* changed in Unicode 5.2 */
2003            { 0xa97d, UProperty.HANGUL_SYLLABLE_TYPE, 0 },
2004
2005            { 0x1160, UProperty.HANGUL_SYLLABLE_TYPE, UCharacter.HangulSyllableType.VOWEL_JAMO },
2006            { 0x1161, UProperty.HANGUL_SYLLABLE_TYPE, UCharacter.HangulSyllableType.VOWEL_JAMO },
2007            { 0x1172, UProperty.HANGUL_SYLLABLE_TYPE, UCharacter.HangulSyllableType.VOWEL_JAMO },
2008            { 0x11a2, UProperty.HANGUL_SYLLABLE_TYPE, UCharacter.HangulSyllableType.VOWEL_JAMO },
2009            { 0x11a3, UProperty.HANGUL_SYLLABLE_TYPE, UCharacter.HangulSyllableType.VOWEL_JAMO },       /* changed in Unicode 5.2 */
2010            { 0x11a7, UProperty.HANGUL_SYLLABLE_TYPE, UCharacter.HangulSyllableType.VOWEL_JAMO },       /* changed in Unicode 5.2 */
2011
2012            { 0xd7af, UProperty.HANGUL_SYLLABLE_TYPE, 0 },
2013            { 0xd7b0, UProperty.HANGUL_SYLLABLE_TYPE, UCharacter.HangulSyllableType.VOWEL_JAMO },       /* changed in Unicode 5.2 */
2014            { 0xd7c6, UProperty.HANGUL_SYLLABLE_TYPE, UCharacter.HangulSyllableType.VOWEL_JAMO },       /* changed in Unicode 5.2 */
2015            { 0xd7c7, UProperty.HANGUL_SYLLABLE_TYPE, 0 },
2016
2017            { 0x11a8, UProperty.HANGUL_SYLLABLE_TYPE, UCharacter.HangulSyllableType.TRAILING_JAMO },
2018            { 0x11b8, UProperty.HANGUL_SYLLABLE_TYPE, UCharacter.HangulSyllableType.TRAILING_JAMO },
2019            { 0x11c8, UProperty.HANGUL_SYLLABLE_TYPE, UCharacter.HangulSyllableType.TRAILING_JAMO },
2020            { 0x11f9, UProperty.HANGUL_SYLLABLE_TYPE, UCharacter.HangulSyllableType.TRAILING_JAMO },
2021            { 0x11fa, UProperty.HANGUL_SYLLABLE_TYPE, UCharacter.HangulSyllableType.TRAILING_JAMO },    /* changed in Unicode 5.2 */
2022            { 0x11ff, UProperty.HANGUL_SYLLABLE_TYPE, UCharacter.HangulSyllableType.TRAILING_JAMO },    /* changed in Unicode 5.2 */
2023            { 0x1200, UProperty.HANGUL_SYLLABLE_TYPE, 0 },
2024
2025            { 0xd7ca, UProperty.HANGUL_SYLLABLE_TYPE, 0 },
2026            { 0xd7cb, UProperty.HANGUL_SYLLABLE_TYPE, UCharacter.HangulSyllableType.TRAILING_JAMO },    /* changed in Unicode 5.2 */
2027            { 0xd7fb, UProperty.HANGUL_SYLLABLE_TYPE, UCharacter.HangulSyllableType.TRAILING_JAMO },    /* changed in Unicode 5.2 */
2028            { 0xd7fc, UProperty.HANGUL_SYLLABLE_TYPE, 0 },
2029
2030            { 0xac00, UProperty.HANGUL_SYLLABLE_TYPE, UCharacter.HangulSyllableType.LV_SYLLABLE },
2031            { 0xac1c, UProperty.HANGUL_SYLLABLE_TYPE, UCharacter.HangulSyllableType.LV_SYLLABLE },
2032            { 0xc5ec, UProperty.HANGUL_SYLLABLE_TYPE, UCharacter.HangulSyllableType.LV_SYLLABLE },
2033            { 0xd788, UProperty.HANGUL_SYLLABLE_TYPE, UCharacter.HangulSyllableType.LV_SYLLABLE },
2034
2035            { 0xac01, UProperty.HANGUL_SYLLABLE_TYPE, UCharacter.HangulSyllableType.LVT_SYLLABLE },
2036            { 0xac1b, UProperty.HANGUL_SYLLABLE_TYPE, UCharacter.HangulSyllableType.LVT_SYLLABLE },
2037            { 0xac1d, UProperty.HANGUL_SYLLABLE_TYPE, UCharacter.HangulSyllableType.LVT_SYLLABLE },
2038            { 0xc5ee, UProperty.HANGUL_SYLLABLE_TYPE, UCharacter.HangulSyllableType.LVT_SYLLABLE },
2039            { 0xd7a3, UProperty.HANGUL_SYLLABLE_TYPE, UCharacter.HangulSyllableType.LVT_SYLLABLE },
2040
2041            { 0xd7a4, UProperty.HANGUL_SYLLABLE_TYPE, 0 },
2042
2043            { -1, 0x410, 0 }, /* version break for Unicode 4.1 */
2044
2045            { 0x00d7, UProperty.PATTERN_SYNTAX, 1 },
2046            { 0xfe45, UProperty.PATTERN_SYNTAX, 1 },
2047            { 0x0061, UProperty.PATTERN_SYNTAX, 0 },
2048
2049            { 0x0020, UProperty.PATTERN_WHITE_SPACE, 1 },
2050            { 0x0085, UProperty.PATTERN_WHITE_SPACE, 1 },
2051            { 0x200f, UProperty.PATTERN_WHITE_SPACE, 1 },
2052            { 0x00a0, UProperty.PATTERN_WHITE_SPACE, 0 },
2053            { 0x3000, UProperty.PATTERN_WHITE_SPACE, 0 },
2054
2055            { 0x1d200, UProperty.BLOCK, UCharacter.UnicodeBlock.ANCIENT_GREEK_MUSICAL_NOTATION_ID },
2056            { 0x2c8e,  UProperty.BLOCK, UCharacter.UnicodeBlock.COPTIC_ID },
2057            { 0xfe17,  UProperty.BLOCK, UCharacter.UnicodeBlock.VERTICAL_FORMS_ID },
2058
2059            { 0x1a00,  UProperty.SCRIPT, UScript.BUGINESE },
2060            { 0x2cea,  UProperty.SCRIPT, UScript.COPTIC },
2061            { 0xa82b,  UProperty.SCRIPT, UScript.SYLOTI_NAGRI },
2062            { 0x103d0, UProperty.SCRIPT, UScript.OLD_PERSIAN },
2063
2064            { 0xcc28, UProperty.LINE_BREAK, UCharacter.LineBreak.H2 },
2065            { 0xcc29, UProperty.LINE_BREAK, UCharacter.LineBreak.H3 },
2066            { 0xac03, UProperty.LINE_BREAK, UCharacter.LineBreak.H3 },
2067            { 0x115f, UProperty.LINE_BREAK, UCharacter.LineBreak.JL },
2068            { 0x11aa, UProperty.LINE_BREAK, UCharacter.LineBreak.JT },
2069            { 0x11a1, UProperty.LINE_BREAK, UCharacter.LineBreak.JV },
2070
2071            { 0xb2c9, UProperty.GRAPHEME_CLUSTER_BREAK, UCharacter.GraphemeClusterBreak.LVT },
2072            { 0x036f, UProperty.GRAPHEME_CLUSTER_BREAK, UCharacter.GraphemeClusterBreak.EXTEND },
2073            { 0x0000, UProperty.GRAPHEME_CLUSTER_BREAK, UCharacter.GraphemeClusterBreak.CONTROL },
2074            { 0x1160, UProperty.GRAPHEME_CLUSTER_BREAK, UCharacter.GraphemeClusterBreak.V },
2075
2076            { 0x05f4, UProperty.WORD_BREAK, UCharacter.WordBreak.MIDLETTER },
2077            { 0x4ef0, UProperty.WORD_BREAK, UCharacter.WordBreak.OTHER },
2078            { 0x19d9, UProperty.WORD_BREAK, UCharacter.WordBreak.NUMERIC },
2079            { 0x2044, UProperty.WORD_BREAK, UCharacter.WordBreak.MIDNUM },
2080
2081            { 0xfffd, UProperty.SENTENCE_BREAK, UCharacter.SentenceBreak.OTHER },
2082            { 0x1ffc, UProperty.SENTENCE_BREAK, UCharacter.SentenceBreak.UPPER },
2083            { 0xff63, UProperty.SENTENCE_BREAK, UCharacter.SentenceBreak.CLOSE },
2084            { 0x2028, UProperty.SENTENCE_BREAK, UCharacter.SentenceBreak.SEP },
2085
2086            { -1, 0x520, 0 }, /* version break for Unicode 5.2 */
2087
2088            /* unassigned code points in new default Bidi R blocks */
2089            { 0x1ede4, UProperty.BIDI_CLASS, UCharacterDirection.RIGHT_TO_LEFT },
2090            { 0x1efe4, UProperty.BIDI_CLASS, UCharacterDirection.RIGHT_TO_LEFT },
2091
2092            /* test some script codes >127 */
2093            { 0xa6e6,  UProperty.SCRIPT, UScript.BAMUM },
2094            { 0xa4d0,  UProperty.SCRIPT, UScript.LISU },
2095            { 0x10a7f,  UProperty.SCRIPT, UScript.OLD_SOUTH_ARABIAN },
2096
2097            { -1, 0x600, 0 }, /* version break for Unicode 6.0 */
2098
2099            /* value changed in Unicode 6.0 */
2100            { 0x06C3, UProperty.JOINING_GROUP, UCharacter.JoiningGroup.TEH_MARBUTA_GOAL },
2101
2102            { -1, 0x610, 0 }, /* version break for Unicode 6.1 */
2103
2104            /* unassigned code points in new/changed default Bidi AL blocks */
2105            { 0x08ba, UProperty.BIDI_CLASS, UCharacterDirection.RIGHT_TO_LEFT_ARABIC },
2106            { 0x1eee4, UProperty.BIDI_CLASS, UCharacterDirection.RIGHT_TO_LEFT_ARABIC },
2107
2108            { -1, 0x630, 0 }, /* version break for Unicode 6.3 */
2109
2110            /* unassigned code points in the currency symbols block now default to ET */
2111            { 0x20C0, UProperty.BIDI_CLASS, UCharacterDirection.EUROPEAN_NUMBER_TERMINATOR },
2112            { 0x20CF, UProperty.BIDI_CLASS, UCharacterDirection.EUROPEAN_NUMBER_TERMINATOR },
2113
2114            /* new property in Unicode 6.3 */
2115            { 0x0027, UProperty.BIDI_PAIRED_BRACKET_TYPE, UCharacter.BidiPairedBracketType.NONE },
2116            { 0x0028, UProperty.BIDI_PAIRED_BRACKET_TYPE, UCharacter.BidiPairedBracketType.OPEN },
2117            { 0x0029, UProperty.BIDI_PAIRED_BRACKET_TYPE, UCharacter.BidiPairedBracketType.CLOSE },
2118            { 0xFF5C, UProperty.BIDI_PAIRED_BRACKET_TYPE, UCharacter.BidiPairedBracketType.NONE },
2119            { 0xFF5B, UProperty.BIDI_PAIRED_BRACKET_TYPE, UCharacter.BidiPairedBracketType.OPEN },
2120            { 0xFF5D, UProperty.BIDI_PAIRED_BRACKET_TYPE, UCharacter.BidiPairedBracketType.CLOSE },
2121
2122            { -1, 0x700, 0 }, /* version break for Unicode 7.0 */
2123
2124            /* new character range with Joining_Group values */
2125            { 0x10ABF, UProperty.JOINING_GROUP, UCharacter.JoiningGroup.NO_JOINING_GROUP },
2126            { 0x10AC0, UProperty.JOINING_GROUP, UCharacter.JoiningGroup.MANICHAEAN_ALEPH },
2127            { 0x10AC1, UProperty.JOINING_GROUP, UCharacter.JoiningGroup.MANICHAEAN_BETH },
2128            { 0x10AEF, UProperty.JOINING_GROUP, UCharacter.JoiningGroup.MANICHAEAN_HUNDRED },
2129            { 0x10AF0, UProperty.JOINING_GROUP, UCharacter.JoiningGroup.NO_JOINING_GROUP },
2130
2131            /* undefined UProperty values */
2132            { 0x61, 0x4a7, 0 },
2133            { 0x234bc, 0x15ed, 0 }
2134        };
2135
2136
2137        if (UCharacter.getIntPropertyMinValue(UProperty.DASH) != 0
2138            || UCharacter.getIntPropertyMinValue(UProperty.BIDI_CLASS) != 0
2139            || UCharacter.getIntPropertyMinValue(UProperty.BLOCK)!= 0  /* j2478 */
2140            || UCharacter.getIntPropertyMinValue(UProperty.SCRIPT)!= 0 /* JB#2410 */
2141            || UCharacter.getIntPropertyMinValue(0x2345) != 0) {
2142            errln("error: UCharacter.getIntPropertyMinValue() wrong");
2143        }
2144
2145        if( UCharacter.getIntPropertyMaxValue(UProperty.DASH)!=1) {
2146            errln("error: UCharacter.getIntPropertyMaxValue(UProperty.DASH) wrong\n");
2147        }
2148        if( UCharacter.getIntPropertyMaxValue(UProperty.ID_CONTINUE)!=1) {
2149            errln("error: UCharacter.getIntPropertyMaxValue(UProperty.ID_CONTINUE) wrong\n");
2150        }
2151        if( UCharacter.getIntPropertyMaxValue(UProperty.BINARY_LIMIT-1)!=1) {
2152            errln("error: UCharacter.getIntPropertyMaxValue(UProperty.BINARY_LIMIT-1) wrong\n");
2153        }
2154
2155        if( UCharacter.getIntPropertyMaxValue(UProperty.BIDI_CLASS)!=UCharacterDirection.CHAR_DIRECTION_COUNT-1 ) {
2156            errln("error: UCharacter.getIntPropertyMaxValue(UProperty.BIDI_CLASS) wrong\n");
2157        }
2158        if( UCharacter.getIntPropertyMaxValue(UProperty.BLOCK)!=UCharacter.UnicodeBlock.COUNT-1 ) {
2159            errln("error: UCharacter.getIntPropertyMaxValue(UProperty.BLOCK) wrong\n");
2160        }
2161        if(UCharacter.getIntPropertyMaxValue(UProperty.LINE_BREAK)!=UCharacter.LineBreak.COUNT-1) {
2162            errln("error: UCharacter.getIntPropertyMaxValue(UProperty.LINE_BREAK) wrong\n");
2163        }
2164        if(UCharacter.getIntPropertyMaxValue(UProperty.SCRIPT)!=UScript.CODE_LIMIT-1) {
2165            errln("error: UCharacter.getIntPropertyMaxValue(UProperty.SCRIPT) wrong\n");
2166        }
2167        if(UCharacter.getIntPropertyMaxValue(UProperty.NUMERIC_TYPE)!=UCharacter.NumericType.COUNT-1) {
2168            errln("error: UCharacter.getIntPropertyMaxValue(UProperty.NUMERIC_TYPE) wrong\n");
2169        }
2170        if(UCharacter.getIntPropertyMaxValue(UProperty.GENERAL_CATEGORY)!=UCharacterCategory.CHAR_CATEGORY_COUNT-1) {
2171            errln("error: UCharacter.getIntPropertyMaxValue(UProperty.GENERAL_CATEGORY) wrong\n");
2172        }
2173        if(UCharacter.getIntPropertyMaxValue(UProperty.HANGUL_SYLLABLE_TYPE)!=UCharacter.HangulSyllableType.COUNT-1) {
2174            errln("error: UCharacter.getIntPropertyMaxValue(UProperty.HANGUL_SYLLABLE_TYPE) wrong\n");
2175        }
2176        if(UCharacter.getIntPropertyMaxValue(UProperty.GRAPHEME_CLUSTER_BREAK)!=UCharacter.GraphemeClusterBreak.COUNT-1) {
2177            errln("error: UCharacter.getIntPropertyMaxValue(UProperty.GRAPHEME_CLUSTER_BREAK) wrong\n");
2178        }
2179        if(UCharacter.getIntPropertyMaxValue(UProperty.SENTENCE_BREAK)!=UCharacter.SentenceBreak.COUNT-1) {
2180            errln("error: UCharacter.getIntPropertyMaxValue(UProperty.SENTENCE_BREAK) wrong\n");
2181        }
2182        if(UCharacter.getIntPropertyMaxValue(UProperty.WORD_BREAK)!=UCharacter.WordBreak.COUNT-1) {
2183            errln("error: UCharacter.getIntPropertyMaxValue(UProperty.WORD_BREAK) wrong\n");
2184        }
2185        if(UCharacter.getIntPropertyMaxValue(UProperty.BIDI_PAIRED_BRACKET_TYPE)!=UCharacter.BidiPairedBracketType.COUNT-1) {
2186            errln("error: UCharacter.getIntPropertyMaxValue(UProperty.BIDI_PAIRED_BRACKET_TYPE) wrong\n");
2187        }
2188        /*JB#2410*/
2189        if( UCharacter.getIntPropertyMaxValue(0x2345)!=-1) {
2190            errln("error: UCharacter.getIntPropertyMaxValue(0x2345) wrong\n");
2191        }
2192        if( UCharacter.getIntPropertyMaxValue(UProperty.DECOMPOSITION_TYPE) !=  (UCharacter.DecompositionType.COUNT - 1)) {
2193            errln("error: UCharacter.getIntPropertyMaxValue(UProperty.DECOMPOSITION_TYPE) wrong\n");
2194        }
2195        if( UCharacter.getIntPropertyMaxValue(UProperty.JOINING_GROUP) !=   (UCharacter.JoiningGroup.COUNT -1)) {
2196            errln("error: UCharacter.getIntPropertyMaxValue(UProperty.JOINING_GROUP) wrong\n");
2197        }
2198        if( UCharacter.getIntPropertyMaxValue(UProperty.JOINING_TYPE) !=  (UCharacter.JoiningType.COUNT -1)) {
2199            errln("error: UCharacter.getIntPropertyMaxValue(UProperty.JOINING_TYPE) wrong\n");
2200        }
2201        if( UCharacter.getIntPropertyMaxValue(UProperty.EAST_ASIAN_WIDTH) !=  (UCharacter.EastAsianWidth.COUNT -1)) {
2202            errln("error: UCharacter.getIntPropertyMaxValue(UProperty.EAST_ASIAN_WIDTH) wrong\n");
2203        }
2204
2205        VersionInfo version = UCharacter.getUnicodeVersion();
2206
2207        // test hasBinaryProperty()
2208        for (int i = 0; i < props.length; ++ i) {
2209            int which = props[i][1];
2210            if (props[i][0] < 0) {
2211                if (version.compareTo(VersionInfo.getInstance(which >> 8,
2212                                                          (which >> 4) & 0xF,
2213                                                          which & 0xF,
2214                                                          0)) < 0) {
2215                    break;
2216                }
2217                continue;
2218            }
2219            String whichName;
2220            try {
2221                whichName = UCharacter.getPropertyName(which, UProperty.NameChoice.LONG);
2222            } catch(IllegalArgumentException e) {
2223                // There are intentionally invalid property integer values ("which").
2224                // Catch and ignore the exception from getPropertyName().
2225                whichName = "undefined UProperty value";
2226            }
2227            boolean expect = true;
2228            if (props[i][2] == 0) {
2229                expect = false;
2230            }
2231            if (which < UProperty.INT_START) {
2232                if (UCharacter.hasBinaryProperty(props[i][0], which)
2233                    != expect) {
2234                    errln("error: UCharacter.hasBinaryProperty(U+" +
2235                            Utility.hex(props[i][0], 4) + ", " +
2236                          whichName + ") has an error, expected=" + expect);
2237                }
2238            }
2239
2240            int retVal = UCharacter.getIntPropertyValue(props[i][0], which);
2241            if (retVal != props[i][2]) {
2242                errln("error: UCharacter.getIntPropertyValue(U+" +
2243                      Utility.hex(props[i][0], 4) +
2244                      ", " + whichName + ") is wrong, expected="
2245                      + props[i][2] + " actual=" + retVal);
2246            }
2247
2248            // test separate functions, too
2249            switch (which) {
2250            case UProperty.ALPHABETIC:
2251                if (UCharacter.isUAlphabetic(props[i][0]) != expect) {
2252                    errln("error: UCharacter.isUAlphabetic(\\u" +
2253                          Integer.toHexString(props[i][0]) +
2254                          ") is wrong expected " + props[i][2]);
2255                }
2256                break;
2257            case UProperty.LOWERCASE:
2258                if (UCharacter.isULowercase(props[i][0]) != expect) {
2259                    errln("error: UCharacter.isULowercase(\\u" +
2260                          Integer.toHexString(props[i][0]) +
2261                          ") is wrong expected " +props[i][2]);
2262                }
2263                break;
2264            case UProperty.UPPERCASE:
2265                if (UCharacter.isUUppercase(props[i][0]) != expect) {
2266                    errln("error: UCharacter.isUUppercase(\\u" +
2267                          Integer.toHexString(props[i][0]) +
2268                          ") is wrong expected " + props[i][2]);
2269                }
2270                break;
2271            case UProperty.WHITE_SPACE:
2272                if (UCharacter.isUWhiteSpace(props[i][0]) != expect) {
2273                    errln("error: UCharacter.isUWhiteSpace(\\u" +
2274                          Integer.toHexString(props[i][0]) +
2275                          ") is wrong expected " + props[i][2]);
2276                }
2277                break;
2278            default:
2279                break;
2280            }
2281        }
2282    }
2283
2284    public void TestNumericProperties()
2285    {
2286        // see UnicodeData.txt, DerivedNumericValues.txt
2287        double values[][] = {
2288            // Code point, numeric type, numeric value.
2289            // If a fourth value is specified, it is the getNumericValue().
2290            // Otherwise it is expected to be the same as the getUnicodeNumericValue(),
2291            // where UCharacter.NO_NUMERIC_VALUE is turned into -1.
2292            // getNumericValue() returns -2 if the code point has a value
2293            // which is not a non-negative integer. (This is mostly auto-converted to -2.)
2294            { 0x0F33, UCharacter.NumericType.NUMERIC, -1./2. },
2295            { 0x0C66, UCharacter.NumericType.DECIMAL, 0 },
2296            { 0x96f6, UCharacter.NumericType.NUMERIC, 0 },
2297            { 0xa833, UCharacter.NumericType.NUMERIC, 1./16. },
2298            { 0x2152, UCharacter.NumericType.NUMERIC, 1./10. },
2299            { 0x2151, UCharacter.NumericType.NUMERIC, 1./9. },
2300            { 0x1245f, UCharacter.NumericType.NUMERIC, 1./8. },
2301            { 0x2150, UCharacter.NumericType.NUMERIC, 1./7. },
2302            { 0x2159, UCharacter.NumericType.NUMERIC, 1./6. },
2303            { 0x09f6, UCharacter.NumericType.NUMERIC, 3./16. },
2304            { 0x2155, UCharacter.NumericType.NUMERIC, 1./5. },
2305            { 0x00BD, UCharacter.NumericType.NUMERIC, 1./2. },
2306            { 0x0031, UCharacter.NumericType.DECIMAL, 1. },
2307            { 0x4e00, UCharacter.NumericType.NUMERIC, 1. },
2308            { 0x58f1, UCharacter.NumericType.NUMERIC, 1. },
2309            { 0x10320, UCharacter.NumericType.NUMERIC, 1. },
2310            { 0x0F2B, UCharacter.NumericType.NUMERIC, 3./2. },
2311            { 0x00B2, UCharacter.NumericType.DIGIT, 2. }, /* Unicode 4.0 change */
2312            { 0x5f10, UCharacter.NumericType.NUMERIC, 2. },
2313            { 0x1813, UCharacter.NumericType.DECIMAL, 3. },
2314            { 0x5f0e, UCharacter.NumericType.NUMERIC, 3. },
2315            { 0x2173, UCharacter.NumericType.NUMERIC, 4. },
2316            { 0x8086, UCharacter.NumericType.NUMERIC, 4. },
2317            { 0x278E, UCharacter.NumericType.DIGIT, 5. },
2318            { 0x1D7F2, UCharacter.NumericType.DECIMAL, 6. },
2319            { 0x247A, UCharacter.NumericType.DIGIT, 7. },
2320            { 0x7396, UCharacter.NumericType.NUMERIC, 9. },
2321            { 0x1372, UCharacter.NumericType.NUMERIC, 10. },
2322            { 0x216B, UCharacter.NumericType.NUMERIC, 12. },
2323            { 0x16EE, UCharacter.NumericType.NUMERIC, 17. },
2324            { 0x249A, UCharacter.NumericType.NUMERIC, 19. },
2325            { 0x303A, UCharacter.NumericType.NUMERIC, 30. },
2326            { 0x5345, UCharacter.NumericType.NUMERIC, 30. },
2327            { 0x32B2, UCharacter.NumericType.NUMERIC, 37. },
2328            { 0x1375, UCharacter.NumericType.NUMERIC, 40. },
2329            { 0x10323, UCharacter.NumericType.NUMERIC, 50. },
2330            { 0x0BF1, UCharacter.NumericType.NUMERIC, 100. },
2331            { 0x964c, UCharacter.NumericType.NUMERIC, 100. },
2332            { 0x217E, UCharacter.NumericType.NUMERIC, 500. },
2333            { 0x2180, UCharacter.NumericType.NUMERIC, 1000. },
2334            { 0x4edf, UCharacter.NumericType.NUMERIC, 1000. },
2335            { 0x2181, UCharacter.NumericType.NUMERIC, 5000. },
2336            { 0x137C, UCharacter.NumericType.NUMERIC, 10000. },
2337            { 0x4e07, UCharacter.NumericType.NUMERIC, 10000. },
2338            { 0x12432, UCharacter.NumericType.NUMERIC, 216000. },
2339            { 0x12433, UCharacter.NumericType.NUMERIC, 432000. },
2340            { 0x4ebf, UCharacter.NumericType.NUMERIC, 100000000. },
2341            { 0x5146, UCharacter.NumericType.NUMERIC, 1000000000000. },
2342            { -1, UCharacter.NumericType.NONE, UCharacter.NO_NUMERIC_VALUE },
2343            { 0x61, UCharacter.NumericType.NONE, UCharacter.NO_NUMERIC_VALUE, 10. },
2344            { 0x3000, UCharacter.NumericType.NONE, UCharacter.NO_NUMERIC_VALUE },
2345            { 0xfffe, UCharacter.NumericType.NONE, UCharacter.NO_NUMERIC_VALUE },
2346            { 0x10301, UCharacter.NumericType.NONE, UCharacter.NO_NUMERIC_VALUE },
2347            { 0xe0033, UCharacter.NumericType.NONE, UCharacter.NO_NUMERIC_VALUE },
2348            { 0x10ffff, UCharacter.NumericType.NONE, UCharacter.NO_NUMERIC_VALUE },
2349            { 0x110000, UCharacter.NumericType.NONE, UCharacter.NO_NUMERIC_VALUE }
2350        };
2351
2352        for (int i = 0; i < values.length; ++ i) {
2353            int c = (int)values[i][0];
2354            int type = UCharacter.getIntPropertyValue(c,
2355                                                      UProperty.NUMERIC_TYPE);
2356            double nv = UCharacter.getUnicodeNumericValue(c);
2357
2358            if (type != values[i][1]) {
2359                errln("UProperty.NUMERIC_TYPE(\\u" + Utility.hex(c, 4)
2360                       + ") = " + type + " should be " + (int)values[i][1]);
2361            }
2362            if (0.000001 <= Math.abs(nv - values[i][2])) {
2363                errln("UCharacter.getUnicodeNumericValue(\\u" + Utility.hex(c, 4)
2364                        + ") = " + nv + " should be " + values[i][2]);
2365            }
2366
2367            // Test getNumericValue() as well.
2368            // It can only return the subset of numeric values that are
2369            // non-negative and fit into an int.
2370            int expectedInt;
2371            if (values[i].length == 3) {
2372                if (values[i][2] == UCharacter.NO_NUMERIC_VALUE) {
2373                    expectedInt = -1;
2374                } else {
2375                    expectedInt = (int)values[i][2];
2376                    if (expectedInt < 0 || expectedInt != values[i][2]) {
2377                        // The numeric value is not a non-negative integer.
2378                        expectedInt = -2;
2379                    }
2380                }
2381            } else {
2382                expectedInt = (int)values[i][3];
2383            }
2384            int nvInt = UCharacter.getNumericValue(c);
2385            if (nvInt != expectedInt) {
2386                errln("UCharacter.getNumericValue(\\u" + Utility.hex(c, 4)
2387                        + ") = " + nvInt + " should be " + expectedInt);
2388            }
2389        }
2390    }
2391
2392    /**
2393     * Test the property values API.  See JB#2410.
2394     */
2395    public void TestPropertyValues() {
2396        int i, p, min, max;
2397
2398        /* Min should be 0 for everything. */
2399        /* Until JB#2478 is fixed, the one exception is UProperty.BLOCK. */
2400        for (p=UProperty.INT_START; p<UProperty.INT_LIMIT; ++p) {
2401            min = UCharacter.getIntPropertyMinValue(p);
2402            if (min != 0) {
2403                if (p == UProperty.BLOCK) {
2404                    /* This is okay...for now.  See JB#2487.
2405                       TODO Update this for JB#2487. */
2406                } else {
2407                    String name;
2408                    name = UCharacter.getPropertyName(p, UProperty.NameChoice.LONG);
2409                    errln("FAIL: UCharacter.getIntPropertyMinValue(" + name + ") = " +
2410                          min + ", exp. 0");
2411                }
2412            }
2413        }
2414
2415        if (UCharacter.getIntPropertyMinValue(UProperty.GENERAL_CATEGORY_MASK)
2416            != 0
2417            || UCharacter.getIntPropertyMaxValue(
2418                                               UProperty.GENERAL_CATEGORY_MASK)
2419               != -1) {
2420            errln("error: UCharacter.getIntPropertyMin/MaxValue("
2421                  + "UProperty.GENERAL_CATEGORY_MASK) is wrong");
2422        }
2423
2424        /* Max should be -1 for invalid properties. */
2425        max = UCharacter.getIntPropertyMaxValue(-1);
2426        if (max != -1) {
2427            errln("FAIL: UCharacter.getIntPropertyMaxValue(-1) = " +
2428                  max + ", exp. -1");
2429        }
2430
2431        /* Script should return 0 for an invalid code point. If the API
2432           throws an exception then that's fine too. */
2433        for (i=0; i<2; ++i) {
2434            try {
2435                int script = 0;
2436                String desc = null;
2437                switch (i) {
2438                case 0:
2439                    script = UScript.getScript(-1);
2440                    desc = "UScript.getScript(-1)";
2441                    break;
2442                case 1:
2443                    script = UCharacter.getIntPropertyValue(-1, UProperty.SCRIPT);
2444                    desc = "UCharacter.getIntPropertyValue(-1, UProperty.SCRIPT)";
2445                    break;
2446                }
2447                if (script != 0) {
2448                    errln("FAIL: " + desc + " = " + script + ", exp. 0");
2449                }
2450            } catch (IllegalArgumentException e) {}
2451        }
2452    }
2453
2454    public void TestBidiPairedBracketType() {
2455        // BidiBrackets-6.3.0.txt says:
2456        //
2457        // The set of code points listed in this file was originally derived
2458        // using the character properties General_Category (gc), Bidi_Class (bc),
2459        // Bidi_Mirrored (Bidi_M), and Bidi_Mirroring_Glyph (bmg), as follows:
2460        // two characters, A and B, form a pair if A has gc=Ps and B has gc=Pe,
2461        // both have bc=ON and Bidi_M=Y, and bmg of A is B. Bidi_Paired_Bracket
2462        // maps A to B and vice versa, and their Bidi_Paired_Bracket_Type
2463        // property values are Open and Close, respectively.
2464        UnicodeSet bpt = new UnicodeSet("[:^bpt=n:]");
2465        assertTrue("bpt!=None is not empty", !bpt.isEmpty());
2466        // The following should always be true.
2467        UnicodeSet mirrored = new UnicodeSet("[:Bidi_M:]");
2468        UnicodeSet other_neutral = new UnicodeSet("[:bc=ON:]");
2469        assertTrue("bpt!=None is a subset of Bidi_M", mirrored.containsAll(bpt));
2470        assertTrue("bpt!=None is a subset of bc=ON", other_neutral.containsAll(bpt));
2471        // The following are true at least initially in Unicode 6.3.
2472        UnicodeSet bpt_open = new UnicodeSet("[:bpt=o:]");
2473        UnicodeSet bpt_close = new UnicodeSet("[:bpt=c:]");
2474        UnicodeSet ps = new UnicodeSet("[:Ps:]");
2475        UnicodeSet pe = new UnicodeSet("[:Pe:]");
2476        assertTrue("bpt=Open is a subset of Ps", ps.containsAll(bpt_open));
2477        assertTrue("bpt=Close is a subset of Pe", pe.containsAll(bpt_close));
2478    }
2479
2480    public void TestIsBMP()
2481    {
2482        int ch[] = {0x0, -1, 0xffff, 0x10ffff, 0xff, 0x1ffff};
2483        boolean flag[] = {true, false, true, false, true, false};
2484        for (int i = 0; i < ch.length; i ++) {
2485            if (UCharacter.isBMP(ch[i]) != flag[i]) {
2486                errln("Fail: \\u" + Utility.hex(ch[i], 8)
2487                      + " failed at UCharacter.isBMP");
2488            }
2489        }
2490    }
2491
2492    private boolean showADiffB(UnicodeSet a, UnicodeSet b,
2493                                        String a_name, String b_name,
2494                                        boolean expect,
2495                                        boolean diffIsError){
2496        int i, start, end;
2497        boolean equal=true;
2498        for(i=0; i < a.getRangeCount(); ++i) {
2499            start  = a.getRangeStart(i);
2500            end    = a.getRangeEnd(i);
2501            if(expect!=b.contains(start, end)) {
2502                equal=false;
2503                while(start<=end) {
2504                    if(expect!=b.contains(start)) {
2505                        if(diffIsError) {
2506                            if(expect) {
2507                                errln("error: "+ a_name +" contains "+ hex(start)+" but "+ b_name +" does not");
2508                            } else {
2509                                errln("error: "+a_name +" and "+ b_name+" both contain "+hex(start) +" but should not intersect");
2510                            }
2511                        } else {
2512                            if(expect) {
2513                                logln("info: "+a_name +" contains "+hex(start)+ "but " + b_name +" does not");
2514                            } else {
2515                                logln("info: "+a_name +" and "+b_name+" both contain "+hex(start)+" but should not intersect");
2516                            }
2517                        }
2518                    }
2519                    ++start;
2520                }
2521            }
2522        }
2523        return equal;
2524    }
2525    private boolean showAMinusB(UnicodeSet a, UnicodeSet b,
2526                                        String a_name, String b_name,
2527                                        boolean diffIsError) {
2528
2529        return showADiffB(a, b, a_name, b_name, true, diffIsError);
2530    }
2531
2532    private boolean showAIntersectB(UnicodeSet a, UnicodeSet b,
2533                                            String a_name, String b_name,
2534                                            boolean diffIsError) {
2535        return showADiffB(a, b, a_name, b_name, false, diffIsError);
2536    }
2537
2538    private boolean compareUSets(UnicodeSet a, UnicodeSet b,
2539                                         String a_name, String b_name,
2540                                         boolean diffIsError) {
2541        return
2542            showAMinusB(a, b, a_name, b_name, diffIsError) &&
2543            showAMinusB(b, a, b_name, a_name, diffIsError);
2544    }
2545
2546   /* various tests for consistency of UCD data and API behavior */
2547   public void TestConsistency() {
2548       UnicodeSet set1, set2, set3, set4;
2549
2550       int start, end;
2551       int i, length;
2552
2553       String hyphenPattern = "[:Hyphen:]";
2554       String dashPattern = "[:Dash:]";
2555       String lowerPattern = "[:Lowercase:]";
2556       String formatPattern = "[:Cf:]";
2557       String alphaPattern  =  "[:Alphabetic:]";
2558
2559       /*
2560        * It used to be that UCD.html and its precursors said
2561        * "Those dashes used to mark connections between pieces of words,
2562        *  plus the Katakana middle dot."
2563        *
2564        * Unicode 4 changed 00AD Soft Hyphen to Cf and removed it from Dash
2565        * but not from Hyphen.
2566        * UTC 94 (2003mar) decided to leave it that way and to change UCD.html.
2567        * Therefore, do not show errors when testing the Hyphen property.
2568        */
2569       logln("Starting with Unicode 4, inconsistencies with [:Hyphen:] are\n"
2570                   + "known to the UTC and not considered errors.\n");
2571
2572       set1=new UnicodeSet(hyphenPattern);
2573       set2=new UnicodeSet(dashPattern);
2574
2575           /* remove the Katakana middle dot(s) from set1 */
2576           set1.remove(0x30fb);
2577           set2.remove (0xff65); /* halfwidth variant */
2578           showAMinusB(set1, set2, "[:Hyphen:]", "[:Dash:]", false);
2579
2580
2581       /* check that Cf is neither Hyphen nor Dash nor Alphabetic */
2582       set3=new UnicodeSet(formatPattern);
2583       set4=new UnicodeSet(alphaPattern);
2584
2585       showAIntersectB(set3, set1, "[:Cf:]", "[:Hyphen:]", false);
2586       showAIntersectB(set3, set2, "[:Cf:]", "[:Dash:]", true);
2587       showAIntersectB(set3, set4, "[:Cf:]", "[:Alphabetic:]", true);
2588       /*
2589        * Check that each lowercase character has "small" in its name
2590        * and not "capital".
2591        * There are some such characters, some of which seem odd.
2592        * Use the verbose flag to see these notices.
2593        */
2594       set1=new UnicodeSet(lowerPattern);
2595
2596       for(i=0;; ++i) {
2597//               try{
2598//                   length=set1.getItem(set1, i, &start, &end, NULL, 0, &errorCode);
2599//               }catch(Exception e){
2600//                   break;
2601//               }
2602            start = set1.getRangeStart(i);
2603            end = set1.getRangeEnd(i);
2604            length = i<set1.getRangeCount() ? set1.getRangeCount() : 0;
2605           if(length!=0) {
2606               break; /* done with code points, got a string or -1 */
2607           }
2608
2609           while(start<=end) {
2610               String name=UCharacter.getName(start);
2611
2612               if( (name.indexOf("SMALL")< 0 || name.indexOf("CAPITAL")<-1) &&
2613                   name.indexOf("SMALL CAPITAL")==-1
2614               ) {
2615                   logln("info: [:Lowercase:] contains U+"+hex(start) + " whose name does not suggest lowercase: " + name);
2616               }
2617               ++start;
2618           }
2619       }
2620
2621
2622       /*
2623        * Test for an example that unorm_getCanonStartSet() delivers
2624        * all characters that compose from the input one,
2625        * even in multiple steps.
2626        * For example, the set for "I" (0049) should contain both
2627        * I-diaeresis (00CF) and I-diaeresis-acute (1E2E).
2628        * In general, the set for the middle such character should be a subset
2629        * of the set for the first.
2630        */
2631       Normalizer2 norm2=Normalizer2.getNFDInstance();
2632       set1=new UnicodeSet();
2633       Norm2AllModes.getNFCInstance().impl.
2634           ensureCanonIterData().getCanonStartSet(0x49, set1);
2635       set2=new UnicodeSet();
2636
2637       /* enumerate all characters that are plausible to be latin letters */
2638       for(start=0xa0; start<0x2000; ++start) {
2639           String decomp=norm2.normalize(UTF16.valueOf(start));
2640           if(decomp.length() > 1 && decomp.charAt(0)==0x49) {
2641               set2.add(start);
2642           }
2643       }
2644
2645       compareUSets(set1, set2,
2646                    "[canon start set of 0049]", "[all c with canon decomp with 0049]",
2647                    false);
2648
2649   }
2650
2651    public void TestCoverage() {
2652        //cover forDigit
2653        char ch1 = UCharacter.forDigit(7, 11);
2654        assertEquals("UCharacter.forDigit ", "7", String.valueOf(ch1));
2655        char ch2 = UCharacter.forDigit(17, 20);
2656        assertEquals("UCharacter.forDigit ", "h", String.valueOf(ch2));
2657
2658        //Jitterbug 4451, for coverage
2659        for (int i = 0x0041; i < 0x005B; i++) {
2660            if (!UCharacter.isJavaLetter(i))
2661                errln("FAIL \\u" + hex(i) + " expected to be a letter");
2662            if (!UCharacter.isJavaIdentifierStart(i))
2663                errln("FAIL \\u" + hex(i) + " expected to be a Java identifier start character");
2664            if (!UCharacter.isJavaLetterOrDigit(i))
2665                errln("FAIL \\u" + hex(i) + " expected not to be a Java letter");
2666            if (!UCharacter.isJavaIdentifierPart(i))
2667                errln("FAIL \\u" + hex(i) + " expected to be a Java identifier part character");
2668        }
2669        char[] spaces = {'\t','\n','\f','\r',' '};
2670        for (int i = 0; i < spaces.length; i++){
2671            if (!UCharacter.isSpace(spaces[i]))
2672                errln("FAIL \\u" + hex(spaces[i]) + " expected to be a Java space");
2673        }
2674    }
2675
2676    public void TestBlockData()
2677    {
2678        Class ubc = UCharacter.UnicodeBlock.class;
2679
2680        for (int b = 1; b < UCharacter.UnicodeBlock.COUNT; b += 1) {
2681            UCharacter.UnicodeBlock blk = UCharacter.UnicodeBlock.getInstance(b);
2682            int id = blk.getID();
2683            String name = blk.toString();
2684
2685            if (id != b) {
2686                errln("UCharacter.UnicodeBlock.getInstance(" + b + ") returned a block with id = " + id);
2687            }
2688
2689            try {
2690                if (ubc.getField(name + "_ID").getInt(blk) != b) {
2691                    errln("UCharacter.UnicodeBlock.getInstance(" + b + ") returned a block with a name of " + name +
2692                          " which does not match the block id.");
2693                }
2694            } catch (Exception e) {
2695                errln("Couldn't get the id name for id " + b);
2696            }
2697        }
2698    }
2699
2700    /*
2701     * The following method tests
2702     *      public static UnicodeBlock getInstance(int id)
2703     */
2704    public void TestGetInstance(){
2705        // Testing values for invalid and valid ID
2706        int[] invalid_test = {-1,-10,-100};
2707        for(int i=0; i< invalid_test.length; i++){
2708            if(UCharacter.UnicodeBlock.INVALID_CODE != UCharacter.UnicodeBlock.getInstance(invalid_test[i])){
2709                errln("UCharacter.UnicodeBlock.getInstance(invalid_test[i]) was " +
2710                        "suppose to return UCharacter.UnicodeBlock.INVALID_CODE. Got " +
2711                        UCharacter.UnicodeBlock.getInstance(invalid_test[i]) + ". Expected " +
2712                        UCharacter.UnicodeBlock.INVALID_CODE);
2713            }
2714        }
2715    }
2716
2717    /*
2718     * The following method tests
2719     *      public static UnicodeBlock of(int ch)
2720     */
2721    public void TestOf(){
2722        if(UCharacter.UnicodeBlock.INVALID_CODE != UCharacter.UnicodeBlock.of(UTF16.CODEPOINT_MAX_VALUE+1)){
2723            errln("UCharacter.UnicodeBlock.of(UTF16.CODEPOINT_MAX_VALUE+1) was " +
2724                    "suppose to return UCharacter.UnicodeBlock.INVALID_CODE. Got " +
2725                    UCharacter.UnicodeBlock.of(UTF16.CODEPOINT_MAX_VALUE+1) + ". Expected " +
2726                    UCharacter.UnicodeBlock.INVALID_CODE);
2727        }
2728    }
2729
2730    /*
2731     * The following method tests
2732     *      public static final UnicodeBlock forName(String blockName)
2733     */
2734    public void TestForName(){
2735        //UCharacter.UnicodeBlock.forName("");
2736        //Tests when "if (b == null)" is true
2737    }
2738
2739    /*
2740     * The following method tests
2741     *      public static int getNumericValue(int ch)
2742     */
2743    public void TestGetNumericValue(){
2744        // The following tests the else statement when
2745        //      if(numericType<NumericType.COUNT) is false
2746        // The following values were obtained by testing all values from
2747        //      UTF16.CODEPOINT_MIN_VALUE to UTF16.CODEPOINT_MAX_VALUE inclusively
2748        //      to obtain the value to go through the else statement.
2749        int[] valid_values =
2750            {3058,3442,4988,8558,8559,8574,8575,8576,8577,8578,8583,8584,19975,
2751             20159,20191,20740,20806,21315,33836,38433,65819,65820,65821,65822,
2752             65823,65824,65825,65826,65827,65828,65829,65830,65831,65832,65833,
2753             65834,65835,65836,65837,65838,65839,65840,65841,65842,65843,65861,
2754             65862,65863,65868,65869,65870,65875,65876,65877,65878,65899,65900,
2755             65901,65902,65903,65904,65905,65906,66378,68167};
2756
2757        int[] results =
2758            {1000,1000,10000,500,1000,500,1000,1000,5000,10000,50000,100000,
2759             10000,100000000,1000,100000000,-2,1000,10000,1000,300,400,500,
2760             600,700,800,900,1000,2000,3000,4000,5000,6000,7000,8000,9000,
2761             10000,20000,30000,40000,50000,60000,70000,80000,90000,500,5000,
2762             50000,500,1000,5000,500,1000,10000,50000,300,500,500,500,500,500,
2763             1000,5000,900,1000};
2764
2765        if(valid_values.length != results.length){
2766            errln("The valid_values array and the results array need to be "+
2767                    "the same length.");
2768        } else {
2769            for(int i = 0; i < valid_values.length; i++){
2770                try{
2771                    if(UCharacter.getNumericValue(valid_values[i]) != results[i]){
2772                        errln("UCharacter.getNumericValue(i) returned a " +
2773                                "different value from the expected result. " +
2774                                "Got " + UCharacter.getNumericValue(valid_values[i]) +
2775                                "Expected" + results[i]);
2776                    }
2777                } catch(Exception e){
2778                    errln("UCharacter.getNumericValue(int) returned an exception " +
2779                            "with the parameter value");
2780                }
2781            }
2782        }
2783    }
2784
2785    /*
2786     * The following method tests
2787     *      public static double getUnicodeNumericValue(int ch)
2788     */
2789    // The following tests covers if(mant==0), else if(mant > 9), and default
2790    public void TestGetUnicodeNumericValue(){
2791        /*  The code coverage for if(mant==0), else if(mant > 9), and default
2792         *  could not be covered even with input values from UTF16.CODEPOINT_MIN_VALUE
2793         *  to UTF16.CODEPOINT_MAX_VALUE. I also tested from UTF16.CODEPOINT_MAX_VALUE to
2794         *  Integer.MAX_VALUE and didn't recieve any code coverage there too.
2795         *  Therefore, the code could either be dead code or meaningless.
2796         */
2797    }
2798
2799    /*
2800     * The following method tests
2801     *      public static String toString(int ch)
2802     */
2803    public void TestToString(){
2804        int[] valid_tests = {
2805                UCharacter.MIN_VALUE, UCharacter.MIN_VALUE+1,
2806                UCharacter.MAX_VALUE-1, UCharacter.MAX_VALUE};
2807        int[] invalid_tests = {
2808                UCharacter.MIN_VALUE-1, UCharacter.MIN_VALUE-2,
2809                UCharacter.MAX_VALUE+1, UCharacter.MAX_VALUE+2};
2810
2811        for(int i=0; i< valid_tests.length; i++){
2812            if(UCharacter.toString(valid_tests[i]) == null){
2813                errln("UCharacter.toString(int) was not suppose to return " +
2814                "null because it was given a valid parameter. Value passed: " +
2815                valid_tests[i] + ". Got null.");
2816            }
2817        }
2818
2819        for(int i=0; i< invalid_tests.length; i++){
2820            if(UCharacter.toString(invalid_tests[i]) != null){
2821                errln("UCharacter.toString(int) was suppose to return " +
2822                "null because it was given an invalid parameter. Value passed: " +
2823                invalid_tests[i] + ". Got: " + UCharacter.toString(invalid_tests[i]));
2824            }
2825        }
2826    }
2827
2828    /*
2829     * The following method tests
2830     *      public static int getCombiningClass(int ch)
2831     */
2832    public void TestGetCombiningClass(){
2833        int[] valid_tests = {
2834                UCharacter.MIN_VALUE, UCharacter.MIN_VALUE+1,
2835                UCharacter.MAX_VALUE-1, UCharacter.MAX_VALUE};
2836        int[] invalid_tests = {
2837                UCharacter.MIN_VALUE-1, UCharacter.MIN_VALUE-2,
2838                UCharacter.MAX_VALUE+1, UCharacter.MAX_VALUE+2};
2839
2840        for(int i=0; i< valid_tests.length; i++){
2841            try{
2842                UCharacter.getCombiningClass(valid_tests[i]);
2843            } catch(Exception e){
2844                errln("UCharacter.getCombiningClass(int) was not supposed to have " +
2845                        "an exception. Value passed: " + valid_tests[i]);
2846            }
2847        }
2848
2849        for(int i=0; i< invalid_tests.length; i++){
2850            try{
2851                assertEquals("getCombiningClass(out of range)",
2852                             0, UCharacter.getCombiningClass(invalid_tests[i]));
2853            } catch(Exception e){
2854                errln("UCharacter.getCombiningClass(int) was not supposed to have " +
2855                        "an exception. Value passed: " + invalid_tests[i]);
2856            }
2857        }
2858    }
2859
2860    /*
2861     * The following method tests
2862     *      public static String getName(int ch)
2863     */
2864    public void TestGetName(){
2865        // Need to test on other "one characters" for the getName() method
2866        String[] data = {"a","z"};
2867        String[] results = {"LATIN SMALL LETTER A","LATIN SMALL LETTER Z"};
2868        if(data.length != results.length){
2869            errln("The data array and the results array need to be "+
2870                    "the same length.");
2871        } else {
2872            for(int i=0; i < data.length; i++){
2873                if(UCharacter.getName(data[i], "").compareTo(results[i]) != 0){
2874                    errln("UCharacter.getName(String, String) was suppose " +
2875                            "to have the same result for the data in the parameter. " +
2876                            "Value passed: " + data[i] + ". Got: " +
2877                            UCharacter.getName(data[i], "") + ". Expected: " +
2878                            results[i]);
2879                }
2880            }
2881        }
2882    }
2883
2884    /*
2885     * The following method tests
2886     *      public static String getISOComment(int ch)
2887     */
2888    public void TestGetISOComment(){
2889        int[] invalid_tests = {
2890                UCharacter.MIN_VALUE-1, UCharacter.MIN_VALUE-2,
2891                UCharacter.MAX_VALUE+1, UCharacter.MAX_VALUE+2};
2892
2893        for(int i=0; i< invalid_tests.length; i++){
2894            if(UCharacter.getISOComment(invalid_tests[i]) != null){
2895                errln("UCharacter.getISOComment(int) was suppose to return " +
2896                "null because it was given an invalid parameter. Value passed: " +
2897                invalid_tests[i] + ". Got: " + UCharacter.getISOComment(invalid_tests[i]));
2898            }
2899        }
2900    }
2901
2902    /*
2903     * The following method tests
2904     *      public void setLimit(int lim)
2905     */
2906    public void TestSetLimit(){
2907        // TODO: Tests when "if(0<=lim && lim<=s.length())" is false
2908    }
2909
2910    /*
2911     * The following method tests
2912     *      public int nextCaseMapCP()
2913     */
2914    public void TestNextCaseMapCP(){
2915        // TODO: Tests when "if(UTF16.LEAD_SURROGATE_MIN_VALUE<=c || c<=UTF16.TRAIL_SURROGATE_MAX_VALUE)" is false
2916        /* TODO: Tests when "if( c<=UTF16.LEAD_SURROGATE_MAX_VALUE && cpLimit<limit &&
2917         * UTF16.TRAIL_SURROGATE_MIN_VALUE<=(c2=s.charAt(cpLimit)) && c2<=UTF16.TRAIL_SURROGATE_MAX_VALUE)" is false
2918         */
2919    }
2920
2921    /*
2922     * The following method tests
2923     *      public void reset(int direction)
2924     */
2925    public void TestReset(){
2926        // The method reset() is never called by another function
2927        // TODO: Tests when "else if(direction<0)" is false
2928    }
2929
2930    /*
2931     * The following method tests
2932     *      public static String toTitleCase(Locale locale, String str, BreakIterator breakiter)
2933     */
2934    public void TestToTitleCaseCoverage(){
2935        //Calls the function "toTitleCase(Locale locale, String str, BreakIterator breakiter)"
2936        String[] locale={"en","fr","zh","ko","ja","it","de",""};
2937        for(int i=0; i<locale.length; i++){
2938            UCharacter.toTitleCase(new Locale(locale[i]), "", null);
2939        }
2940
2941        // Calls the function "String toTitleCase(ULocale locale, String str, BreakIterator titleIter, int options)"
2942        // Tests when "if (locale == null)" is true
2943        UCharacter.toTitleCase((ULocale)null, "", null, 0);
2944
2945        // TODO: Tests when "if(index==BreakIterator.DONE || index>srcLength)" is true
2946        // TODO: Tests when "while((c=iter.nextCaseMapCP())>=0 && UCaseProps.NONE==gCsp.getType(c))" is false
2947        // TODO: Tests when "if(prev<titleStart)" is false
2948        // TODO: Tests when "if(c<=0xffff)" is false
2949        // TODO: Tests when "if(c<=0xffff)" is false
2950        // TODO: Tests when "if(titleLimit<index)" is false
2951        // TODO: Tests when "else if((nc=iter.nextCaseMapCP())>=0)" is false
2952    }
2953    /*
2954     * The following method tests
2955     *      public static String toUpperCase(ULocale locale, String str)
2956     */
2957    public void TestToUpperCase(){
2958        // TODO: Tests when "while((c=iter.nextCaseMapCP())>=0)" is false
2959    }
2960
2961    /*
2962     * The following method tests
2963     *      public static String toLowerCase(ULocale locale, String str)
2964     */
2965    public void TestToLowerCase(){
2966        // Test when locale is null
2967        String[] cases = {"","a","A","z","Z","Dummy","DUMMY","dummy","a z","A Z",
2968                "'","\"","0","9","0a","a0","*","~!@#$%^&*()_+"};
2969        for(int i=0; i<cases.length; i++){
2970            try{
2971                UCharacter.toLowerCase((ULocale) null, cases[i]);
2972            } catch(Exception e){
2973                errln("UCharacter.toLowerCase was not suppose to return an " +
2974                        "exception for input of null and string: " + cases[i]);
2975            }
2976        }
2977        // TODO: Tests when "while((c=iter.nextCaseMapCP())>=0)" is false
2978    }
2979
2980    /*
2981     * The following method tests
2982     *      public static int getHanNumericValue(int ch)
2983     */
2984    public void TestGetHanNumericValue(){
2985        int[] valid = {
2986                0x3007, //IDEOGRAPHIC_NUMBER_ZERO_
2987                0x96f6, //CJK_IDEOGRAPH_COMPLEX_ZERO_
2988                0x4e00, //CJK_IDEOGRAPH_FIRST_
2989                0x58f9, //CJK_IDEOGRAPH_COMPLEX_ONE_
2990                0x4e8c, //CJK_IDEOGRAPH_SECOND_
2991                0x8cb3, //CJK_IDEOGRAPH_COMPLEX_TWO_
2992                0x4e09, //CJK_IDEOGRAPH_THIRD_
2993                0x53c3, //CJK_IDEOGRAPH_COMPLEX_THREE_
2994                0x56db, //CJK_IDEOGRAPH_FOURTH_
2995                0x8086, //CJK_IDEOGRAPH_COMPLEX_FOUR_
2996                0x4e94, //CJK_IDEOGRAPH_FIFTH_
2997                0x4f0d, //CJK_IDEOGRAPH_COMPLEX_FIVE_
2998                0x516d, //CJK_IDEOGRAPH_SIXTH_
2999                0x9678, //CJK_IDEOGRAPH_COMPLEX_SIX_
3000                0x4e03, //CJK_IDEOGRAPH_SEVENTH_
3001                0x67d2, //CJK_IDEOGRAPH_COMPLEX_SEVEN_
3002                0x516b, //CJK_IDEOGRAPH_EIGHTH_
3003                0x634c, //CJK_IDEOGRAPH_COMPLEX_EIGHT_
3004                0x4e5d, //CJK_IDEOGRAPH_NINETH_
3005                0x7396, //CJK_IDEOGRAPH_COMPLEX_NINE_
3006                0x5341, //CJK_IDEOGRAPH_TEN_
3007                0x62fe, //CJK_IDEOGRAPH_COMPLEX_TEN_
3008                0x767e, //CJK_IDEOGRAPH_HUNDRED_
3009                0x4f70, //CJK_IDEOGRAPH_COMPLEX_HUNDRED_
3010                0x5343, //CJK_IDEOGRAPH_THOUSAND_
3011                0x4edf, //CJK_IDEOGRAPH_COMPLEX_THOUSAND_
3012                0x824c, //CJK_IDEOGRAPH_TEN_THOUSAND_
3013                0x5104, //CJK_IDEOGRAPH_HUNDRED_MILLION_
3014        };
3015
3016        int[] invalid = {-5,-2,-1,0};
3017
3018        int[] results = {0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,100,100,
3019                1000,1000,10000,100000000};
3020
3021        if(valid.length != results.length){
3022            errln("The arrays valid and results are suppose to be the same length " +
3023                    "to test getHanNumericValue(int ch).");
3024        } else{
3025            for(int i=0; i<valid.length; i++){
3026                if(UCharacter.getHanNumericValue(valid[i]) != results[i]){
3027                    errln("UCharacter.getHanNumericValue does not return the " +
3028                            "same result as expected. Passed value: " + valid[i] +
3029                            ". Got: " + UCharacter.getHanNumericValue(valid[i]) +
3030                            ". Expected: " + results[i]);
3031                }
3032            }
3033        }
3034
3035        for(int i=0; i<invalid.length; i++){
3036            if(UCharacter.getHanNumericValue(invalid[i]) != -1){
3037                errln("UCharacter.getHanNumericValue does not return the " +
3038                        "same result as expected. Passed value: " + invalid[i] +
3039                        ". Got: " + UCharacter.getHanNumericValue(invalid[i]) +
3040                        ". Expected: -1");
3041            }
3042        }
3043    }
3044
3045    /*
3046     * The following method tests
3047     *      public static boolean hasBinaryProperty(int ch, int property)
3048     */
3049    public void TestHasBinaryProperty(){
3050        // Testing when "if (ch < MIN_VALUE || ch > MAX_VALUE)" is true
3051        int[] invalid = {
3052                UCharacter.MIN_VALUE-1, UCharacter.MIN_VALUE-2,
3053                UCharacter.MAX_VALUE+1, UCharacter.MAX_VALUE+2};
3054        int[] valid = {
3055                UCharacter.MIN_VALUE, UCharacter.MIN_VALUE+1,
3056                UCharacter.MAX_VALUE, UCharacter.MAX_VALUE-1};
3057
3058        for(int i=0; i<invalid.length; i++){
3059            try{
3060                if (UCharacter.hasBinaryProperty(invalid[i], 1)) {
3061                    errln("UCharacter.hasBinaryProperty(ch, property) should return " +
3062                            "false for out-of-range code points but " +
3063                            "returns true for " + invalid[i]);
3064                }
3065            } catch(Exception e) {
3066                errln("UCharacter.hasBinaryProperty(ch, property) should not " +
3067                        "throw an exception for any input. Value passed: " +
3068                        invalid[i]);
3069            }
3070        }
3071
3072        for(int i=0; i<valid.length; i++){
3073            try{
3074                UCharacter.hasBinaryProperty(valid[i], 1);
3075            } catch(Exception e) {
3076                errln("UCharacter.hasBinaryProperty(ch, property) should not " +
3077                        "throw an exception for any input. Value passed: " +
3078                        valid[i]);
3079            }
3080        }
3081    }
3082
3083    /*
3084     * The following method tests
3085     *      public static int getIntPropertyValue(int ch, int type)
3086     */
3087    public void TestGetIntPropertyValue(){
3088        /* Testing UCharacter.getIntPropertyValue(ch, type) */
3089        // Testing when "if (type < UProperty.BINARY_START)" is true
3090        int[] negative_cases = {-100,-50,-10,-5,-2,-1};
3091        for(int i=0; i<negative_cases.length; i++){
3092            if(UCharacter.getIntPropertyValue(0, negative_cases[i]) != 0){
3093                errln("UCharacter.getIntPropertyValue(ch, type) was suppose to return 0 " +
3094                        "when passing a negative value of " + negative_cases[i]);
3095
3096            }
3097        }
3098
3099        // Testing when "if(ch<NormalizerImpl.JAMO_L_BASE)" is true
3100        for(int i=Normalizer2Impl.Hangul.JAMO_L_BASE-5; i<Normalizer2Impl.Hangul.JAMO_L_BASE; i++){
3101            if(UCharacter.getIntPropertyValue(i, UProperty.HANGUL_SYLLABLE_TYPE) != 0){
3102                errln("UCharacter.getIntPropertyValue(ch, type) was suppose to return 0 " +
3103                        "when passing ch: " + i + "and type of Property.HANGUL_SYLLABLE_TYPE");
3104
3105            }
3106        }
3107
3108        // Testing when "else if((ch-=NormalizerImpl.HANGUL_BASE)<0)" is true
3109        for(int i=Normalizer2Impl.Hangul.HANGUL_BASE-5; i<Normalizer2Impl.Hangul.HANGUL_BASE; i++){
3110            if(UCharacter.getIntPropertyValue(i, UProperty.HANGUL_SYLLABLE_TYPE) != 0){
3111                errln("UCharacter.getIntPropertyValue(ch, type) was suppose to return 0 " +
3112                        "when passing ch: " + i + "and type of Property.HANGUL_SYLLABLE_TYPE");
3113
3114            }
3115        }
3116    }
3117
3118    /*
3119     * The following method tests
3120     *      public static int getIntPropertyMaxValue(int type)
3121     */
3122    public void TestGetIntPropertyMaxValue(){
3123        /* Testing UCharacter.getIntPropertyMaxValue(type) */
3124        // Testing when "else if (type < UProperty.INT_START)" is true
3125        int[] cases = {UProperty.BINARY_LIMIT, UProperty.BINARY_LIMIT+1,
3126                UProperty.INT_START-2, UProperty.INT_START-1};
3127        for(int i=0; i<cases.length; i++){
3128            if(UCharacter.getIntPropertyMaxValue(cases[i]) != -1){
3129                errln("UCharacter.getIntPropertyMaxValue was suppose to return -1 " +
3130                        "but got " + UCharacter.getIntPropertyMaxValue(cases[i]));
3131            }
3132        }
3133
3134        // TODO: Testing when the case statment reaches "default"
3135        // After testing between values of UProperty.INT_START and
3136        // UProperty.INT_LIMIT are covered, none of the values reaches default.
3137    }
3138
3139    /*
3140     * The following method tests
3141     *      public static final int codePointAt(CharSequence seq, int index)
3142     *      public static final int codePointAt(char[] text, int index, int limit)
3143     */
3144    public void TestCodePointAt(){
3145
3146        // {LEAD_SURROGATE_MIN_VALUE,
3147        //  LEAD_SURROGATE_MAX_VALUE, LEAD_SURROGATE_MAX_VALUE-1
3148        String[] cases = {"\uD800","\uDBFF","\uDBFE"};
3149        int[] result = {55296,56319,56318};
3150        for(int i=0; i < cases.length; i++){
3151            /* Testing UCharacter.codePointAt(seq, index) */
3152            // Testing when "if (index < seq.length())" is false
3153            if(UCharacter.codePointAt((CharSequence) cases[i], 0) != result[i])
3154                errln("UCharacter.codePointAt(CharSequence ...) did not return as expected. " +
3155                        "Passed value: " + cases[i] + ". Expected: " +
3156                        result[i] + ". Got: " +
3157                        UCharacter.codePointAt((CharSequence) cases[i], 0));
3158
3159            /* Testing UCharacter.codePointAt(text, index) */
3160            // Testing when "if (index < text.length)" is false
3161            if(UCharacter.codePointAt(cases[i].toCharArray(), 0) != result[i])
3162                errln("UCharacter.codePointAt(char[] ...) did not return as expected. " +
3163                        "Passed value: " + cases[i] + ". Expected: " +
3164                        result[i] + ". Got: " +
3165                        UCharacter.codePointAt(cases[i].toCharArray(), 0));
3166
3167            /* Testing UCharacter.codePointAt(text, index, limit) */
3168            // Testing when "if (index < limit)" is false
3169            if(UCharacter.codePointAt(cases[i].toCharArray(), 0, 1) != result[i])
3170                errln("UCharacter.codePointAt(char[], int, int) did not return as expected. " +
3171                        "Passed value: " + cases[i] + ". Expected: " +
3172                        result[i] + ". Got: " +
3173                        UCharacter.codePointAt(cases[i].toCharArray(), 0, 1));
3174        }
3175
3176        /* Testing UCharacter.codePointAt(text, index, limit) */
3177        // Testing when "if (index >= limit || limit > text.length)" is true
3178        char[] empty_text = {};
3179        char[] one_char_text = {'a'};
3180        char[] reg_text = {'d','u','m','m','y'};
3181        int[] limitCases = {2,3,5,10,25};
3182
3183        // When index >= limit
3184        for(int i=0; i < limitCases.length; i++){
3185            try{
3186                UCharacter.codePointAt(reg_text, 100, limitCases[i]);
3187                errln("UCharacter.codePointAt was suppose to return an exception " +
3188                        "but got " + UCharacter.codePointAt(reg_text, 100, limitCases[i]) +
3189                        ". The following passed parameters were Text: " + String.valueOf(reg_text) + ", Start: " +
3190                        100 + ", Limit: " + limitCases[i] + ".");
3191            } catch(Exception e){
3192            }
3193        }
3194
3195        // When limit > text.length
3196        for(int i=0; i < limitCases.length; i++){
3197            try{
3198                UCharacter.codePointAt(empty_text, 0, limitCases[i]);
3199                errln("UCharacter.codePointAt was suppose to return an exception " +
3200                        "but got " + UCharacter.codePointAt(empty_text, 0, limitCases[i]) +
3201                        ". The following passed parameters were Text: " + String.valueOf(empty_text) + ", Start: " +
3202                        0 + ", Limit: " + limitCases[i] + ".");
3203            } catch(Exception e){
3204            }
3205
3206            try{
3207                UCharacter.codePointCount(one_char_text, 0, limitCases[i]);
3208                errln("UCharacter.codePointCount was suppose to return an exception " +
3209                        "but got " + UCharacter.codePointCount(one_char_text, 0, limitCases[i]) +
3210                        ". The following passed parameters were Text: " + String.valueOf(one_char_text) + ", Start: " +
3211                        0 + ", Limit: " + limitCases[i] + ".");
3212            } catch(Exception e){
3213            }
3214        }
3215    }
3216
3217    /*
3218     * The following method tests
3219     *      public static final int codePointBefore(CharSequence seq, int index)
3220     *      public static final int codePointBefore(char[] text, int index)
3221     *      public static final int codePointBefore(char[] text, int index, int limit)
3222     */
3223    public void TestCodePointBefore(){
3224        // {TRAIL_SURROGATE_MIN_VALUE,
3225        //  TRAIL_SURROGATE_MAX_VALUE, TRAIL_SURROGATE_MAX_VALUE -1
3226        String[] cases = {"\uDC00","\uDFFF","\uDDFE"};
3227        int[] result = {56320,57343,56830};
3228        for(int i=0; i < cases.length; i++){
3229            /* Testing UCharacter.codePointBefore(seq, index) */
3230            // Testing when "if (index > 0)" is false
3231            if(UCharacter.codePointBefore((CharSequence) cases[i], 1) != result[i])
3232                errln("UCharacter.codePointBefore(CharSequence ...) did not return as expected. " +
3233                        "Passed value: " + cases[i] + ". Expected: " +
3234                        result[i] + ". Got: " +
3235                        UCharacter.codePointBefore((CharSequence) cases[i], 1));
3236
3237            /* Testing UCharacter.codePointBefore(text, index) */
3238            // Testing when "if (index > 0)" is false
3239            if(UCharacter.codePointBefore(cases[i].toCharArray(), 1) != result[i])
3240                errln("UCharacter.codePointBefore(char[] ...) did not return as expected. " +
3241                        "Passed value: " + cases[i] + ". Expected: " +
3242                        result[i] + ". Got: " +
3243                        UCharacter.codePointBefore(cases[i].toCharArray(), 1));
3244
3245            /* Testing UCharacter.codePointBefore(text, index, limit) */
3246            // Testing when "if (index > limit)" is false
3247            if(UCharacter.codePointBefore(cases[i].toCharArray(), 1, 0) != result[i])
3248                errln("UCharacter.codePointBefore(char[], int, int) did not return as expected. " +
3249                        "Passed value: " + cases[i] + ". Expected: " +
3250                        result[i] + ". Got: " +
3251                        UCharacter.codePointBefore(cases[i].toCharArray(), 1, 0));
3252        }
3253
3254        /* Testing UCharacter.codePointBefore(text, index, limit) */
3255        char[] dummy = {'d','u','m','m','y'};
3256        // Testing when "if (index <= limit || limit < 0)" is true
3257        int[] negative_cases = {-100,-10,-5,-2,-1};
3258        int[] index_cases = {0,1,2,5,10,100};
3259
3260        for(int i=0; i < negative_cases.length; i++){
3261            try{
3262                UCharacter.codePointBefore(dummy, 10000, negative_cases[i]);
3263                errln("UCharacter.codePointBefore(text, index, limit) was suppose to return an exception " +
3264                        "when the parameter limit of " + negative_cases[i] + " is a negative number.");
3265            } catch(Exception e) {}
3266        }
3267
3268        for(int i=0; i < index_cases.length; i++){
3269            try{
3270                UCharacter.codePointBefore(dummy, index_cases[i], 101);
3271                errln("UCharacter.codePointBefore(text, index, limit) was suppose to return an exception " +
3272                        "when the parameter index of " + index_cases[i] + " is a negative number.");
3273            } catch(Exception e) {}
3274        }
3275    }
3276
3277    /*
3278     * The following method tests
3279     *      public static final int toChars(int cp, char[] dst, int dstIndex)
3280     *      public static final char[] toChars(int cp)
3281     */
3282    public void TestToChars(){
3283        int[] positive_cases = {1,2,5,10,100};
3284        char[] dst = {'a'};
3285
3286        /* Testing UCharacter.toChars(cp, dst, dstIndex) */
3287        for(int i=0; i < positive_cases.length; i++){
3288            // Testing negative values when cp < 0 for if (cp >= 0)
3289            try{
3290                UCharacter.toChars(-1*positive_cases[i],dst,0);
3291                errln("UCharacter.toChars(int,char[],int) was suppose to return an exception " +
3292                        "when the parameter " + (-1*positive_cases[i]) + " is a negative number.");
3293            } catch(Exception e){
3294            }
3295
3296            // Testing when "if (cp < MIN_SUPPLEMENTARY_CODE_POINT)" is true
3297            if(UCharacter.toChars(UCharacter.MIN_SUPPLEMENTARY_CODE_POINT-positive_cases[i], dst, 0) != 1){
3298                errln("UCharacter.toChars(int,char[],int) was suppose to return a value of 1. Got: " +
3299                        UCharacter.toChars(UCharacter.MIN_SUPPLEMENTARY_CODE_POINT-positive_cases[i], dst, 0));
3300            }
3301
3302            // Testing when "if (cp < MIN_SUPPLEMENTARY_CODE_POINT)" is false and
3303            //     when "if (cp <= MAX_CODE_POINT)" is false
3304            try{
3305                UCharacter.toChars(UCharacter.MAX_CODE_POINT+positive_cases[i],dst,0);
3306                errln("UCharacter.toChars(int,char[],int) was suppose to return an exception " +
3307                        "when the parameter " + (UCharacter.MAX_CODE_POINT+positive_cases[i]) +
3308                        " is a large number.");
3309            } catch(Exception e){
3310            }
3311        }
3312
3313
3314        /* Testing UCharacter.toChars(cp)*/
3315        for(int i=0; i<positive_cases.length; i++){
3316            // Testing negative values when cp < 0 for if (cp >= 0)
3317            try{
3318                UCharacter.toChars(-1*positive_cases[i]);
3319                errln("UCharacter.toChars(cint) was suppose to return an exception " +
3320                        "when the parameter " + positive_cases[i] + " is a negative number.");
3321            } catch(Exception e){
3322            }
3323
3324            // Testing when "if (cp < MIN_SUPPLEMENTARY_CODE_POINT)" is true
3325            if(UCharacter.toChars(UCharacter.MIN_SUPPLEMENTARY_CODE_POINT-positive_cases[i]).length <= 0){
3326                errln("UCharacter.toChars(int) was suppose to return some result result when the parameter " +
3327                        (UCharacter.MIN_SUPPLEMENTARY_CODE_POINT-positive_cases[i]) + "is passed.");
3328            }
3329
3330            // Testing when "if (cp < MIN_SUPPLEMENTARY_CODE_POINT)" is false and
3331            //     when "if (cp <= MAX_CODE_POINT)" is false
3332            try{
3333                UCharacter.toChars(UCharacter.MAX_CODE_POINT+positive_cases[i]);
3334                errln("UCharacter.toChars(int) was suppose to return an exception " +
3335                        "when the parameter " + positive_cases[i] + " is a large number.");
3336            } catch(Exception e){
3337            }
3338        }
3339    }
3340
3341    /*
3342     * The following method tests
3343     *      public static int codePointCount(CharSequence text, int start, int limit)
3344     *      public static int codePointCount(char[] text, int start, int limit)
3345     */
3346    public void TestCodePointCount(){
3347        // The following tests the first if statement to make it true:
3348        //  if (start < 0 || limit < start || limit > text.length)
3349        //  which will throw an exception.
3350        char[] empty_text = {};
3351        char[] one_char_text = {'a'};
3352        char[] reg_text = {'d','u','m','m','y'};
3353        int[] invalid_startCases = {-1,-2,-5,-10,-100};
3354        int[] limitCases = {2,3,5,10,25};
3355
3356        // When start < 0
3357        for(int i=0; i < invalid_startCases.length; i++){
3358            try{
3359                UCharacter.codePointCount(reg_text, invalid_startCases[i], 1);
3360                errln("UCharacter.codePointCount was suppose to return an exception " +
3361                        "but got " + UCharacter.codePointCount(reg_text, invalid_startCases[i], 1) +
3362                        ". The following passed parameters were Text: " + String.valueOf(reg_text) + ", Start: " +
3363                        invalid_startCases[i] + ", Limit: " + 1 + ".");
3364            } catch(Exception e){
3365            }
3366        }
3367
3368        // When limit < start
3369        for(int i=0; i < limitCases.length; i++){
3370            try{
3371                UCharacter.codePointCount(reg_text, 100, limitCases[i]);
3372                errln("UCharacter.codePointCount was suppose to return an exception " +
3373                        "but got " + UCharacter.codePointCount(reg_text, 100, limitCases[i]) +
3374                        ". The following passed parameters were Text: " + String.valueOf(reg_text) + ", Start: " +
3375                        100 + ", Limit: " + limitCases[i] + ".");
3376            } catch(Exception e){
3377            }
3378        }
3379
3380        // When limit > text.length
3381        for(int i=0; i < limitCases.length; i++){
3382            try{
3383                UCharacter.codePointCount(empty_text, 0, limitCases[i]);
3384                errln("UCharacter.codePointCount was suppose to return an exception " +
3385                        "but got " + UCharacter.codePointCount(empty_text, 0, limitCases[i]) +
3386                        ". The following passed parameters were Text: " + String.valueOf(empty_text) + ", Start: " +
3387                        0 + ", Limit: " + limitCases[i] + ".");
3388            } catch(Exception e){
3389            }
3390
3391            try{
3392                UCharacter.codePointCount(one_char_text, 0, limitCases[i]);
3393                errln("UCharacter.codePointCount was suppose to return an exception " +
3394                        "but got " + UCharacter.codePointCount(one_char_text, 0, limitCases[i]) +
3395                        ". The following passed parameters were Text: " + String.valueOf(one_char_text) + ", Start: " +
3396                        0 + ", Limit: " + limitCases[i] + ".");
3397            } catch(Exception e){
3398            }
3399        }
3400    }
3401
3402    /*
3403     * The following method tests
3404     *      private static int getEuropeanDigit(int ch)
3405     * The method needs to use the method "digit" in order to access the
3406     * getEuropeanDigit method.
3407     */
3408    public void TestGetEuropeanDigit(){
3409        //The number retrieved from 0xFF41 to 0xFF5A is due to
3410        //  exhaustive testing from UTF16.CODEPOINT_MIN_VALUE to
3411        //  UTF16.CODEPOINT_MAX_VALUE return a value of -1.
3412
3413        int[] radixResult = {
3414                10,11,12,13,14,15,16,17,18,19,20,21,22,
3415                23,24,25,26,27,28,29,30,31,32,33,34,35};
3416        // Invalid and too-small-for-these-digits radix values.
3417        int[] radixCase1 = {0,1,5,10,100};
3418        // Radix values that work for at least some of the "digits".
3419        int[] radixCase2 = {12,16,20,36};
3420
3421        for(int i=0xFF41; i<=0xFF5A; i++){
3422            for(int j=0; j < radixCase1.length; j++){
3423                if(UCharacter.digit(i, radixCase1[j]) != -1){
3424                    errln("UCharacter.digit(int,int) was supposed to return -1 for radix " + radixCase1[j]
3425                            + ". Value passed: U+" + Integer.toHexString(i) + ". Got: " + UCharacter.digit(i, radixCase1[j]));
3426                }
3427            }
3428            for(int j=0; j < radixCase2.length; j++){
3429                int radix = radixCase2[j];
3430                int expected = (radixResult[i-0xFF41] < radix) ? radixResult[i-0xFF41] : -1;
3431                int actual = UCharacter.digit(i, radix);
3432                if(actual != expected){
3433                    errln("UCharacter.digit(int,int) was supposed to return " +
3434                            expected + " for radix " + radix +
3435                            ". Value passed: U+" + Integer.toHexString(i) + ". Got: " + actual);
3436                    break;
3437                }
3438            }
3439        }
3440    }
3441
3442    /* Tests the method
3443     *      private static final int getProperty(int ch)
3444     * from public static int getType(int ch)
3445     */
3446    public void TestGetProperty(){
3447        int[] cases = {UTF16.CODEPOINT_MAX_VALUE+1, UTF16.CODEPOINT_MAX_VALUE+2};
3448        for(int i=0; i < cases.length; i++)
3449            if(UCharacter.getType(cases[i]) != 0)
3450                errln("UCharacter.getType for testing UCharacter.getProperty "
3451                        + "did not return 0 for passed value of " + cases[i] +
3452                        " but got " + UCharacter.getType(cases[i]));
3453    }
3454
3455    /* Tests the class
3456     *      abstract public static class XSymbolTable implements SymbolTable
3457     */
3458    public void TestXSymbolTable(){
3459        class MyXSymbolTable extends UnicodeSet.XSymbolTable {}
3460        MyXSymbolTable st = new MyXSymbolTable();
3461
3462        // Tests "public UnicodeMatcher lookupMatcher(int i)"
3463        if(st.lookupMatcher(0) != null)
3464            errln("XSymbolTable.lookupMatcher(int i) was suppose to return null.");
3465
3466        // Tests "public boolean applyPropertyAlias(String propertyName, String propertyValue, UnicodeSet result)"
3467        if(st.applyPropertyAlias("", "", new UnicodeSet()) != false)
3468            errln("XSymbolTable.applyPropertyAlias(String propertyName, String propertyValue, UnicodeSet result) was suppose to return false.");
3469
3470        // Tests "public char[] lookup(String s)"
3471        if(st.lookup("") != null)
3472            errln("XSymbolTable.lookup(String s) was suppose to return null.");
3473
3474        // Tests "public String parseReference(String text, ParsePosition pos, int limit)"
3475        if(st.parseReference("", null, 0) != null)
3476            errln("XSymbolTable.parseReference(String text, ParsePosition pos, int limit) was suppose to return null.");
3477    }
3478
3479    /* Tests the method
3480     *      public boolean isFrozen()
3481     */
3482    public void TestIsFrozen(){
3483        UnicodeSet us = new UnicodeSet();
3484        if(us.isFrozen() != false)
3485            errln("Unicode.isFrozen() was suppose to return false.");
3486
3487        us.freeze();
3488        if(us.isFrozen() != true)
3489            errln("Unicode.isFrozen() was suppose to return true.");
3490    }
3491}
3492