| /* |
| ******************************************************************************* |
| * Copyright (C) 2003, International Business Machines Corporation and * |
| * others. All Rights Reserved. * |
| ******************************************************************************* |
| */ |
| |
| #include "unicode/utypes.h" |
| |
| #if !UCONFIG_NO_COLLATION |
| |
| #include "svccoll.h" |
| #include "unicode/coll.h" |
| #include "unicode/strenum.h" |
| #include "hash.h" |
| |
| #include "ucol_imp.h" // internal api needed to test ucollator equality |
| #include "cstring.h" // internal api used to compare locale strings |
| |
| void CollationServiceTest::TestRegister() |
| { |
| // register a singleton |
| const Locale& FR = Locale::getFrance(); |
| const Locale& US = Locale::getUS(); |
| const Locale US_FOO("en", "US", "FOO"); |
| |
| UErrorCode status = U_ZERO_ERROR; |
| |
| Collator* frcol = Collator::createInstance(FR, status); |
| Collator* uscol = Collator::createInstance(US, status); |
| |
| { // try override en_US collator |
| URegistryKey key = Collator::registerInstance(frcol, US, status); |
| |
| Collator* ncol = Collator::createInstance(US_FOO, status); |
| if (*frcol != *ncol) { |
| errln("register of french collator for en_US failed on request for en_US_FOO"); |
| } |
| // ensure original collator's params not touched |
| Locale loc = frcol->getLocale(ULOC_REQUESTED_LOCALE, status); |
| if (loc != FR) { |
| errln(UnicodeString("fr collator's requested locale changed to ") + loc.getName()); |
| } |
| loc = frcol->getLocale(ULOC_VALID_LOCALE, status); |
| if (loc != FR) { |
| errln(UnicodeString("fr collator's valid locale changed to ") + loc.getName()); |
| } |
| |
| loc = ncol->getLocale(ULOC_REQUESTED_LOCALE, status); |
| if (loc != US_FOO) { |
| errln(UnicodeString("requested locale for en_US_FOO is not en_US_FOO but ") + loc.getName()); |
| } |
| loc = ncol->getLocale(ULOC_VALID_LOCALE, status); |
| if (loc != US) { |
| errln(UnicodeString("valid locale for en_US_FOO is not en_US but ") + loc.getName()); |
| } |
| loc = ncol->getLocale(ULOC_ACTUAL_LOCALE, status); |
| if (loc != US) { |
| errln(UnicodeString("actual locale for en_US_FOO is not en_US but ") + loc.getName()); |
| } |
| delete ncol; ncol = NULL; |
| |
| if (!Collator::unregister(key, status)) { |
| errln("failed to unregister french collator"); |
| } |
| // !!! frcol pointer is now invalid !!! |
| |
| ncol = Collator::createInstance(US, status); |
| if (*uscol != *ncol) { |
| errln("collator after unregister does not match original"); |
| } |
| delete ncol; ncol = NULL; |
| } |
| |
| // recreate frcol |
| frcol = Collator::createInstance(FR, status); |
| |
| UCollator* frFR = ucol_open("fr_FR", &status); |
| |
| { // try create collator for new locale |
| Locale fu_FU_FOO("fu", "FU", "FOO"); |
| Locale fu_FU("fu", "FU", ""); |
| |
| Collator* fucol = Collator::createInstance(fu_FU, status); |
| URegistryKey key = Collator::registerInstance(frcol, fu_FU, status); |
| Collator* ncol = Collator::createInstance(fu_FU_FOO, status); |
| if (*frcol != *ncol) { |
| errln("register of fr collator for fu_FU failed"); |
| } |
| |
| UnicodeString locName = fu_FU.getName(); |
| StringEnumeration* localeEnum = Collator::getAvailableLocales(); |
| UBool found = FALSE; |
| const UnicodeString* locStr; |
| for (locStr = localeEnum->snext(status); |
| !found && locStr != NULL; |
| locStr = localeEnum->snext(status)) { |
| // |
| if (locName == *locStr) { |
| found = TRUE; |
| } |
| } |
| delete localeEnum; |
| |
| if (!found) { |
| errln("new locale fu_FU not reported as supported locale"); |
| } |
| |
| UnicodeString displayName; |
| Collator::getDisplayName(fu_FU, displayName); |
| if (displayName != "fu (FU)") { |
| errln(UnicodeString("found ") + displayName + " for fu_FU"); |
| } |
| |
| Collator::getDisplayName(fu_FU, fu_FU, displayName); |
| if (displayName != "fu (FU)") { |
| errln(UnicodeString("found ") + displayName + " for fu_FU"); |
| } |
| |
| // test ucol_open |
| UCollator* fufu = ucol_open("fu_FU_FOO", &status); |
| if (!fufu) { |
| errln("could not open fu_FU_FOO with ucol_open"); |
| } else { |
| if (!ucol_equals(fufu, frFR)) { |
| errln("collator fufu != collator frFR"); |
| } |
| } |
| |
| if (!Collator::unregister(key, status)) { |
| errln("failed to unregister french collator"); |
| } |
| // !!! note frcoll invalid again, but we're no longer using it |
| |
| // other collators should still work ok |
| Locale nloc = ncol->getLocale(ULOC_VALID_LOCALE, status); |
| if (nloc != fu_FU) { |
| errln(UnicodeString("asked for nloc valid locale after close and got") + nloc.getName()); |
| } |
| delete ncol; ncol = NULL; |
| |
| if (fufu) { |
| const char* nlocstr = ucol_getLocale(fufu, ULOC_VALID_LOCALE, &status); |
| if (uprv_strcmp(nlocstr, "fu_FU") != 0) { |
| errln(UnicodeString("asked for uloc valid locale after close and got ") + nlocstr); |
| } |
| ucol_close(fufu); |
| } |
| |
| ncol = Collator::createInstance(fu_FU, status); |
| if (*fucol != *ncol) { |
| errln("collator after unregister does not match original fu_FU"); |
| } |
| delete uscol; uscol = NULL; |
| delete ncol; ncol = NULL; |
| delete fucol; fucol = NULL; |
| } |
| } |
| |
| // ------------------ |
| |
| struct CollatorInfo { |
| Locale locale; |
| Collator* collator; |
| Hashtable* displayNames; // locale name -> string |
| |
| CollatorInfo(const Locale& locale, Collator* collatorToAdopt, Hashtable* displayNamesToAdopt); |
| ~CollatorInfo(); |
| UnicodeString& getDisplayName(const Locale& displayLocale, UnicodeString& name) const; |
| }; |
| |
| CollatorInfo::CollatorInfo(const Locale& _locale, Collator* _collator, Hashtable* _displayNames) |
| : locale(_locale) |
| , collator(_collator) |
| , displayNames(_displayNames) |
| { |
| } |
| |
| CollatorInfo::~CollatorInfo() { |
| delete collator; |
| delete displayNames; |
| } |
| |
| UnicodeString& |
| CollatorInfo::getDisplayName(const Locale& displayLocale, UnicodeString& name) const { |
| if (displayNames) { |
| UnicodeString* val = (UnicodeString*)displayNames->get(displayLocale.getName()); |
| if (val) { |
| name = *val; |
| return name; |
| } |
| } |
| |
| return locale.getDisplayName(displayLocale, name); |
| } |
| |
| // --------------- |
| |
| class TestFactory : public CollatorFactory { |
| CollatorInfo** info; |
| int32_t count; |
| UnicodeString* ids; |
| |
| const CollatorInfo* getInfo(const Locale& loc) const { |
| for (CollatorInfo** p = info; *p; ++p) { |
| if (loc == (**p).locale) { |
| return *p; |
| } |
| } |
| return NULL; |
| } |
| |
| public: |
| TestFactory(CollatorInfo** _info) |
| : info(_info) |
| , count(0) |
| , ids(NULL) |
| { |
| CollatorInfo** p; |
| for (p = info; *p; ++p) {} |
| count = p - info; |
| } |
| |
| ~TestFactory() { |
| for (CollatorInfo** p = info; *p; ++p) { |
| delete *p; |
| } |
| delete[] info; |
| delete[] ids; |
| } |
| |
| virtual Collator* createCollator(const Locale& loc) { |
| const CollatorInfo* ci = getInfo(loc); |
| if (ci) { |
| return ci->collator->clone(); |
| } |
| return NULL; |
| } |
| |
| virtual UnicodeString& getDisplayName(const Locale& objectLocale, |
| const Locale& displayLocale, |
| UnicodeString& result) |
| { |
| const CollatorInfo* ci = getInfo(objectLocale); |
| if (ci) { |
| ci->getDisplayName(displayLocale, result); |
| } else { |
| result.setToBogus(); |
| } |
| return result; |
| } |
| |
| const UnicodeString* getSupportedIDs(int32_t& _count, UErrorCode& status) { |
| if (U_SUCCESS(status)) { |
| if (!ids) { |
| ids = new UnicodeString[count]; |
| if (!ids) { |
| status = U_MEMORY_ALLOCATION_ERROR; |
| _count = 0; |
| return NULL; |
| } |
| |
| for (int i = 0; i < count; ++i) { |
| ids[i] = info[i]->locale.getName(); |
| } |
| } |
| |
| _count = count; |
| return ids; |
| } |
| return NULL; |
| } |
| |
| virtual inline UClassID getDynamicClassID() const { |
| return (UClassID)&gClassID; |
| } |
| |
| static UClassID getStaticClassID() { |
| return (UClassID)&gClassID; |
| } |
| |
| private: |
| static char gClassID; |
| }; |
| |
| char TestFactory::gClassID = 0; |
| |
| void CollationServiceTest::TestRegisterFactory(void) |
| { |
| Locale fu_FU("fu", "FU", ""); |
| Locale fu_FU_FOO("fu", "FU", "FOO"); |
| |
| UErrorCode status = U_ZERO_ERROR; |
| |
| Hashtable* fuFUNames = new Hashtable(FALSE, status); |
| if (!fuFUNames) { |
| errln("memory allocation error"); |
| return; |
| } |
| fuFUNames->setValueDeleter(uhash_deleteUnicodeString); |
| |
| fuFUNames->put(fu_FU.getName(), new UnicodeString("ze leetle bunny Fu-Fu"), status); |
| fuFUNames->put(fu_FU_FOO.getName(), new UnicodeString("zee leetel bunny Foo-Foo"), status); |
| fuFUNames->put(Locale::getUS().getName(), new UnicodeString("little bunny Foo Foo"), status); |
| |
| Collator* frcol = Collator::createInstance(Locale::getFrance(), status); |
| Collator* gecol = Collator::createInstance(Locale::getGermany(), status); |
| Collator* jpcol = Collator::createInstance(Locale::getJapan(), status); |
| |
| CollatorInfo** info = new CollatorInfo*[4]; |
| if (!info) { |
| errln("memory allocation error"); |
| return; |
| } |
| |
| info[0] = new CollatorInfo(Locale::getUS(), frcol, NULL); |
| info[1] = new CollatorInfo(Locale::getFrance(), gecol, NULL); |
| info[2] = new CollatorInfo(fu_FU, jpcol, fuFUNames); |
| info[3] = NULL; |
| |
| TestFactory* factory = new TestFactory(info); |
| if (!factory) { |
| errln("memory allocation error"); |
| return; |
| } |
| |
| Collator* uscol = Collator::createInstance(Locale::getUS(), status); |
| Collator* fucol = Collator::createInstance(fu_FU, status); |
| |
| { |
| URegistryKey key = Collator::registerFactory(factory, status); |
| Collator* ncol = Collator::createInstance(Locale::getUS(), status); |
| if (*frcol != *ncol) { |
| errln("frcoll for en_US failed"); |
| } |
| delete ncol; ncol = NULL; |
| |
| ncol = Collator::createInstance(fu_FU_FOO, status); |
| if (*jpcol != *ncol) { |
| errln("jpcol for fu_FU_FOO failed"); |
| } |
| |
| Locale loc = ncol->getLocale(ULOC_REQUESTED_LOCALE, status); |
| if (loc != fu_FU_FOO) { |
| errln(UnicodeString("requested locale for fu_FU_FOO is not fu_FU_FOO but ") + loc.getName()); |
| } |
| loc = ncol->getLocale(ULOC_VALID_LOCALE, status); |
| if (loc != fu_FU) { |
| errln(UnicodeString("valid locale for fu_FU_FOO is not fu_FU but ") + loc.getName()); |
| } |
| delete ncol; ncol = NULL; |
| |
| UnicodeString locName = fu_FU.getName(); |
| StringEnumeration* localeEnum = Collator::getAvailableLocales(); |
| UBool found = FALSE; |
| const UnicodeString* locStr; |
| for (locStr = localeEnum->snext(status); |
| !found && locStr != NULL; |
| locStr = localeEnum->snext(status)) |
| { |
| if (locName == *locStr) { |
| found = TRUE; |
| } |
| } |
| delete localeEnum; |
| |
| if (!found) { |
| errln("new locale fu_FU not reported as supported locale"); |
| } |
| |
| UnicodeString name; |
| Collator::getDisplayName(fu_FU, name); |
| if (name != "little bunny Foo Foo") { |
| errln(UnicodeString("found ") + name + " for fu_FU"); |
| } |
| |
| Collator::getDisplayName(fu_FU, fu_FU_FOO, name); |
| if (name != "zee leetel bunny Foo-Foo") { |
| errln(UnicodeString("found ") + name + " for fu_FU in fu_FU_FOO"); |
| } |
| |
| if (!Collator::unregister(key, status)) { |
| errln("failed to unregister factory"); |
| } |
| // ja, fr, ge collators no longer valid |
| |
| ncol = Collator::createInstance(fu_FU, status); |
| if (*fucol != *ncol) { |
| errln("collator after unregister does not match original fu_FU"); |
| } |
| delete ncol; |
| } |
| |
| delete fucol; |
| delete uscol; |
| } |
| |
| void CollationServiceTest::runIndexedTest(int32_t index, UBool exec, const char* &name, char* /*par */) |
| { |
| if (exec) logln("TestSuite CollationServiceTest: "); |
| switch (index) { |
| TESTCASE(0, TestRegister); |
| TESTCASE(1, TestRegisterFactory); |
| default: name = ""; break; |
| } |
| } |
| |
| #endif |