1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package libcore.java.text;
18
19import java.text.CharacterIterator;
20import java.text.CollationElementIterator;
21import java.text.Collator;
22import java.text.ParseException;
23import java.text.RuleBasedCollator;
24import java.text.StringCharacterIterator;
25import java.util.Locale;
26
27public class CollatorTest extends junit.framework.TestCase {
28    public void test_setStrengthI() throws Exception {
29        Collator collator = Collator.getInstance();
30        collator.setStrength(Collator.PRIMARY);
31        assertEquals(Collator.PRIMARY, collator.getStrength());
32        collator.setStrength(Collator.SECONDARY);
33        assertEquals(Collator.SECONDARY, collator.getStrength());
34        collator.setStrength(Collator.TERTIARY);
35        assertEquals(Collator.TERTIARY, collator.getStrength());
36        collator.setStrength(Collator.IDENTICAL);
37        assertEquals(Collator.IDENTICAL, collator.getStrength());
38        try {
39            collator.setStrength(-1);
40            fail("IllegalArgumentException was not thrown.");
41        } catch (IllegalArgumentException expected) {
42        }
43    }
44
45    public void test_stackCorruption() throws Exception {
46        // This used to crash Android.
47        Collator mColl = Collator.getInstance();
48        mColl.setStrength(Collator.PRIMARY);
49        mColl.getCollationKey("2d294f2d3739433565147655394f3762f3147312d3731641452f310");
50    }
51
52    public void test_icuConstantNullorder() throws Exception {
53        assertEquals(android.icu.text.CollationElementIterator.NULLORDER,
54                CollationElementIterator.NULLORDER);
55    }
56
57    public void test_collationKeySize() throws Exception {
58        // Test to verify that very large collation keys are not truncated.
59        StringBuilder b = new StringBuilder();
60        for (int i = 0; i < 1024; i++) {
61            b.append("0123456789ABCDEF");
62        }
63        String sixteen = b.toString();
64        b.append("_THE_END");
65        String sixteenplus = b.toString();
66
67        Collator mColl = Collator.getInstance();
68        mColl.setStrength(Collator.PRIMARY);
69
70        byte [] arr = mColl.getCollationKey(sixteen).toByteArray();
71        int len = arr.length;
72        assertTrue("Collation key not 0 terminated", arr[arr.length - 1] == 0);
73        len--;
74        String foo = new String(arr, 0, len, "iso8859-1");
75
76        arr = mColl.getCollationKey(sixteen).toByteArray();
77        len = arr.length;
78        assertTrue("Collation key not 0 terminated", arr[arr.length - 1] == 0);
79        len--;
80        String bar = new String(arr, 0, len, "iso8859-1");
81
82        assertTrue("Collation keys should differ", foo.equals(bar));
83    }
84
85    public void test_decompositionCompatibility() throws Exception {
86        Collator myCollator = Collator.getInstance();
87        myCollator.setDecomposition(Collator.NO_DECOMPOSITION);
88        assertFalse("Error: \u00e0\u0325 should not equal to a\u0325\u0300 without decomposition",
89                myCollator.compare("\u00e0\u0325", "a\u0325\u0300") == 0);
90        myCollator.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
91        assertTrue("Error: \u00e0\u0325 should equal to a\u0325\u0300 with decomposition",
92                myCollator.compare("\u00e0\u0325", "a\u0325\u0300") == 0);
93    }
94
95    public void testEqualsObject() throws ParseException {
96        String rule = "&9 < a < b < c < d < e";
97        RuleBasedCollator coll = new RuleBasedCollator(rule);
98
99        assertEquals(Collator.TERTIARY, coll.getStrength());
100        assertEquals(Collator.NO_DECOMPOSITION, coll.getDecomposition());
101        RuleBasedCollator other = new RuleBasedCollator(rule);
102        assertTrue(coll.equals(other));
103
104        coll.setStrength(Collator.PRIMARY);
105        assertFalse(coll.equals(other));
106
107        coll.setStrength(Collator.TERTIARY);
108        coll.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
109        other.setDecomposition(Collator.NO_DECOMPOSITION); // See comment above.
110        assertFalse(coll.equals(other));
111    }
112
113    public void test_Harmony_1352() throws Exception {
114        // Regression test for HARMONY-1352, that doesn't get run in the harmony test suite because
115        // of an earlier failure.
116        try {
117            new RuleBasedCollator("&9 < a< b< c< d").getCollationElementIterator((CharacterIterator) null);
118            fail("NullPointerException expected");
119        } catch (NullPointerException expected) {
120        }
121    }
122
123    // In traditional Spanish sorting, the pair of characters 'ch' behaves as a single character
124    // that sorts primary-after c.
125    public void testTradSpanishSorting() {
126        RuleBasedCollator traditionalSpanishCollator = (RuleBasedCollator)
127                Collator.getInstance(Locale.forLanguageTag("es-u-co-trad"));
128        String cd = "cd";
129        String chd = "chd";
130        assertTrue(traditionalSpanishCollator.compare(cd, chd) < 0);
131    }
132
133    private void assertCollationElementIterator(CollationElementIterator it, Integer... offsets) {
134        for (int offset : offsets) {
135            assertEquals(offset, it.getOffset());
136            it.next();
137        }
138        assertEquals(CollationElementIterator.NULLORDER, it.next());
139    }
140
141    private void assertGetCollationElementIteratorString(Locale l, String s, Integer... offsets) {
142        RuleBasedCollator coll = (RuleBasedCollator) Collator.getInstance(l);
143        assertCollationElementIterator(coll.getCollationElementIterator(s), offsets);
144    }
145
146    private void assertGetCollationElementIteratorCharacterIterator(Locale l, String s, Integer... offsets) {
147        RuleBasedCollator coll = (RuleBasedCollator) Collator.getInstance(l);
148        CharacterIterator it = new StringCharacterIterator(s);
149        assertCollationElementIterator(coll.getCollationElementIterator(it), offsets);
150    }
151
152    public void testGetCollationElementIteratorString_es() throws Exception {
153        assertGetCollationElementIteratorString(new Locale("es", "", ""), "cha", 0, 1, 2, 3);
154    }
155
156    public void testGetCollationElementIteratorString_de_DE() throws Exception {
157        assertGetCollationElementIteratorString(new Locale("de", "DE", ""), "\u00e6b", 0, 1, 1, 2);
158    }
159
160    public void testGetCollationElementIteratorCharacterIterator_es() throws Exception {
161        assertGetCollationElementIteratorCharacterIterator(new Locale("es", "", ""), "cha", 0, 1, 2, 3);
162    }
163
164    public void testGetCollationElementIteratorCharacterIterator_de_DE() throws Exception {
165        assertGetCollationElementIteratorCharacterIterator(new Locale("de", "DE", ""), "\u00e6b", 0, 1, 1, 2);
166    }
167}
168