]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/test/intltest/svccoll.cpp
ICU-531.30.tar.gz
[apple/icu.git] / icuSources / test / intltest / svccoll.cpp
index 4c1db47406b1ddbfd61f3c89d285ce7fa0713c4e..f9dfb5188cc9ae30fd2514b340aa12dc5ab97819 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *******************************************************************************
- * Copyright (C) 2003-2006, International Business Machines Corporation and    *
- * others. All Rights Reserved.                                                *
+ * Copyright (C) 2003-2014, International Business Machines Corporation and
+ * others. All Rights Reserved.
  *******************************************************************************
  */
 
@@ -15,7 +15,6 @@
 #include "hash.h"
 #include "uassert.h"
 
-#include "ucol_imp.h" // internal api needed to test ucollator equality
 #include "cstring.h" // internal api used to compare locale strings
 
 void CollationServiceTest::runIndexedTest(int32_t index, UBool exec, const char* &name, char* /*par */)
@@ -29,45 +28,42 @@ void CollationServiceTest::runIndexedTest(int32_t index, UBool exec, const char*
     }
 }
 
-void CollationServiceTest::TestRegister() 
+void CollationServiceTest::TestRegister()
 {
 #if !UCONFIG_NO_SERVICE
     // 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);
     if(U_FAILURE(status)) {
-        errln("Failed to create collators with %s", u_errorName(status));
+        errcheckln(status, "Failed to create collators with %s", u_errorName(status));
         delete frcol;
         delete uscol;
         return;
     }
-    
+
     { // try override en_US collator
+        Collator *clone = frcol->clone();
         URegistryKey key = Collator::registerInstance(frcol, US, status);
-        
+        // frcol has been adopted. We must not use it any more, nor rely on its attributes.
+        frcol = NULL;
+
         Collator* ncol = Collator::createInstance(US_FOO, status);
-        if (*frcol != *ncol) {
+        if (*clone != *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());
+        delete clone;
+
+        // The requested locale may be the same as the valid locale,
+        // or may not be supported at all. See ticket #10477.
+        Locale loc = ncol->getLocale(ULOC_REQUESTED_LOCALE, status);
+        if (loc != US_FOO && loc != US) {
+            errln(UnicodeString("requested locale for en_US_FOO is not en_US_FOO nor en_US but ") + loc.getName());
         }
         loc = ncol->getLocale(ULOC_VALID_LOCALE, status);
         if (loc != US) {
@@ -78,35 +74,37 @@ void CollationServiceTest::TestRegister()
             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);
-    
+
+    LocalUCollatorPointer 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);
+        Collator *clone = frcol->clone();
         URegistryKey key = Collator::registerInstance(frcol, fu_FU, status);
+        frcol = NULL;  // frcol has been adopted.
         Collator* ncol = Collator::createInstance(fu_FU_FOO, status);
-        if (*frcol != *ncol) {
+        if (*clone != *ncol) {
             errln("register of fr collator for fu_FU failed");
         }
-        
+        delete clone;
+
         UnicodeString locName = fu_FU.getName();
         StringEnumeration* localeEnum = Collator::getAvailableLocales();
         UBool found = FALSE;
@@ -145,53 +143,60 @@ void CollationServiceTest::TestRegister()
 
         delete localeEnum;
         delete le2;
-        
+
         if (!found) {
             errln("new locale fu_FU not reported as supported locale");
         }
-        
+
         UnicodeString displayName;
         Collator::getDisplayName(fu_FU, displayName);
-        if (displayName != "fu (FU)") {
+        /* The locale display pattern for the locale ja, ko, and zh are different. */
+        const UChar zh_fuFU_Array[] = { 0x0066, 0x0075, 0xff08, 0x0046, 0x0055, 0xff09, 0 };
+        const UnicodeString zh_fuFU(zh_fuFU_Array);
+        const Locale& defaultLocale = Locale::getDefault();
+        if (displayName != "fu (FU)" &&
+           ((defaultLocale == Locale::getKorean() && defaultLocale == Locale::getJapanese()) && displayName == "fu(FU)") &&
+           ((defaultLocale == Locale::getChinese()) && displayName != zh_fuFU)) {
             errln(UnicodeString("found ") + displayName + " for fu_FU");
         }
-        
+
         Collator::getDisplayName(fu_FU, fu_FU, displayName);
-        if (displayName != "fu (FU)") {
+        if (displayName != "fu (FU)" &&
+           ((defaultLocale == Locale::getKorean() && defaultLocale == Locale::getJapanese()) && displayName == "fu(FU)") &&
+           ((defaultLocale == Locale::getChinese()) && displayName != zh_fuFU)) {
             errln(UnicodeString("found ") + displayName + " for fu_FU");
         }
-        
+
         // test ucol_open
-        UCollator* fufu = ucol_open("fu_FU_FOO", &status);
-        if (!fufu) {
+        LocalUCollatorPointer fufu(ucol_open("fu_FU_FOO", &status));
+        if (fufu.isNull()) {
             errln("could not open fu_FU_FOO with ucol_open");
         } else {
-            if (!ucol_equals(fufu, frFR)) {
+            if (*Collator::fromUCollator(fufu.getAlias()) !=
+                    *Collator::fromUCollator(frFR.getAlias())) {
                 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 (fufu.isValid()) {
+            const char* nlocstr = ucol_getLocaleByType(fufu.getAlias(), 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);
         }
-        ucol_close(frFR);
-        
+
         ncol = Collator::createInstance(fu_FU, status);
         if (*fucol != *ncol) {
             errln("collator after unregister does not match original fu_FU");
@@ -221,6 +226,7 @@ CollatorInfo::CollatorInfo(const Locale& _locale, Collator* _collator, Hashtable
   , collator(_collator)
   , displayNames(_displayNames)
 {
+  collator->setLocales(locale, locale, locale);
 }
 
 CollatorInfo::~CollatorInfo() {
@@ -228,7 +234,7 @@ CollatorInfo::~CollatorInfo() {
   delete displayNames;
 }
 
-UnicodeString& 
+UnicodeString&
 CollatorInfo::getDisplayName(const Locale& displayLocale, UnicodeString& name) const {
   if (displayNames) {
     UnicodeString* val = (UnicodeString*)displayNames->get(displayLocale.getName());
@@ -257,8 +263,8 @@ class TestFactory : public CollatorFactory {
     return NULL;
   }
 
-public:       
-  TestFactory(CollatorInfo** _info) 
+public:
+  TestFactory(CollatorInfo** _info)
     : info(_info)
     , count(0)
     , ids(NULL)
@@ -284,7 +290,7 @@ public:
     return NULL;
   }
 
-  virtual UnicodeString& getDisplayName(const Locale& objectLocale, 
+  virtual UnicodeString& getDisplayName(const Locale& objectLocale,
                                         const Locale& displayLocale,
                                         UnicodeString& result)
   {
@@ -333,58 +339,58 @@ private:
 char TestFactory::gClassID = 0;
 #endif
 
-void CollationServiceTest::TestRegisterFactory(void) 
+void CollationServiceTest::TestRegisterFactory(void)
 {
 #if !UCONFIG_NO_SERVICE
     int32_t n1, n2, n3;
     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->setValueDeleter(uprv_deleteUObject);
+
     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::getDefault().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);
     if(U_FAILURE(status)) {
-      errln("Failed to create collators with %s", u_errorName(status));
+      errcheckln(status, "Failed to create collators with %s", u_errorName(status));
       delete frcol;
       delete gecol;
       delete jpcol;
       delete fuFUNames;
       return;
     }
-    
+
     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);
-    
+
     {
         n1 = checkAvailable("before registerFactory");
 
@@ -398,22 +404,24 @@ void CollationServiceTest::TestRegisterFactory(void)
             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");
         }
-        
+
+        // The requested locale may be the same as the valid locale,
+        // or may not be supported at all. See ticket #10477.
         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());
+        if (loc != fu_FU_FOO && loc != fu_FU) {
+            errln(UnicodeString("requested locale for fu_FU_FOO is not fu_FU_FOO nor fu_FU 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;
@@ -427,27 +435,27 @@ void CollationServiceTest::TestRegisterFactory(void)
             }
         }
         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");
@@ -457,7 +465,7 @@ void CollationServiceTest::TestRegisterFactory(void)
         n3 = checkAvailable("after unregister");
         assertTrue("count after unregister == count before register", n3 == n1);
     }
-    
+
     delete fucol;
     delete uscol;
 #endif
@@ -558,29 +566,45 @@ void CollationServiceTest::TestSeparateTree() {
     if (!assertSuccess("getKeywords", ec)) return;
     checkStringEnumeration("getKeywords", *iter, KW, KW_COUNT);
     delete iter;
-    
+
     iter = Collator::getKeywordValues(KW[0], ec);
-    if (!assertTrue("getKeywordValues != NULL", iter!=NULL)) return;
+    if (!assertTrue("getKeywordValues != NULL", iter!=NULL, FALSE, TRUE)) return;
     if (!assertSuccess("getKeywordValues", ec)) return;
     checkStringEnumeration("getKeywordValues", *iter, KWVAL, KWVAL_COUNT);
     delete iter;
 
     UBool isAvailable;
     Locale equiv = Collator::getFunctionalEquivalent("collation",
-                                                     Locale::createFromName("fr"),
+                                                     Locale::createFromName("de"),
                                                      isAvailable, ec);
     assertSuccess("getFunctionalEquivalent", ec);
-    assertEquals("getFunctionalEquivalent(fr)", "fr", equiv.getName());
-    assertTrue("getFunctionalEquivalent(fr).isAvailable==TRUE",
+    assertEquals("getFunctionalEquivalent(de)", "root", equiv.getName());
+    assertTrue("getFunctionalEquivalent(de).isAvailable==TRUE",
                isAvailable == TRUE);
-    
+
     equiv = Collator::getFunctionalEquivalent("collation",
-                                              Locale::createFromName("fr_FR"),
+                                              Locale::createFromName("de_DE"),
                                               isAvailable, ec);
     assertSuccess("getFunctionalEquivalent", ec);
-    assertEquals("getFunctionalEquivalent(fr_FR)", "fr", equiv.getName());
-    assertTrue("getFunctionalEquivalent(fr_FR).isAvailable==TRUE",
+    assertEquals("getFunctionalEquivalent(de_DE)", "root", equiv.getName());
+    assertTrue("getFunctionalEquivalent(de_DE).isAvailable==FALSE",
+               isAvailable == FALSE);
+
+    equiv = Collator::getFunctionalEquivalent("collation",
+                                                     Locale::createFromName("sv"),
+                                                     isAvailable, ec);
+    assertSuccess("getFunctionalEquivalent", ec);
+    assertEquals("getFunctionalEquivalent(sv)", "sv", equiv.getName());
+    assertTrue("getFunctionalEquivalent(sv).isAvailable==TRUE",
                isAvailable == TRUE);
+
+    equiv = Collator::getFunctionalEquivalent("collation",
+                                              Locale::createFromName("sv_SE"),
+                                              isAvailable, ec);
+    assertSuccess("getFunctionalEquivalent", ec);
+    assertEquals("getFunctionalEquivalent(sv_SE)", "sv", equiv.getName());
+    assertTrue("getFunctionalEquivalent(sv_SE).isAvailable==FALSE",
+               isAvailable == FALSE);
 }
 
 #endif