static jstring AlphabeticIndex_getBucketLabel(JNIEnv* env, jclass, jlong peer, jint index) { if (index < 0) { jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", "Invalid index: %d", index); return NULL; } // Iterate to the nth bucket. AlphabeticIndex* ai = fromPeer(peer); UErrorCode status = U_ZERO_ERROR; ai->resetBucketIterator(status); if (maybeThrowIcuException(env, "AlphabeticIndex::resetBucketIterator", status)) { return NULL; } for (jint i = 0; i <= index; ++i) { if (!ai->nextBucket(status)) { jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", "Invalid index: %d", index); return NULL; } if (maybeThrowIcuException(env, "AlphabeticIndex::nextBucket", status)) { return NULL; } } // Return "" for the underflow/inflow/overflow buckets. if (ai->getBucketLabelType() != U_ALPHAINDEX_NORMAL) { return env->NewStringUTF(""); } const UnicodeString& label(ai->getBucketLabel()); return env->NewString(label.getBuffer(), label.length()); }
void AlphabeticIndexTest::ManyLocalesTest() { UErrorCode status = U_ZERO_ERROR; int32_t lc = 0; AlphabeticIndex *index = NULL; for (int i=0; ; ++i) { status = U_ZERO_ERROR; const char *localeName = KEY_LOCALES[i]; if (localeName[0] == 0) { break; } // std::cout << localeName << " "; Locale loc = Locale::createFromName(localeName); index = new AlphabeticIndex(loc, status); TEST_CHECK_STATUS; lc = index->getBucketCount(status); TEST_CHECK_STATUS; // std::cout << "getBucketCount() == " << lc << std::endl; while (index->nextBucket(status)) { TEST_CHECK_STATUS; const UnicodeString &label = index->getBucketLabel(); TEST_ASSERT(label.length()>0); // std::string ss; // std::cout << ":" << label.toUTF8String(ss); } // std::cout << ":" << std::endl; delete index; } }
// // APITest. Invoke every function at least once, and check that it does something. // Does not attempt to check complete functionality. // void AlphabeticIndexTest::APITest() { // // Simple constructor and destructor, getBucketCount() // UErrorCode status = U_ZERO_ERROR; int32_t lc = 0; int32_t i = 0; AlphabeticIndex *index = new AlphabeticIndex(Locale::getEnglish(), status); TEST_CHECK_STATUS; lc = index->getBucketCount(status); TEST_CHECK_STATUS; TEST_ASSERT(28 == lc); // 26 letters plus two under/overflow labels. //printf("getBucketCount() == %d\n", lc); delete index; // Constructor from a Collator // status = U_ZERO_ERROR; RuleBasedCollator *coll = dynamic_cast<RuleBasedCollator *>( Collator::createInstance(Locale::getGerman(), status)); TEST_CHECK_STATUS; TEST_ASSERT(coll != NULL); index = new AlphabeticIndex(coll, status); TEST_CHECK_STATUS; TEST_ASSERT(coll == &index->getCollator()); assertEquals("only the underflow label in an index built from a collator", 1, index->getBucketCount(status)); TEST_CHECK_STATUS; delete index; // addLabels() status = U_ZERO_ERROR; index = new AlphabeticIndex(Locale::getEnglish(), status); TEST_CHECK_STATUS; UnicodeSet additions; additions.add((UChar32)0x410).add((UChar32)0x415); // A couple of Cyrillic letters index->addLabels(additions, status); TEST_CHECK_STATUS; lc = index->getBucketCount(status); TEST_CHECK_STATUS; assertEquals("underflow, A-Z, inflow, 2 Cyrillic, overflow", 31, index->getBucketCount(status)); // std::cout << lc << std::endl; delete index; // addLabels(Locale) status = U_ZERO_ERROR; index = new AlphabeticIndex(Locale::getEnglish(), status); TEST_CHECK_STATUS; AlphabeticIndex &aip = index->addLabels(Locale::getJapanese(), status); TEST_ASSERT(&aip == index); TEST_CHECK_STATUS; lc = index->getBucketCount(status); TEST_CHECK_STATUS; TEST_ASSERT(35 < lc); // Japanese should add a bunch. Don't rely on the exact value. delete index; // GetCollator(), Get under/in/over flow labels status = U_ZERO_ERROR; index = new AlphabeticIndex(Locale::getGerman(), status); TEST_CHECK_STATUS; Collator *germanCol = Collator::createInstance(Locale::getGerman(), status); TEST_CHECK_STATUS; const RuleBasedCollator &indexCol = index->getCollator(); TEST_ASSERT(*germanCol == indexCol); delete germanCol; UnicodeString ELLIPSIS; ELLIPSIS.append((UChar32)0x2026); UnicodeString s = index->getUnderflowLabel(); TEST_ASSERT(ELLIPSIS == s); s = index->getOverflowLabel(); TEST_ASSERT(ELLIPSIS == s); s = index->getInflowLabel(); TEST_ASSERT(ELLIPSIS == s); index->setOverflowLabel(UNICODE_STRING_SIMPLE("O"), status); index->setUnderflowLabel(UNICODE_STRING_SIMPLE("U"), status).setInflowLabel(UNICODE_STRING_SIMPLE("I"), status); s = index->getUnderflowLabel(); TEST_ASSERT(UNICODE_STRING_SIMPLE("U") == s); s = index->getOverflowLabel(); TEST_ASSERT(UNICODE_STRING_SIMPLE("O") == s); s = index->getInflowLabel(); TEST_ASSERT(UNICODE_STRING_SIMPLE("I") == s); delete index; const UnicodeString adam = UNICODE_STRING_SIMPLE("Adam"); const UnicodeString baker = UNICODE_STRING_SIMPLE("Baker"); const UnicodeString charlie = UNICODE_STRING_SIMPLE("Charlie"); const UnicodeString chad = UNICODE_STRING_SIMPLE("Chad"); const UnicodeString zed = UNICODE_STRING_SIMPLE("Zed"); const UnicodeString Cyrillic = UNICODE_STRING_SIMPLE("\\u0410\\u0443\\u0435").unescape(); // addRecord(), verify that it comes back out. // status = U_ZERO_ERROR; index = new AlphabeticIndex(Locale::getEnglish(), status); TEST_CHECK_STATUS; index->addRecord(UnicodeString("Adam"), this, status); UBool b; TEST_CHECK_STATUS; index->resetBucketIterator(status); TEST_CHECK_STATUS; index->nextBucket(status); // Move to underflow label index->nextBucket(status); // Move to "A" TEST_CHECK_STATUS; const UnicodeString &label2 = index->getBucketLabel(); UnicodeString A_STR = UNICODE_STRING_SIMPLE("A"); TEST_ASSERT(A_STR == label2); b = index->nextRecord(status); TEST_CHECK_STATUS; TEST_ASSERT(b); const UnicodeString &itemName = index->getRecordName(); TEST_ASSERT(adam == itemName); const void *itemContext = index->getRecordData(); TEST_ASSERT(itemContext == this); delete index; // clearRecords, addRecord(), Iteration status = U_ZERO_ERROR; index = new AlphabeticIndex(Locale::getEnglish(), status); TEST_CHECK_STATUS; while (index->nextBucket(status)) { TEST_CHECK_STATUS; while (index->nextRecord(status)) { TEST_CHECK_STATUS; TEST_ASSERT(FALSE); // No items have been added. } TEST_CHECK_STATUS; } index->addRecord(adam, NULL, status); index->addRecord(baker, NULL, status); index->addRecord(charlie, NULL, status); index->addRecord(chad, NULL, status); TEST_CHECK_STATUS; int itemCount = 0; index->resetBucketIterator(status); while (index->nextBucket(status)) { TEST_CHECK_STATUS; while (index->nextRecord(status)) { TEST_CHECK_STATUS; ++itemCount; } } TEST_CHECK_STATUS; TEST_ASSERT(itemCount == 4); TEST_ASSERT(index->nextBucket(status) == FALSE); index->resetBucketIterator(status); TEST_CHECK_STATUS; TEST_ASSERT(index->nextBucket(status) == TRUE); index->clearRecords(status); TEST_CHECK_STATUS; index->resetBucketIterator(status); while (index->nextBucket(status)) { TEST_CHECK_STATUS; while (index->nextRecord(status)) { TEST_ASSERT(FALSE); // No items have been added. } } TEST_CHECK_STATUS; delete index; // getBucketLabel(), getBucketType() status = U_ZERO_ERROR; index = new AlphabeticIndex(Locale::getEnglish(), status); TEST_CHECK_STATUS; index->setUnderflowLabel(adam, status).setOverflowLabel(charlie, status); TEST_CHECK_STATUS; for (i=0; index->nextBucket(status); i++) { TEST_CHECK_STATUS; UnicodeString label = index->getBucketLabel(); UAlphabeticIndexLabelType type = index->getBucketLabelType(); if (i == 0) { TEST_ASSERT(type == U_ALPHAINDEX_UNDERFLOW); TEST_ASSERT(label == adam); } else if (i <= 26) { // Labels A - Z for English locale TEST_ASSERT(type == U_ALPHAINDEX_NORMAL); UnicodeString expectedLabel((UChar)(0x40 + i)); TEST_ASSERT(expectedLabel == label); } else if (i == 27) { TEST_ASSERT(type == U_ALPHAINDEX_OVERFLOW); TEST_ASSERT(label == charlie); } else { TEST_ASSERT(FALSE); } } TEST_ASSERT(i==28); delete index; // getBucketIndex() status = U_ZERO_ERROR; index = new AlphabeticIndex(Locale::getEnglish(), status); TEST_CHECK_STATUS; int32_t n = index->getBucketIndex(adam, status); TEST_CHECK_STATUS; TEST_ASSERT(n == 1); /* Label #0 is underflow, 1 is A, etc. */ n = index->getBucketIndex(baker, status); TEST_ASSERT(n == 2); n = index->getBucketIndex(Cyrillic, status); TEST_ASSERT(n == 27); // Overflow label n = index->getBucketIndex(zed, status); TEST_ASSERT(n == 26); for (i=0; index->nextBucket(status); i++) { n = index->getBucketIndex(); TEST_ASSERT(n == i); UnicodeString label = index->getBucketLabel(); TEST_ASSERT(n == i); } TEST_ASSERT(i == 28); delete index; index = new AlphabeticIndex(Locale::createFromName("ru"), status); TEST_CHECK_STATUS; assertEquals("Russian index.getBucketCount()", 32, index->getBucketCount(status)); // Latin-script names should go into the underflow label (0) // if the Russian collation does not use script reordering, // but into the overflow label (getBucketCount()-1) // if Russian sorts Cyrillic first. int32_t reorderCodes[20]; int32_t expectedLatinIndex = 0; if (index->getCollator().getReorderCodes(reorderCodes, LENGTHOF(reorderCodes), status) > 0) { expectedLatinIndex = index->getBucketCount(status) - 1; } n = index->getBucketIndex(adam, status); TEST_CHECK_STATUS; assertEquals("Russian index.getBucketIndex(adam)", expectedLatinIndex, n); n = index->getBucketIndex(baker, status); assertEquals("Russian index.getBucketIndex(baker)", expectedLatinIndex, n); n = index->getBucketIndex(Cyrillic, status); assertEquals("Russian index.getBucketIndex(Cyrillic)", 1, n); n = index->getBucketIndex(zed, status); assertEquals("Russian index.getBucketIndex(zed)", expectedLatinIndex, n); delete index; }
// // APITest. Invoke every function at least once, and check that it does something. // Does not attempt to check complete functionality. // void AlphabeticIndexTest::APITest() { // // Simple constructor and destructor, getBucketCount() // UErrorCode status = U_ZERO_ERROR; int32_t lc = 0; int32_t i = 0; AlphabeticIndex *index = new AlphabeticIndex(Locale::getEnglish(), status); TEST_CHECK_STATUS; lc = index->getBucketCount(status); TEST_CHECK_STATUS; TEST_ASSERT(28 == lc); // 26 letters plus two under/overflow labels. //printf("getBucketCount() == %d\n", lc); delete index; // addLabels() status = U_ZERO_ERROR; index = new AlphabeticIndex(Locale::getEnglish(), status); TEST_CHECK_STATUS; UnicodeSet additions; additions.add((UChar32)0x410).add((UChar32)0x415); // A couple of Cyrillic letters index->addLabels(additions, status); TEST_CHECK_STATUS; lc = index->getBucketCount(status); TEST_CHECK_STATUS; // TODO: should get 31. Java also gives 30. Needs fixing TEST_ASSERT(30 == lc); // 26 Latin letters plus // TEST_ASSERT(31 == lc); // 26 Latin letters plus // 2 Cyrillic letters plus // 1 inflow label plus // two under/overflow labels. // std::cout << lc << std::endl; delete index; // addLabels(Locale) status = U_ZERO_ERROR; index = new AlphabeticIndex(Locale::getEnglish(), status); TEST_CHECK_STATUS; AlphabeticIndex &aip = index->addLabels(Locale::getJapanese(), status); TEST_ASSERT(&aip == index); TEST_CHECK_STATUS; lc = index->getBucketCount(status); TEST_CHECK_STATUS; TEST_ASSERT(35 < lc); // Japanese should add a bunch. Don't rely on the exact value. delete index; // GetCollator(), Get under/in/over flow labels status = U_ZERO_ERROR; index = new AlphabeticIndex(Locale::getGerman(), status); TEST_CHECK_STATUS; Collator *germanCol = Collator::createInstance(Locale::getGerman(), status); TEST_CHECK_STATUS; const RuleBasedCollator &indexCol = index->getCollator(); TEST_ASSERT(*germanCol == indexCol); delete germanCol; UnicodeString ELLIPSIS; ELLIPSIS.append((UChar32)0x2026); UnicodeString s = index->getUnderflowLabel(); TEST_ASSERT(ELLIPSIS == s); s = index->getOverflowLabel(); TEST_ASSERT(ELLIPSIS == s); s = index->getInflowLabel(); TEST_ASSERT(ELLIPSIS == s); index->setOverflowLabel(UNICODE_STRING_SIMPLE("O"), status); index->setUnderflowLabel(UNICODE_STRING_SIMPLE("U"), status).setInflowLabel(UNICODE_STRING_SIMPLE("I"), status); s = index->getUnderflowLabel(); TEST_ASSERT(UNICODE_STRING_SIMPLE("U") == s); s = index->getOverflowLabel(); TEST_ASSERT(UNICODE_STRING_SIMPLE("O") == s); s = index->getInflowLabel(); TEST_ASSERT(UNICODE_STRING_SIMPLE("I") == s); delete index; const UnicodeString adam = UNICODE_STRING_SIMPLE("Adam"); const UnicodeString baker = UNICODE_STRING_SIMPLE("Baker"); const UnicodeString charlie = UNICODE_STRING_SIMPLE("Charlie"); const UnicodeString chad = UNICODE_STRING_SIMPLE("Chad"); const UnicodeString zed = UNICODE_STRING_SIMPLE("Zed"); const UnicodeString Cyrillic = UNICODE_STRING_SIMPLE("\\u0410\\u0443\\u0435").unescape(); // addRecord(), verify that it comes back out. // status = U_ZERO_ERROR; index = new AlphabeticIndex(Locale::getEnglish(), status); TEST_CHECK_STATUS; index->addRecord(UnicodeString("Adam"), this, status); UBool b; TEST_CHECK_STATUS; index->resetBucketIterator(status); TEST_CHECK_STATUS; index->nextBucket(status); // Move to underflow label index->nextBucket(status); // Move to "A" TEST_CHECK_STATUS; const UnicodeString &label2 = index->getBucketLabel(); UnicodeString A_STR = UNICODE_STRING_SIMPLE("A"); TEST_ASSERT(A_STR == label2); b = index->nextRecord(status); TEST_CHECK_STATUS; TEST_ASSERT(b); const UnicodeString &itemName = index->getRecordName(); TEST_ASSERT(adam == itemName); const void *itemContext = index->getRecordData(); TEST_ASSERT(itemContext == this); delete index; // clearRecords, addRecord(), Iteration status = U_ZERO_ERROR; index = new AlphabeticIndex(Locale::getEnglish(), status); TEST_CHECK_STATUS; while (index->nextBucket(status)) { TEST_CHECK_STATUS; while (index->nextRecord(status)) { TEST_CHECK_STATUS; TEST_ASSERT(FALSE); // No items have been added. } TEST_CHECK_STATUS; } index->addRecord(adam, NULL, status); index->addRecord(baker, NULL, status); index->addRecord(charlie, NULL, status); index->addRecord(chad, NULL, status); TEST_CHECK_STATUS; int itemCount = 0; index->resetBucketIterator(status); while (index->nextBucket(status)) { TEST_CHECK_STATUS; while (index->nextRecord(status)) { TEST_CHECK_STATUS; ++itemCount; } } TEST_CHECK_STATUS; TEST_ASSERT(itemCount == 4); TEST_ASSERT(index->nextBucket(status) == FALSE); index->resetBucketIterator(status); TEST_CHECK_STATUS; TEST_ASSERT(index->nextBucket(status) == TRUE); index->clearRecords(status); TEST_CHECK_STATUS; index->resetBucketIterator(status); while (index->nextBucket(status)) { TEST_CHECK_STATUS; while (index->nextRecord(status)) { TEST_ASSERT(FALSE); // No items have been added. } } TEST_CHECK_STATUS; delete index; // getBucketLabel(), getBucketType() status = U_ZERO_ERROR; index = new AlphabeticIndex(Locale::getEnglish(), status); TEST_CHECK_STATUS; index->setUnderflowLabel(adam, status).setOverflowLabel(charlie, status); TEST_CHECK_STATUS; for (i=0; index->nextBucket(status); i++) { TEST_CHECK_STATUS; UnicodeString label = index->getBucketLabel(); UAlphabeticIndexLabelType type = index->getBucketLabelType(); if (i == 0) { TEST_ASSERT(type == U_ALPHAINDEX_UNDERFLOW); TEST_ASSERT(label == adam); } else if (i <= 26) { // Labels A - Z for English locale TEST_ASSERT(type == U_ALPHAINDEX_NORMAL); UnicodeString expectedLabel((UChar)(0x40 + i)); TEST_ASSERT(expectedLabel == label); } else if (i == 27) { TEST_ASSERT(type == U_ALPHAINDEX_OVERFLOW); TEST_ASSERT(label == charlie); } else { TEST_ASSERT(FALSE); } } TEST_ASSERT(i==28); delete index; // getBucketIndex() status = U_ZERO_ERROR; index = new AlphabeticIndex(Locale::getEnglish(), status); TEST_CHECK_STATUS; int32_t n = index->getBucketIndex(adam, status); TEST_CHECK_STATUS; TEST_ASSERT(n == 1); /* Label #0 is underflow, 1 is A, etc. */ n = index->getBucketIndex(baker, status); TEST_ASSERT(n == 2); n = index->getBucketIndex(Cyrillic, status); TEST_ASSERT(n == 27); // Overflow label n = index->getBucketIndex(zed, status); TEST_ASSERT(n == 26); for (i=0; index->nextBucket(status); i++) { n = index->getBucketIndex(); TEST_ASSERT(n == i); UnicodeString label = index->getBucketLabel(); TEST_ASSERT(n == i); } TEST_ASSERT(i == 28); delete index; index = new AlphabeticIndex(Locale::createFromName("ru"), status); //Locale loc = Locale::createFromName(localeName); TEST_CHECK_STATUS; n = index->getBucketIndex(adam, status); TEST_CHECK_STATUS; TEST_ASSERT(n == 0); // Label #0 is underflow n = index->getBucketIndex(baker, status); TEST_ASSERT(n == 0); n = index->getBucketIndex(Cyrillic, status); TEST_ASSERT(n == 1); // Overflow label n = index->getBucketIndex(zed, status); TEST_ASSERT(n == 0); delete index; }