1 /* 2 * Copyright (C) 2013 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 17 package libcore.icu; 18 19 import java.util.Locale; 20 21 public class AlphabeticIndexTest extends junit.framework.TestCase { 22 private static AlphabeticIndex.ImmutableIndex createIndex(Locale locale) { 23 return new AlphabeticIndex(locale).addLabels(Locale.US) 24 .getImmutableIndex(); 25 } 26 27 private static void assertHasLabel(AlphabeticIndex.ImmutableIndex ii, String string, String expectedLabel) { 28 int index = ii.getBucketIndex(string); 29 String label = ii.getBucketLabel(index); 30 assertEquals(expectedLabel, label); 31 } 32 33 public void test_en() throws Exception { 34 // English [A-Z] 35 AlphabeticIndex.ImmutableIndex en = createIndex(Locale.ENGLISH); 36 assertHasLabel(en, "Allen", "A"); 37 assertHasLabel(en, "allen", "A"); 38 } 39 40 public void test_ja() throws Exception { 41 AlphabeticIndex.ImmutableIndex ja = createIndex(Locale.JAPANESE); 42 43 // Japanese 44 // sorts hiragana/katakana, Kanji/Chinese, English, other 45 // , , , , , , , , , , , 46 // hiragana "a" 47 assertHasLabel(ja, "Allen", "A"); 48 assertHasLabel(ja, "\u3041", "\u3042"); 49 // katakana "a" 50 assertHasLabel(ja, "\u30a1", "\u3042"); 51 52 // Kanji (sorts to inflow section) 53 assertHasLabel(ja, "\u65e5", ""); 54 // http://bugs.icu-project.org/trac/ticket/10423 / http://b/10809397 55 assertHasLabel(ja, "\u95c7", ""); 56 57 // English 58 assertHasLabel(ja, "Smith", "S"); 59 60 // Chinese (sorts to inflow section) 61 assertHasLabel(ja, "\u6c88" /* Shen/Chen */, ""); 62 63 // Korean Hangul (sorts to overflow section) 64 assertHasLabel(ja, "\u1100", ""); 65 } 66 67 public void test_ko() throws Exception { 68 // Korean (sorts Korean, then English) 69 // , , , , , , , , , , , , , , , 70 AlphabeticIndex.ImmutableIndex ko = createIndex(Locale.KOREAN); 71 assertHasLabel(ko, "\u1100", "\u3131"); 72 assertHasLabel(ko, "\u3131", "\u3131"); 73 assertHasLabel(ko, "\u1101", "\u3131"); 74 assertHasLabel(ko, "\u1161", "\u314e"); 75 } 76 77 public void test_cs() throws Exception { 78 // Czech 79 // , [A-C], ,[D-H], CH, [I-R], , S, , [T-Z], , 80 AlphabeticIndex.ImmutableIndex cs = createIndex(new Locale("cs")); 81 assertHasLabel(cs, "Cena", "C"); 82 assertHasLabel(cs, "p", "\u010c"); 83 assertHasLabel(cs, "Ruda", "R"); 84 assertHasLabel(cs, "ada", "\u0158"); 85 assertHasLabel(cs, "Selka", "S"); 86 assertHasLabel(cs, "la", "\u0160"); 87 assertHasLabel(cs, "Zebra", "Z"); 88 assertHasLabel(cs, "ba", "\u017d"); 89 assertHasLabel(cs, "Chata", "CH"); 90 } 91 92 public void test_fr() throws Exception { 93 // French: [A-Z] (no accented chars) 94 AlphabeticIndex.ImmutableIndex fr = createIndex(Locale.FRENCH); 95 assertHasLabel(fr, "fer", "O"); 96 assertHasLabel(fr, "ster", "O"); 97 } 98 99 public void test_da() throws Exception { 100 // Danish: [A-Z], , , 101 AlphabeticIndex.ImmutableIndex da = createIndex(new Locale("da")); 102 assertHasLabel(da, "nes", "\u00c6"); 103 assertHasLabel(da, "fer", "\u00d8"); 104 assertHasLabel(da, "ster", "\u00d8"); 105 assertHasLabel(da, "grd", "\u00c5"); 106 } 107 108 public void test_de() throws Exception { 109 // German: [A-S,Sch,St,T-Z] (no or umlauted characters in standard alphabet) 110 AlphabeticIndex.ImmutableIndex de = createIndex(Locale.GERMAN); 111 assertHasLabel(de, "ind", "S"); 112 assertHasLabel(de, "Sacher", "S"); 113 assertHasLabel(de, "Schiller", "Sch"); 114 assertHasLabel(de, "Steiff", "St"); 115 } 116 117 public void test_th() throws Exception { 118 // Thai (sorts English then Thai) 119 // , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , 120 AlphabeticIndex.ImmutableIndex th = createIndex(new Locale("th")); 121 assertHasLabel(th, "\u0e2d\u0e07\u0e04\u0e4c\u0e40\u0e25\u0e47\u0e01", "\u0e2d"); 122 assertHasLabel(th, "\u0e2a\u0e34\u0e07\u0e2b\u0e40\u0e2a\u0e19\u0e35", "\u0e2a"); 123 } 124 125 public void test_ar() throws Exception { 126 // Arabic (sorts English then Arabic) 127 // , , , , , , , , , , , , , , , , , , , , , , , , , , , , , 128 AlphabeticIndex.ImmutableIndex ar = createIndex(new Locale("ar")); 129 assertHasLabel(ar, "\u0646\u0648\u0631", /* Noor */ "\u0646"); 130 } 131 132 public void test_he() throws Exception { 133 // Hebrew (sorts English then Hebrew) 134 // , , , , , , , , , , , , , , , , , , , , , , , 135 AlphabeticIndex.ImmutableIndex he = createIndex(new Locale("he")); 136 assertHasLabel(he, "\u05e4\u05e8\u05d9\u05d3\u05de\u05df", "\u05e4"); 137 } 138 139 public void test_zh_CN() throws Exception { 140 // Simplified Chinese (default collator Pinyin): [A-Z] 141 // Shen/Chen (simplified): should be, usually, 'S' for name collator and 'C' for apps/other 142 AlphabeticIndex.ImmutableIndex zh_CN = createIndex(new Locale("zh", "CN")); 143 144 // Jia/Gu: should be, usually, 'J' for name collator and 'G' for apps/other 145 assertHasLabel(zh_CN, "\u8d3e", "J"); 146 147 // Shen/Chen 148 assertHasLabel(zh_CN, "\u6c88", "C"); // icu4c 50 does not specialize for names. 149 // Shen/Chen (traditional) 150 assertHasLabel(zh_CN, "\u700b", "S"); 151 } 152 153 public void test_zh_HK() throws Exception { 154 // Traditional Chinese (strokes). 155 // , [1-33, 35, 36, 39, 48], 156 // Shen/Chen 157 AlphabeticIndex.ImmutableIndex zh_HK = createIndex(new Locale("zh", "HK")); 158 assertHasLabel(zh_HK, "\u6c88", "7\u5283"); 159 assertHasLabel(zh_HK, "\u700b", "18\u5283"); 160 // Jia/Gu 161 assertHasLabel(zh_HK, "\u8d3e", "10\u5283"); 162 } 163 164 public void test_constructor_NPE() throws Exception { 165 try { 166 new AlphabeticIndex(null); 167 fail(); 168 } catch (NullPointerException expected) { 169 } 170 } 171 172 public void test_addLabels_NPE() throws Exception { 173 AlphabeticIndex ai = new AlphabeticIndex(Locale.US); 174 try { 175 ai.addLabels(null); 176 fail(); 177 } catch (NullPointerException expected) { 178 } 179 } 180 181 // ICU 51 default max label count is 99. Test to make sure can create an 182 // index with a larger number of labels. 183 public void test_setMaxLabelCount() throws Exception { 184 final int MAX_LABEL_COUNT = 500; 185 AlphabeticIndex ai = new AlphabeticIndex(Locale.US) 186 .setMaxLabelCount(MAX_LABEL_COUNT) 187 .addLabels(Locale.JAPANESE) 188 .addLabels(Locale.KOREAN) 189 .addLabels(new Locale("th")) 190 .addLabels(new Locale("ar")) 191 .addLabels(new Locale("he")) 192 .addLabels(new Locale("el")) 193 .addLabels(new Locale("ru")); 194 assertEquals(MAX_LABEL_COUNT, ai.getMaxLabelCount()); 195 assertEquals(208, ai.getBucketCount()); 196 AlphabeticIndex.ImmutableIndex ii = ai.getImmutableIndex(); 197 assertEquals(ai.getBucketCount(), ii.getBucketCount()); 198 } 199 200 public void test_getBucketIndex_NPE() throws Exception { 201 AlphabeticIndex.ImmutableIndex ii = createIndex(Locale.US); 202 try { 203 ii.getBucketIndex(null); 204 fail(); 205 } catch (NullPointerException expected) { 206 } 207 } 208 209 public void test_getBucketLabel_invalid() throws Exception { 210 AlphabeticIndex.ImmutableIndex ii = createIndex(Locale.US); 211 try { 212 ii.getBucketLabel(-1); 213 fail(); 214 } catch (IllegalArgumentException expected) { 215 } 216 217 try { 218 ii.getBucketLabel(123456); 219 fail(); 220 } catch (IllegalArgumentException expected) { 221 } 222 } 223 } 224