1b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/********************************************************************
2b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * COPYRIGHT:
3f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius * Copyright (c) 2012-2013, International Business Machines Corporation
4f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius * and others. All Rights Reserved.
5b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ********************************************************************/
6b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho//
7b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho//   file:  alphaindex.cpp
8b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho//          Alphabetic Index Tests.
9b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho//
10f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius#include <stdio.h>  // for sprintf
11f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius
12b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "intltest.h"
13b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "alphaindextst.h"
14b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
15b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "unicode/alphaindex.h"
16b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "unicode/coll.h"
17f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius#include "unicode/localpointer.h"
18b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "unicode/tblcoll.h"
19b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "unicode/uniset.h"
20b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
21103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if !UCONFIG_NO_COLLATION && !UCONFIG_NO_NORMALIZATION
22103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
23b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// #include <string>
24b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// #include <iostream>
25b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
26f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
27f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius
28f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Corneliusnamespace {
29f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius
30f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig CorneliusUnicodeString joinLabelsAndAppend(AlphabeticIndex::ImmutableIndex &index, UnicodeString &dest) {
31f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    int32_t oldLength = dest.length();
32f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    const AlphabeticIndex::Bucket *bucket;
33f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    for (int32_t i = 0; (bucket = index.getBucket(i)) != NULL; ++i) {
34f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        if (dest.length() > oldLength) {
35f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius            dest.append((UChar)0x3A);  // ':'
36f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        }
37f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        dest.append(bucket->getLabel());
38f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    }
39f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    return dest;
40f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius}
41f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius
42f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius}  // namespace
43f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius
44b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoAlphabeticIndexTest::AlphabeticIndexTest() {
45b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}
46b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
47b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoAlphabeticIndexTest::~AlphabeticIndexTest() {
48b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}
49b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
50b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid AlphabeticIndexTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
51b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho{
52b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (exec) logln("TestSuite AlphabeticIndex: ");
53f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    TESTCASE_AUTO_BEGIN;
54f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    TESTCASE_AUTO(APITest);
55f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    TESTCASE_AUTO(ManyLocalesTest);
56f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    TESTCASE_AUTO(HackPinyinTest);
57f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    TESTCASE_AUTO(TestBug9009);
58f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    TESTCASE_AUTO(TestIndexCharactersList);
59f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    TESTCASE_AUTO(TestHaniFirst);
60f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    TESTCASE_AUTO(TestPinyinFirst);
61f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    TESTCASE_AUTO(TestSchSt);
62f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    TESTCASE_AUTO(TestNoLabels);
63f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    // BEGIN android-remove - test to be added in 51.1
64f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    // TESTCASE_AUTO(TestChineseZhuyin);
65f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    // END android-remove
660a61a367aa48577edf1c9ba57c501b8f5e7555d5Craig Cornelius    TESTCASE_AUTO(TestJapaneseKanji);
67f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    TESTCASE_AUTO_END;
68b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}
69b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
70b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#define TEST_CHECK_STATUS {if (U_FAILURE(status)) {dataerrln("%s:%d: Test failure.  status=%s", \
71b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                                              __FILE__, __LINE__, u_errorName(status)); return;}}
72b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
73b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#define TEST_ASSERT(expr) {if ((expr)==FALSE) {errln("%s:%d: Test failure \n", __FILE__, __LINE__);};}
74b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
75b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho//
76b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho//  APITest.   Invoke every function at least once, and check that it does something.
77b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho//             Does not attempt to check complete functionality.
78b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho//
79b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid AlphabeticIndexTest::APITest() {
80b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    //
81b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    //  Simple constructor and destructor,  getBucketCount()
82b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    //
83b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    UErrorCode status = U_ZERO_ERROR;
84b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    int32_t lc = 0;
85b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    int32_t i  = 0;
86b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    AlphabeticIndex *index = new AlphabeticIndex(Locale::getEnglish(), status);
87b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_CHECK_STATUS;
88b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    lc = index->getBucketCount(status);
89b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_CHECK_STATUS;
90b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_ASSERT(28 == lc);    // 26 letters plus two under/overflow labels.
91b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    //printf("getBucketCount() == %d\n", lc);
92b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    delete index;
93b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
94f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    // Constructor from a Collator
95f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    //
96f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    status = U_ZERO_ERROR;
970a61a367aa48577edf1c9ba57c501b8f5e7555d5Craig Cornelius    RuleBasedCollator *coll = dynamic_cast<RuleBasedCollator *>(
980a61a367aa48577edf1c9ba57c501b8f5e7555d5Craig Cornelius        Collator::createInstance(Locale::getGerman(), status));
99f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    TEST_CHECK_STATUS;
100f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    TEST_ASSERT(coll != NULL);
101f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    index = new AlphabeticIndex(coll, status);
102f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    TEST_CHECK_STATUS;
103f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    TEST_ASSERT(coll == &index->getCollator());
104f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    assertEquals("only the underflow label in an index built from a collator",
105f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius                 1, index->getBucketCount(status));
106f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    TEST_CHECK_STATUS;
107f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    delete index;
108f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius
109f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius
110b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // addLabels()
111b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
112b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    status = U_ZERO_ERROR;
113b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    index = new AlphabeticIndex(Locale::getEnglish(), status);
114b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_CHECK_STATUS;
115b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    UnicodeSet additions;
116b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    additions.add((UChar32)0x410).add((UChar32)0x415);   // A couple of Cyrillic letters
117b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    index->addLabels(additions, status);
118b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_CHECK_STATUS;
119b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    lc = index->getBucketCount(status);
120b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_CHECK_STATUS;
121f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    assertEquals("underflow, A-Z, inflow, 2 Cyrillic, overflow",
122f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius                 31, index->getBucketCount(status));
123b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // std::cout << lc << std::endl;
124b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    delete index;
125b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
126b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
127b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // addLabels(Locale)
128b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
129b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    status = U_ZERO_ERROR;
130b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    index = new AlphabeticIndex(Locale::getEnglish(), status);
131b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_CHECK_STATUS;
132b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    AlphabeticIndex &aip = index->addLabels(Locale::getJapanese(), status);
133b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_ASSERT(&aip == index);
134b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_CHECK_STATUS;
135b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    lc = index->getBucketCount(status);
136b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_CHECK_STATUS;
137b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_ASSERT(35 < lc);  // Japanese should add a bunch.  Don't rely on the exact value.
138b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    delete index;
139b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
140b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // GetCollator(),  Get under/in/over flow labels
141b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
142b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    status = U_ZERO_ERROR;
143b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    index = new AlphabeticIndex(Locale::getGerman(), status);
144b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_CHECK_STATUS;
145b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    Collator *germanCol = Collator::createInstance(Locale::getGerman(), status);
146b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_CHECK_STATUS;
147b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    const RuleBasedCollator &indexCol = index->getCollator();
148b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_ASSERT(*germanCol == indexCol);
149b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    delete germanCol;
150b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
151b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    UnicodeString ELLIPSIS;  ELLIPSIS.append((UChar32)0x2026);
152b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    UnicodeString s = index->getUnderflowLabel();
153b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_ASSERT(ELLIPSIS == s);
154b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    s = index->getOverflowLabel();
155b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_ASSERT(ELLIPSIS == s);
156b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    s = index->getInflowLabel();
157b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_ASSERT(ELLIPSIS == s);
158b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    index->setOverflowLabel(UNICODE_STRING_SIMPLE("O"), status);
159b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    index->setUnderflowLabel(UNICODE_STRING_SIMPLE("U"), status).setInflowLabel(UNICODE_STRING_SIMPLE("I"), status);
160b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    s = index->getUnderflowLabel();
161b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_ASSERT(UNICODE_STRING_SIMPLE("U") == s);
162b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    s = index->getOverflowLabel();
163b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_ASSERT(UNICODE_STRING_SIMPLE("O") == s);
164b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    s = index->getInflowLabel();
165b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_ASSERT(UNICODE_STRING_SIMPLE("I") == s);
166b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
167b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
168b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
169b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
170b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    delete index;
171b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
172b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
173b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
174b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    const UnicodeString adam = UNICODE_STRING_SIMPLE("Adam");
175b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    const UnicodeString baker = UNICODE_STRING_SIMPLE("Baker");
176b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    const UnicodeString charlie = UNICODE_STRING_SIMPLE("Charlie");
177b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    const UnicodeString chad = UNICODE_STRING_SIMPLE("Chad");
178b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    const UnicodeString zed  = UNICODE_STRING_SIMPLE("Zed");
179b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    const UnicodeString Cyrillic = UNICODE_STRING_SIMPLE("\\u0410\\u0443\\u0435").unescape();
180b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
181b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // addRecord(), verify that it comes back out.
182b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    //
183b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    status = U_ZERO_ERROR;
184b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    index = new AlphabeticIndex(Locale::getEnglish(), status);
185b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_CHECK_STATUS;
186b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    index->addRecord(UnicodeString("Adam"), this, status);
187b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    UBool   b;
188b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_CHECK_STATUS;
189b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    index->resetBucketIterator(status);
190b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_CHECK_STATUS;
191b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    index->nextBucket(status);  // Move to underflow label
192b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    index->nextBucket(status);  // Move to "A"
193b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_CHECK_STATUS;
194b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    const UnicodeString &label2 = index->getBucketLabel();
195b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    UnicodeString A_STR = UNICODE_STRING_SIMPLE("A");
196b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_ASSERT(A_STR == label2);
197b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
198b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    b = index->nextRecord(status);
199b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_CHECK_STATUS;
200b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_ASSERT(b);
201b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    const UnicodeString &itemName = index->getRecordName();
202b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_ASSERT(adam == itemName);
203b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
204b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    const void *itemContext = index->getRecordData();
205b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_ASSERT(itemContext == this);
206b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
207b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    delete index;
208b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
209b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // clearRecords, addRecord(), Iteration
210b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
211b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    status = U_ZERO_ERROR;
212b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    index = new AlphabeticIndex(Locale::getEnglish(), status);
213b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_CHECK_STATUS;
214b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    while (index->nextBucket(status)) {
215b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        TEST_CHECK_STATUS;
216b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        while (index->nextRecord(status)) {
217b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            TEST_CHECK_STATUS;
218b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            TEST_ASSERT(FALSE);   // No items have been added.
219b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        }
220b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        TEST_CHECK_STATUS;
221b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
222b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
223b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    index->addRecord(adam, NULL, status);
224b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    index->addRecord(baker, NULL, status);
225b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    index->addRecord(charlie, NULL, status);
226b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    index->addRecord(chad, NULL, status);
227b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_CHECK_STATUS;
228b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    int itemCount = 0;
229b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    index->resetBucketIterator(status);
230b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    while (index->nextBucket(status)) {
231b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        TEST_CHECK_STATUS;
232b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        while (index->nextRecord(status)) {
233b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            TEST_CHECK_STATUS;
234b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            ++itemCount;
235b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        }
236b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
237b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_CHECK_STATUS;
238b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_ASSERT(itemCount == 4);
239b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
240b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_ASSERT(index->nextBucket(status) == FALSE);
241b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    index->resetBucketIterator(status);
242b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_CHECK_STATUS;
243b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_ASSERT(index->nextBucket(status) == TRUE);
244b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
245b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    index->clearRecords(status);
246b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_CHECK_STATUS;
247b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    index->resetBucketIterator(status);
248b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    while (index->nextBucket(status)) {
249b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        TEST_CHECK_STATUS;
250b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        while (index->nextRecord(status)) {
251b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            TEST_ASSERT(FALSE);   // No items have been added.
252b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        }
253b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
254b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_CHECK_STATUS;
255b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    delete index;
256b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
257b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // getBucketLabel(), getBucketType()
258b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
259b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    status = U_ZERO_ERROR;
260b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    index = new AlphabeticIndex(Locale::getEnglish(), status);
261b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_CHECK_STATUS;
262b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    index->setUnderflowLabel(adam, status).setOverflowLabel(charlie, status);
263b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_CHECK_STATUS;
264b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    for (i=0; index->nextBucket(status); i++) {
265b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        TEST_CHECK_STATUS;
266b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        UnicodeString label = index->getBucketLabel();
267b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        UAlphabeticIndexLabelType type = index->getBucketLabelType();
268b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (i == 0) {
269b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            TEST_ASSERT(type == U_ALPHAINDEX_UNDERFLOW);
270b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            TEST_ASSERT(label == adam);
271b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        } else if (i <= 26) {
272b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // Labels A - Z for English locale
273b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            TEST_ASSERT(type == U_ALPHAINDEX_NORMAL);
274b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            UnicodeString expectedLabel((UChar)(0x40 + i));
275b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            TEST_ASSERT(expectedLabel == label);
276b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        } else if (i == 27) {
277b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            TEST_ASSERT(type == U_ALPHAINDEX_OVERFLOW);
278b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            TEST_ASSERT(label == charlie);
279b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        } else {
280b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            TEST_ASSERT(FALSE);
281b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        }
282b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
283b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_ASSERT(i==28);
284b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    delete index;
285b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
286b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // getBucketIndex()
287b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
288b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    status = U_ZERO_ERROR;
289b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    index = new AlphabeticIndex(Locale::getEnglish(), status);
290b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_CHECK_STATUS;
291b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    int32_t n = index->getBucketIndex(adam, status);
292b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_CHECK_STATUS;
293b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_ASSERT(n == 1);    /*  Label #0 is underflow, 1 is A, etc. */
294b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    n = index->getBucketIndex(baker, status);
295b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_ASSERT(n == 2);
296b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    n = index->getBucketIndex(Cyrillic, status);
297b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_ASSERT(n == 27);   // Overflow label
298b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    n = index->getBucketIndex(zed, status);
299b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_ASSERT(n == 26);
300b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
301b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    for (i=0; index->nextBucket(status); i++) {
302b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        n = index->getBucketIndex();
303b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        TEST_ASSERT(n == i);
304b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        UnicodeString label = index->getBucketLabel();
305b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        TEST_ASSERT(n == i);
306b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
307b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_ASSERT(i == 28);
308b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
309b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    delete index;
310b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    index = new AlphabeticIndex(Locale::createFromName("ru"), status);
311b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_CHECK_STATUS;
312f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    assertEquals("Russian index.getBucketCount()", 32, index->getBucketCount(status));
313f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    // Latin-script names should go into the underflow label (0)
314f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    // if the Russian collation does not use script reordering,
315f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    // but into the overflow label (getBucketCount()-1)
316f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    // if Russian sorts Cyrillic first.
317f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    int32_t reorderCodes[20];
318f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    int32_t expectedLatinIndex = 0;
319f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    if (index->getCollator().getReorderCodes(reorderCodes, LENGTHOF(reorderCodes), status) > 0) {
320f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        expectedLatinIndex = index->getBucketCount(status) - 1;
321f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    }
322b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    n = index->getBucketIndex(adam, status);
323b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_CHECK_STATUS;
324f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    assertEquals("Russian index.getBucketIndex(adam)", expectedLatinIndex, n);
325b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    n = index->getBucketIndex(baker, status);
326f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    assertEquals("Russian index.getBucketIndex(baker)", expectedLatinIndex, n);
327b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    n = index->getBucketIndex(Cyrillic, status);
328f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    assertEquals("Russian index.getBucketIndex(Cyrillic)", 1, n);
329b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    n = index->getBucketIndex(zed, status);
330f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    assertEquals("Russian index.getBucketIndex(zed)", expectedLatinIndex, n);
331b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
332b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    delete index;
333b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
334b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}
335b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
336b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
337b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic const char * KEY_LOCALES[] = {
338b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            "en", "es", "de", "fr", "ja", "it", "tr", "pt", "zh", "nl",
339b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            "pl", "ar", "ru", "zh_Hant", "ko", "th", "sv", "fi", "da",
340b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            "he", "nb", "el", "hr", "bg", "sk", "lt", "vi", "lv", "sr",
341b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            "pt_PT", "ro", "hu", "cs", "id", "sl", "fil", "fa", "uk",
342b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            "ca", "hi", "et", "eu", "is", "sw", "ms", "bn", "am", "ta",
343b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            "te", "mr", "ur", "ml", "kn", "gu", "or", ""};
344b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
345b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
346b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid AlphabeticIndexTest::ManyLocalesTest() {
347b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    UErrorCode status = U_ZERO_ERROR;
348b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    int32_t  lc = 0;
349b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
350b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    for (int i=0; ; ++i) {
351b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        status = U_ZERO_ERROR;
352b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        const char *localeName = KEY_LOCALES[i];
353b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (localeName[0] == 0) {
354b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            break;
355b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        }
356b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // std::cout <<  localeName << "  ";
357b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        Locale loc = Locale::createFromName(localeName);
358f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        AlphabeticIndex index(loc, status);
359b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        TEST_CHECK_STATUS;
360f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        lc = index.getBucketCount(status);
361b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        TEST_CHECK_STATUS;
362b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // std::cout << "getBucketCount() == " << lc << std::endl;
363b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
364f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        LocalPointer<AlphabeticIndex::ImmutableIndex> immIndex(index.buildImmutableIndex(status));
365f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        TEST_CHECK_STATUS;
366f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        TEST_ASSERT(lc == immIndex->getBucketCount());
367f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius
368f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        assertEquals("initial bucket index", -1, index.getBucketIndex());
369f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        int32_t bucketIndex = 0;
370f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        while (index.nextBucket(status)) {
371b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            TEST_CHECK_STATUS;
372f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius            assertEquals("bucket index", bucketIndex, index.getBucketIndex());
373f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius            const UnicodeString &label = index.getBucketLabel();
374b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            TEST_ASSERT(label.length()>0);
375b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // std::string ss;
376b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // std::cout << ":" << label.toUTF8String(ss);
377f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius            const AlphabeticIndex::Bucket *bucket = immIndex->getBucket(bucketIndex);
378f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius            TEST_ASSERT(bucket != NULL);
379f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius            assertEquals("bucket label vs. immutable: locale=" + UnicodeString(localeName) +
380f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius                         " index=" + bucketIndex,
381f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius                         label, bucket->getLabel());
382f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius            TEST_ASSERT(&label != &bucket->getLabel());  // not the same pointers
383f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius            UAlphabeticIndexLabelType labelType = index.getBucketLabelType();
384f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius            TEST_ASSERT(labelType == bucket->getLabelType());
385f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius            ++bucketIndex;
386b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        }
387b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // std::cout << ":" << std::endl;
388b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
389f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        TEST_ASSERT(immIndex->getBucketCount() == bucketIndex);
390f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        TEST_ASSERT(immIndex->getBucket(-1) == NULL);
391f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        TEST_ASSERT(immIndex->getBucket(bucketIndex) == NULL);
392b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
393b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}
394b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
395b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
396b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// Test data for Pinyin based indexes.
397b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho//  The Chinese characters should be distributed under latin labels in
398b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho//  an index.
399b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
400b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic const char *pinyinTestData[] = {
401b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        "\\u0101", "\\u5416", "\\u58ba", //
402b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        "b", "\\u516b", "\\u62d4", "\\u8500", //
403b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        "c", "\\u5693", "\\u7938", "\\u9e7e", //
404b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        "d", "\\u5491", "\\u8fcf", "\\u964a", //
405b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        "\\u0113","\\u59b8", "\\u92e8", "\\u834b", //
406b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        "f", "\\u53d1", "\\u9197", "\\u99a5", //
407b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        "g", "\\u7324", "\\u91d3", "\\u8142", //
408b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        "h", "\\u598e", "\\u927f", "\\u593b", //
409b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        "j", "\\u4e0c", "\\u6785", "\\u9d58", //
410b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        "k", "\\u5494", "\\u958b", "\\u7a52", //
411b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        "l", "\\u5783", "\\u62c9", "\\u9ba5", //
412b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        "m", "\\u5638", "\\u9ebb", "\\u65c0", //
413b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        "n", "\\u62ff", "\\u80ad", "\\u685b", //
414b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        "\\u014D", "\\u5662", "\\u6bee", "\\u8bb4", //
415b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        "p", "\\u5991", "\\u8019", "\\u8c31", //
416b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        "q", "\\u4e03", "\\u6053", "\\u7f56", //
417b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        "r", "\\u5465", "\\u72aa", "\\u6e03", //
418b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        "s", "\\u4ee8", "\\u9491", "\\u93c1", //
419b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        "t", "\\u4ed6", "\\u9248", "\\u67dd", //
420b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        "w", "\\u5c72", "\\u5558", "\\u5a7a", //
421b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        "x", "\\u5915", "\\u5438", "\\u6bbe", //
422b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        "y", "\\u4e2b", "\\u82bd", "\\u8574", //
423b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        "z", "\\u5e00", "\\u707d", "\\u5c0a",
424b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        NULL
425b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    };
426b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
427b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid AlphabeticIndexTest::HackPinyinTest() {
428b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    UErrorCode status = U_ZERO_ERROR;
429b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    AlphabeticIndex aindex(Locale::createFromName("zh"), status);
430b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_CHECK_STATUS;
431b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
432b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    UnicodeString names[sizeof(pinyinTestData) / sizeof(pinyinTestData[0])];
433b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    int32_t  nameCount;
434b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    for (nameCount=0; pinyinTestData[nameCount] != NULL; nameCount++) {
435b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        names[nameCount] = UnicodeString(pinyinTestData[nameCount], -1, UnicodeString::kInvariant).unescape();
436b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        aindex.addRecord(names[nameCount], &names[nameCount], status);
437b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        TEST_CHECK_STATUS;
438b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (U_FAILURE(status)) {
439b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            return;
440b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        }
441b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
442b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_ASSERT(nameCount == aindex.getRecordCount(status));
443b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
444b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // Weak checking:  make sure that none of the Chinese names landed in the overflow bucket
445b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    //   of the index, and that the names are distributed among several buckets.
446b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    //   (Exact expected data would be subject to change with evolution of the collation rules.)
447b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
448b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    int32_t bucketCount = 0;
449b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    int32_t filledBucketCount = 0;
450b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    while (aindex.nextBucket(status)) {
451b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        bucketCount++;
452b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        UnicodeString label = aindex.getBucketLabel();
453b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // std::string s;
454b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // std::cout << label.toUTF8String(s) << ":  ";
455b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
456b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        UBool  bucketHasContents = FALSE;
457b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        while (aindex.nextRecord(status)) {
458b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            bucketHasContents = TRUE;
459b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            UnicodeString name = aindex.getRecordName();
460b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            if (aindex.getBucketLabelType() != U_ALPHAINDEX_NORMAL) {
461b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                errln("File %s, Line %d, Name \"\\u%x\" is in an under or overflow bucket.",
462b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    __FILE__, __LINE__, name.char32At(0));
463b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            }
464b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // s.clear();
465b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // std::cout << aindex.getRecordName().toUTF8String(s) << " ";
466b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        }
467b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (bucketHasContents) {
468b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            filledBucketCount++;
469b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        }
470b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // std::cout << std::endl;
471b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
472b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_ASSERT(bucketCount > 25);
473b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    TEST_ASSERT(filledBucketCount > 15);
474b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}
475103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
476103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
477103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusvoid AlphabeticIndexTest::TestBug9009() {
478103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    UErrorCode status = U_ZERO_ERROR;
479103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    Locale loc("root");
480103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    AlphabeticIndex aindex(loc, status);
481103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    TEST_CHECK_STATUS;
482103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    aindex.nextBucket(status);  // Crash here before bug was fixed.
483103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    TEST_CHECK_STATUS;
484103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius}
485f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius
486f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Corneliusstatic const char *localeAndIndexCharactersLists[][2] = {
487f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    /* Arabic*/ {"ar", "\\u0627:\\u0628:\\u062A:\\u062B:\\u062C:\\u062D:\\u062E:\\u062F:\\u0630:\\u0631:\\u0632:\\u0633:\\u0634:\\u0635:\\u0636:\\u0637:\\u0638:\\u0639:\\u063A:\\u0641:\\u0642:\\u0643:\\u0644:\\u0645:\\u0646:\\u0647:\\u0648:\\u064A"},
488f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    /* Bulgarian*/  {"bg", "\\u0410:\\u0411:\\u0412:\\u0413:\\u0414:\\u0415:\\u0416:\\u0417:\\u0418:\\u0419:\\u041A:\\u041B:\\u041C:\\u041D:\\u041E:\\u041F:\\u0420:\\u0421:\\u0422:\\u0423:\\u0424:\\u0425:\\u0426:\\u0427:\\u0428:\\u0429:\\u042E:\\u042F"},
489f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    /* Catalan*/    {"ca", "A:B:C:D:E:F:G:H:I:J:K:L:M:N:O:P:Q:R:S:T:U:V:W:X:Y:Z"},
490f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    /* Czech*/  {"cs", "A:B:C:\\u010C:D:E:F:G:H:CH:I:J:K:L:M:N:O:P:Q:R:\\u0158:S:\\u0160:T:U:V:W:X:Y:Z:\\u017D"},
491f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    /* Danish*/ {"da", "A:B:C:D:E:F:G:H:I:J:K:L:M:N:O:P:Q:R:S:T:U:V:W:X:Y:Z:\\u00C6:\\u00D8:\\u00C5"},
492f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    /* German*/ {"de", "A:B:C:D:E:F:G:H:I:J:K:L:M:N:O:P:Q:R:S:Sch:St:T:U:V:W:X:Y:Z"},
493f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    /* Greek*/  {"el", "\\u0391:\\u0392:\\u0393:\\u0394:\\u0395:\\u0396:\\u0397:\\u0398:\\u0399:\\u039A:\\u039B:\\u039C:\\u039D:\\u039E:\\u039F:\\u03A0:\\u03A1:\\u03A3:\\u03A4:\\u03A5:\\u03A6:\\u03A7:\\u03A8:\\u03A9"},
494f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    /* English*/    {"en", "A:B:C:D:E:F:G:H:I:J:K:L:M:N:O:P:Q:R:S:T:U:V:W:X:Y:Z"},
495f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    /* Spanish*/    {"es", "A:B:C:D:E:F:G:H:I:J:K:L:M:N:\\u00D1:O:P:Q:R:S:T:U:V:W:X:Y:Z"},
496f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    /* Estonian*/   {"et", "A:B:C:D:E:F:G:H:I:J:K:L:M:N:O:P:Q:R:S:\\u0160:Z:\\u017D:T:U:V:\\u00D5:\\u00C4:\\u00D6:\\u00DC:X:Y"},
497f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    /* Basque*/ {"eu", "A:B:C:D:E:F:G:H:I:J:K:L:M:N:O:P:Q:R:S:T:U:V:W:X:Y:Z"},
498f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    /* Finnish*/    {"fi", "A:B:C:D:E:F:G:H:I:J:K:L:M:N:O:P:Q:R:S:T:U:V:W:X:Y:Z:\\u00C5:\\u00C4:\\u00D6"},
499f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    /* Filipino*/   {"fil", "A:B:C:D:E:F:G:H:I:J:K:L:M:N:O:P:Q:R:S:T:U:V:W:X:Y:Z"},
500f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    /* French*/ {"fr", "A:B:C:D:E:F:G:H:I:J:K:L:M:N:O:P:Q:R:S:T:U:V:W:X:Y:Z"},
501f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    /* Hebrew*/ {"he", "\\u05D0:\\u05D1:\\u05D2:\\u05D3:\\u05D4:\\u05D5:\\u05D6:\\u05D7:\\u05D8:\\u05D9:\\u05DB:\\u05DC:\\u05DE:\\u05E0:\\u05E1:\\u05E2:\\u05E4:\\u05E6:\\u05E7:\\u05E8:\\u05E9:\\u05EA"},
502f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    /* Icelandic*/  {"is", "A:\\u00C1:B:C:D:\\u00D0:E:\\u00C9:F:G:H:I:\\u00CD:J:K:L:M:N:O:\\u00D3:P:Q:R:S:T:U:\\u00DA:V:W:X:Y:\\u00DD:Z:\\u00DE:\\u00C6:\\u00D6"},
503f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    /* Italian*/    {"it", "A:B:C:D:E:F:G:H:I:J:K:L:M:N:O:P:Q:R:S:T:U:V:W:X:Y:Z"},
504f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    /* Japanese*/   {"ja", "\\u3042:\\u304B:\\u3055:\\u305F:\\u306A:\\u306F:\\u307E:\\u3084:\\u3089:\\u308F"},
505f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    /* Korean*/ {"ko", "\\u3131:\\u3134:\\u3137:\\u3139:\\u3141:\\u3142:\\u3145:\\u3147:\\u3148:\\u314A:\\u314B:\\u314C:\\u314D:\\u314E"},
506f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    /* Lithuanian*/ {"lt", "A:B:C:\\u010C:D:E:F:G:H:I:J:K:L:M:N:O:P:R:S:\\u0160:T:U:V:Z:\\u017D"},
507f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    // This should be the correct data.  Commented till it is fixed in CLDR collation data.
508f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    // {"lv", "A:B:C:\\u010C:D:E:F:G:\\u0122:H:I:Y:J:K:\\u0136:L:\\u013B:M:N:\\u0145:O:P:Q:R:S:\\u0160:T:U:V:W:X:Z:\\u017D"},
509f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    /* Latvian*/    {"lv", "A:B:C:\\u010C:D:E:F:G:\\u0122:H:I:J:K:\\u0136:L:\\u013B:M:N:\\u0145:O:P:Q:R:S:\\u0160:T:U:V:W:X:Y:Z:\\u017D"},
510f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    /* Norwegian Bokm\\u00E5l*/  {"nb", "A:B:C:D:E:F:G:H:I:J:K:L:M:N:O:P:Q:R:S:T:U:V:W:X:Y:Z:\\u00C6:\\u00D8:\\u00C5"},
511f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    /* Dutch*/  {"nl", "A:B:C:D:E:F:G:H:I:J:K:L:M:N:O:P:Q:R:S:T:U:V:W:X:Y:Z"},
512f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    /* Polish*/ {"pl", "A:\\u0104:B:C:\\u0106:D:E:\\u0118:F:G:H:I:J:K:L:\\u0141:M:N:\\u0143:O:\\u00D3:P:Q:R:S:\\u015A:T:U:V:W:X:Y:Z:\\u0179:\\u017B"},
513f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    /* Portuguese*/ {"pt", "A:B:C:D:E:F:G:H:I:J:K:L:M:N:O:P:Q:R:S:T:U:V:W:X:Y:Z"},
514f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    /* Romanian*/   {"ro", "A:\\u0102:\\u00C2:B:C:D:E:F:G:H:I:\\u00CE:J:K:L:M:N:O:P:Q:R:S:\\u0218:T:\\u021A:U:V:W:X:Y:Z"},
515f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    /* Russian*/    {"ru", "\\u0410:\\u0411:\\u0412:\\u0413:\\u0414:\\u0415:\\u0416:\\u0417:\\u0418:\\u0419:\\u041A:\\u041B:\\u041C:\\u041D:\\u041E:\\u041F:\\u0420:\\u0421:\\u0422:\\u0423:\\u0424:\\u0425:\\u0426:\\u0427:\\u0428:\\u0429:\\u042B:\\u042D:\\u042E:\\u042F"},
516f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    /* Slovak*/ {"sk", "A:\\u00C4:B:C:\\u010C:D:E:F:G:H:CH:I:J:K:L:M:N:O:\\u00D4:P:Q:R:S:\\u0160:T:U:V:W:X:Y:Z:\\u017D"},
517f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    /* Slovenian*/  {"sl", "A:B:C:\\u010C:\\u0106:D:\\u0110:E:F:G:H:I:J:K:L:M:N:O:P:Q:R:S:\\u0160:T:U:V:W:X:Y:Z:\\u017D"},
518f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    /* Serbian*/    {"sr", "\\u0410:\\u0411:\\u0412:\\u0413:\\u0414:\\u0402:\\u0415:\\u0416:\\u0417:\\u0418:\\u0408:\\u041A:\\u041B:\\u0409:\\u041C:\\u041D:\\u040A:\\u041E:\\u041F:\\u0420:\\u0421:\\u0422:\\u040B:\\u0423:\\u0424:\\u0425:\\u0426:\\u0427:\\u040F:\\u0428"},
519f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    /* Swedish*/    {"sv", "A:B:C:D:E:F:G:H:I:J:K:L:M:N:O:P:Q:R:S:T:U:V:W:X:Y:Z:\\u00C5:\\u00C4:\\u00D6"},
520f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    /* Turkish*/    {"tr", "A:B:C:\\u00C7:D:E:F:G:H:I:\\u0130:J:K:L:M:N:O:\\u00D6:P:Q:R:S:\\u015E:T:U:\\u00DC:V:W:X:Y:Z"},
521f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    /* Ukrainian*/  {"uk", "\\u0410:\\u0411:\\u0412:\\u0413:\\u0490:\\u0414:\\u0415:\\u0404:\\u0416:\\u0417:\\u0418:\\u0406:\\u0407:\\u0419:\\u041A:\\u041B:\\u041C:\\u041D:\\u041E:\\u041F:\\u0420:\\u0421:\\u0422:\\u0423:\\u0424:\\u0425:\\u0426:\\u0427:\\u0428:\\u0429:\\u042E:\\u042F"},
522f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    /* Vietnamese*/ {"vi", "A:\\u0102:\\u00C2:B:C:D:\\u0110:E:\\u00CA:F:G:H:I:J:K:L:M:N:O:\\u00D4:\\u01A0:P:Q:R:S:T:U:\\u01AF:V:W:X:Y:Z"},
523f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    /* Chinese*/    {"zh", "A:B:C:D:E:F:G:H:I:J:K:L:M:N:O:P:Q:R:S:T:U:V:W:X:Y:Z"},
524f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    /* Chinese (Traditional Han)*/  {"zh_Hant", "1\\u5283:2\\u5283:3\\u5283:4\\u5283:5\\u5283:6\\u5283:7\\u5283:8\\u5283:9\\u5283:10\\u5283:11\\u5283:12\\u5283:13\\u5283:14\\u5283:15\\u5283:16\\u5283:17\\u5283:18\\u5283:19\\u5283:20\\u5283:21\\u5283:22\\u5283:23\\u5283:24\\u5283:25\\u5283:26\\u5283:27\\u5283:28\\u5283:29\\u5283:30\\u5283:31\\u5283:32\\u5283:33\\u5283:35\\u5283:36\\u5283:39\\u5283:48\\u5283"},
525f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius};
526f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius
527f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Corneliusvoid AlphabeticIndexTest::TestIndexCharactersList() {
528f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    UErrorCode status = U_ZERO_ERROR;
529f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    for (int32_t i = 0; i < LENGTHOF(localeAndIndexCharactersLists); ++i) {
530f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        const char *(&localeAndIndexCharacters)[2] = localeAndIndexCharactersLists[i];
531f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        const char *locale = localeAndIndexCharacters[0];
532f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        UnicodeString expectedIndexCharacters
533f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius            = (UnicodeString("\\u2026:") + localeAndIndexCharacters[1] + ":\\u2026").unescape();
534f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        AlphabeticIndex index(locale, status);
535f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        TEST_CHECK_STATUS;
536f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        LocalPointer<AlphabeticIndex::ImmutableIndex> immIndex(index.buildImmutableIndex(status));
537f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        TEST_CHECK_STATUS;
538f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius
539f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        // Join the elements of the list to a string with delimiter ":"
540f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        UnicodeString actualIndexCharacters;
541f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        assertEquals(locale,
542f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius                     expectedIndexCharacters,
543f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius                     joinLabelsAndAppend(*immIndex, actualIndexCharacters));
544f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        logln(locale + UnicodeString(": ") + actualIndexCharacters);
545f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    }
546f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius}
547f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius
548f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Corneliusvoid AlphabeticIndexTest::TestHaniFirst() {
549f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    UErrorCode status = U_ZERO_ERROR;
550f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    LocalPointer<RuleBasedCollator> coll(
551f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        static_cast<RuleBasedCollator *>(Collator::createInstance(Locale::getRoot(), status)));
552f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius
553f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    if (U_FAILURE(status)) {
554f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        dataerrln("Failed Collator::createInstance call - %s", u_errorName(status));
555f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        return;
556f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    }
557f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    int32_t reorderCodes[] = { USCRIPT_HAN };
558f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    coll->setReorderCodes(reorderCodes, LENGTHOF(reorderCodes), status);
559f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    TEST_CHECK_STATUS;
560f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    AlphabeticIndex index(coll.orphan(), status);
561f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    TEST_CHECK_STATUS;
562f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    assertEquals("getBucketCount()", 1, index.getBucketCount(status));   // ... (underflow only)
563f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    index.addLabels(Locale::getEnglish(), status);
564f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    assertEquals("getBucketCount()", 28, index.getBucketCount(status));  // ... A-Z ...
565f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    int32_t bucketIndex = index.getBucketIndex(UnicodeString((UChar)0x897f), status);
566f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    assertEquals("getBucketIndex(U+897F)", 0, bucketIndex);  // underflow bucket
567f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    bucketIndex = index.getBucketIndex("i", status);
568f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    assertEquals("getBucketIndex(i)", 9, bucketIndex);
569f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    bucketIndex = index.getBucketIndex(UnicodeString((UChar)0x03B1), status);
570f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    assertEquals("getBucketIndex(Greek alpha)", 27, bucketIndex);
571f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    // TODO: Test with an unassigned code point (not just U+FFFF)
572f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    // when unassigned code points are not in the Hani reordering group any more.
573f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    // String unassigned = UTF16.valueOf(0x50005);
574f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    bucketIndex = index.getBucketIndex(UnicodeString((UChar)0xFFFF), status);
575f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    assertEquals("getBucketIndex(U+FFFF)", 27, bucketIndex);
576f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius}
577f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius
578f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Corneliusvoid AlphabeticIndexTest::TestPinyinFirst() {
579f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    UErrorCode status = U_ZERO_ERROR;
580f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    LocalPointer<RuleBasedCollator> coll(
581f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        static_cast<RuleBasedCollator *>(Collator::createInstance(Locale::getChinese(), status)));
582f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    if (U_FAILURE(status)) {
583f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        dataerrln("Failed Collator::createInstance call - %s", u_errorName(status));
584f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        return;
585f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    }
586f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    int32_t reorderCodes[] = { USCRIPT_HAN };
587f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    coll->setReorderCodes(reorderCodes, LENGTHOF(reorderCodes), status);
588f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    TEST_CHECK_STATUS;
589f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    AlphabeticIndex index(coll.orphan(), status);
590f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    TEST_CHECK_STATUS;
591f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    index.addLabels(Locale::getChinese(), status);
592f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    assertEquals("getBucketCount()", 28, index.getBucketCount(status));  // ... A-Z ...
593f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    int bucketIndex = index.getBucketIndex(UnicodeString((UChar)0x897f), status);
594f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    assertEquals("getBucketIndex(U+897F)", 'X' - 'A' + 1, bucketIndex);
595f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    bucketIndex = index.getBucketIndex("i", status);
596f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    assertEquals("getBucketIndex(i)", 9, bucketIndex);
597f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    bucketIndex = index.getBucketIndex(UnicodeString((UChar)0x03B1), status);
598f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    assertEquals("getBucketIndex(Greek alpha)", 27, bucketIndex);
599f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    // TODO: Test with an unassigned code point (not just U+FFFF)
600f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    // when unassigned code points are not in the Hani reordering group any more.
601f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    // String unassigned = UTF16.valueOf(0x50005);
602f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    bucketIndex = index.getBucketIndex(UnicodeString((UChar)0xFFFF), status);
603f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    assertEquals("getBucketIndex(U+FFFF)", 27, bucketIndex);
604f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius}
605f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius
606f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Corneliusvoid AlphabeticIndexTest::TestSchSt() {
607f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    UErrorCode status = U_ZERO_ERROR;
608f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    AlphabeticIndex index(Locale::getGerman(), status);
609f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    index.addLabels(UnicodeSet("[\\u00C6{Sch*}{St*}]", status), status);
610f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    TEST_CHECK_STATUS;
611f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    // ... A AE-ligature B-R S Sch St T-Z ...
612f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    LocalPointer<AlphabeticIndex::ImmutableIndex> immIndex(index.buildImmutableIndex(status));
613f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    TEST_CHECK_STATUS;
614f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    assertEquals("getBucketCount()", 31, index.getBucketCount(status));
615f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    assertEquals("immutable getBucketCount()", 31, immIndex->getBucketCount());
616f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    static const struct TestCase {
617f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        const char *name;
618f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        int32_t bucketIndex;
619f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        const char *bucketLabel;
620f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    } testCases[] = {
621f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        // name, bucket index, bucket label
622f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        { "Adelbert", 1, "A" },
623f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        { "Afrika", 1, "A" },
624f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        { "\\u00C6sculap", 2, "\\u00C6" },
625f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        { "Aesthet", 2, "\\u00C6" },
626f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        { "Berlin", 3, "B" },
627f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        { "Rilke", 19, "R" },
628f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        { "Sacher", 20, "S" },
629f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        { "Seiler", 20, "S" },
630f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        { "Sultan", 20, "S" },
631f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        { "Schiller", 21, "Sch" },
632f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        { "Steiff", 22, "St" },
633f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        { "Thomas", 23, "T" }
634f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    };
635f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    for (int32_t i = 0; i < LENGTHOF(testCases); ++i) {
636f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        const TestCase &testCase = testCases[i];
637f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        UnicodeString name = UnicodeString(testCase.name).unescape();
638f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        UnicodeString label = UnicodeString(testCase.bucketLabel).unescape();
639f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        char msg[100];
640f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        sprintf(msg, "getBucketIndex(%s)", testCase.name);
641f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        assertEquals(msg, testCase.bucketIndex, index.getBucketIndex(name, status));
642f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        sprintf(msg, "immutable getBucketIndex(%s)", testCase.name);
643f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        assertEquals(msg, testCase.bucketIndex, immIndex->getBucketIndex(name, status));
644f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        sprintf(msg, "immutable bucket label (%s)", testCase.name);
645f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        assertEquals(msg, label, immIndex->getBucket(testCase.bucketIndex)->getLabel());
646f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    }
647f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius}
648f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius
649f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Corneliusvoid AlphabeticIndexTest::TestNoLabels() {
650f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    UErrorCode status = U_ZERO_ERROR;
651f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    LocalPointer<RuleBasedCollator> coll(
652f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius        static_cast<RuleBasedCollator *>(Collator::createInstance(Locale::getRoot(), status)));
653f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    TEST_CHECK_STATUS;
654f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    AlphabeticIndex index(coll.orphan(), status);
655f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    TEST_CHECK_STATUS;
656f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    index.addRecord(UnicodeString((UChar)0x897f), NULL, status);
657f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    index.addRecord("i", NULL, status);
658f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    index.addRecord(UnicodeString((UChar)0x03B1), NULL, status);
659f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    assertEquals("getBucketCount()", 1, index.getBucketCount(status));  // ...
660f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    TEST_ASSERT(index.nextBucket(status));
661f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    assertEquals("underflow label type", U_ALPHAINDEX_UNDERFLOW, index.getBucketLabelType());
662f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    assertEquals("all records in the underflow bucket", 3, index.getBucketRecordCount());
663f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius}
664f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius
665f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Corneliusvoid AlphabeticIndexTest::TestChineseZhuyin() {
666f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    UErrorCode status = U_ZERO_ERROR;
667f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    char loc[100];
668f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    uloc_forLanguageTag("zh-u-co-zhuyin", loc, LENGTHOF(loc), NULL, &status);
669f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    AlphabeticIndex index(loc, status);
670f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    LocalPointer<AlphabeticIndex::ImmutableIndex> immIndex(index.buildImmutableIndex(status));
671f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    TEST_CHECK_STATUS;
672f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    assertEquals("getBucketCount()", 38, immIndex->getBucketCount());
673f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    assertEquals("label 1", UnicodeString((UChar)0x3105), immIndex->getBucket(1)->getLabel());
674f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    assertEquals("label 2", UnicodeString((UChar)0x3106), immIndex->getBucket(2)->getLabel());
675f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    assertEquals("label 3", UnicodeString((UChar)0x3107), immIndex->getBucket(3)->getLabel());
676f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    assertEquals("label 4", UnicodeString((UChar)0x3108), immIndex->getBucket(4)->getLabel());
677f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius    assertEquals("label 5", UnicodeString((UChar)0x3109), immIndex->getBucket(5)->getLabel());
678f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius}
679103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
6800a61a367aa48577edf1c9ba57c501b8f5e7555d5Craig Corneliusvoid AlphabeticIndexTest::TestJapaneseKanji() {
6810a61a367aa48577edf1c9ba57c501b8f5e7555d5Craig Cornelius    UErrorCode status = U_ZERO_ERROR;
6820a61a367aa48577edf1c9ba57c501b8f5e7555d5Craig Cornelius    AlphabeticIndex index(Locale::getJapanese(), status);
6830a61a367aa48577edf1c9ba57c501b8f5e7555d5Craig Cornelius    LocalPointer<AlphabeticIndex::ImmutableIndex> immIndex(index.buildImmutableIndex(status));
6840a61a367aa48577edf1c9ba57c501b8f5e7555d5Craig Cornelius    TEST_CHECK_STATUS;
6850a61a367aa48577edf1c9ba57c501b8f5e7555d5Craig Cornelius    // There are no index characters for Kanji in the Japanese standard collator.
6860a61a367aa48577edf1c9ba57c501b8f5e7555d5Craig Cornelius    // They should all go into the overflow bucket.
6870a61a367aa48577edf1c9ba57c501b8f5e7555d5Craig Cornelius    static const UChar32 kanji[] = { 0x4E9C, 0x95C7, 0x4E00, 0x58F1 };
6880a61a367aa48577edf1c9ba57c501b8f5e7555d5Craig Cornelius    int32_t overflowIndex = immIndex->getBucketCount() - 1;
6890a61a367aa48577edf1c9ba57c501b8f5e7555d5Craig Cornelius    for(int32_t i = 0; i < LENGTHOF(kanji); ++i) {
6900a61a367aa48577edf1c9ba57c501b8f5e7555d5Craig Cornelius        char msg[40];
6910a61a367aa48577edf1c9ba57c501b8f5e7555d5Craig Cornelius        sprintf(msg, "kanji[%d]=U+%04lX in overflow bucket", (int)i, (long)kanji[i]);
6920a61a367aa48577edf1c9ba57c501b8f5e7555d5Craig Cornelius        assertEquals(msg, overflowIndex, immIndex->getBucketIndex(UnicodeString(kanji[i]), status));
6930a61a367aa48577edf1c9ba57c501b8f5e7555d5Craig Cornelius        TEST_CHECK_STATUS;
6940a61a367aa48577edf1c9ba57c501b8f5e7555d5Craig Cornelius    }
6950a61a367aa48577edf1c9ba57c501b8f5e7555d5Craig Cornelius}
6960a61a367aa48577edf1c9ba57c501b8f5e7555d5Craig Cornelius
697103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
698