]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/test/intltest/icusvtst.cpp
ICU-62107.0.1.tar.gz
[apple/icu.git] / icuSources / test / intltest / icusvtst.cpp
index 0727d658a392e2d4e7ee9035e04aafe3c2b816cb..fb6fef188e1719d65e2e93d32e4c6fe641a61e1f 100644 (file)
@@ -1,19 +1,22 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /**
  *******************************************************************************
- * Copyright (C) 2001-2002, International Business Machines Corporation and    *
- * others. All Rights Reserved.                                                *
- *******************************************************************************
- *
+ * Copyright (C) 2001-2016, International Business Machines Corporation and
+ * others. All Rights Reserved.
  *******************************************************************************
  */
 
+#include "utypeinfo.h"  // for 'typeid' to work
+
 #include "unicode/utypes.h"
 
 #if !UCONFIG_NO_SERVICE
 
+#include "cmemory.h"
 #include "icusvtst.h"
-
-#include "iculserv.h"
+#include "servloc.h"
+#include <stdio.h>
 
 
 class MyListener : public EventListener {
@@ -24,30 +27,39 @@ class WrongListener : public EventListener {
 
 class ICUNSubclass : public ICUNotifier {
     public:
-    UBool acceptsListener(const EventListener& l) const {
+    UBool acceptsListener(const EventListener& /*l*/) const {
         return TRUE;
         // return l instanceof MyListener;
     }
 
-    virtual void notifyListener(EventListener& l) const {
+    virtual void notifyListener(EventListener& /*l*/) const {
     }
 };
 
+// This factory does nothing
+class LKFSubclass0 : public LocaleKeyFactory {
+public:
+        LKFSubclass0()
+                : LocaleKeyFactory(VISIBLE, "LKFSubclass0")
+        {
+        }
+};
+
 class LKFSubclass : public LocaleKeyFactory {
-       Hashtable table;
+    Hashtable table;
 
     public:
     LKFSubclass(UBool visible) 
         : LocaleKeyFactory(visible ? VISIBLE : INVISIBLE, "LKFSubclass")
     {
-               UErrorCode status = U_ZERO_ERROR;
-               table.put("en_US", this, status);
+        UErrorCode status = U_ZERO_ERROR;
+        table.put("en_US", this, status);
     }
 
     protected:
-       virtual const Hashtable* getSupportedIDs(UErrorCode &/*status*/) const {
-               return &table;
-       }
+    virtual const Hashtable* getSupportedIDs(UErrorCode &/*status*/) const {
+        return &table;
+    }
 };
 
 class Integer : public UObject {
@@ -62,22 +74,22 @@ class Integer : public UObject {
     virtual ~Integer() {
     }
 
-    virtual UBool operator==(const UObject& other) const 
-    {
-        return other.getDynamicClassID() == getStaticClassID() &&
-            _val == ((Integer&)other)._val;
-    }
-
     public:
     /**
      * UObject boilerplate.
      */
+    static UClassID getStaticClassID() { 
+        return (UClassID)&fgClassID;
+    }
+
     virtual UClassID getDynamicClassID() const {
         return getStaticClassID();
     }
 
-    static UClassID getStaticClassID() { 
-        return (UClassID)&fgClassID;
+    virtual UBool operator==(const UObject& other) const 
+    {
+        return typeid(*this) == typeid(other) &&
+            _val == ((Integer&)other)._val;
     }
 
     public:
@@ -107,8 +119,9 @@ class TestIntegerService : public ICUService {
 
     virtual ICUServiceFactory* createSimpleFactory(UObject* obj, const UnicodeString& id, UBool visible, UErrorCode& status) 
     {
-        if (U_SUCCESS(status) && obj && obj->getDynamicClassID() == Integer::getStaticClassID()) {
-            return new SimpleFactory((Integer*)obj, id, visible);
+        Integer* i;
+        if (U_SUCCESS(status) && obj && (i = dynamic_cast<Integer*>(obj)) != NULL) {
+            return new SimpleFactory(i, id, visible);
         }
         return NULL;
     }
@@ -147,13 +160,15 @@ UnicodeString append(UnicodeString& result, const UObject* obj)
     if (obj == NULL) {
         result.append("NULL");
     } else {
-        UClassID id = obj->getDynamicClassID();
-        if (id == UnicodeString::getStaticClassID()) {
-            result.append(*(UnicodeString*)obj);
-        } else if (id == Locale::getStaticClassID()) {
-            result.append(((Locale*)obj)->getName());
-        } else if (id == Integer::getStaticClassID()) {
-            sprintf(buffer, "%d", ((Integer*)obj)->_val);
+        const UnicodeString* s;
+        const Locale* loc;
+        const Integer* i;
+        if ((s = dynamic_cast<const UnicodeString*>(obj)) != NULL) {
+            result.append(*s);
+        } else if ((loc = dynamic_cast<const Locale*>(obj)) != NULL) {
+            result.append(loc->getName());
+        } else if ((i = dynamic_cast<const Integer*>(obj)) != NULL) {
+            sprintf(buffer, "%d", (int)i->_val);
             result.append(buffer);
         } else {
             sprintf(buffer, "%p", (const void*)obj);
@@ -269,7 +284,7 @@ ICUServiceTest::confirmStringsEqual(const UnicodeString& message, const UnicodeS
     if (equ) {
         logln(temp);
     } else {
-        errln(temp);
+        dataerrln(temp);
     }
 }
 
@@ -300,7 +315,7 @@ void
 ICUServiceTest::msgstr(const UnicodeString& message, UObject* obj, UBool err)
 {
     if (obj) {
-       UnicodeString* str = (UnicodeString*)obj;
+    UnicodeString* str = (UnicodeString*)obj;
         logln(message + *str);
         delete str;
     } else if (err) {
@@ -317,7 +332,7 @@ ICUServiceTest::testAPI_One()
     // register an object with one locale, 
     // search for an object with a more specific locale
     // should return the original object
-       UErrorCode status = U_ZERO_ERROR;
+    UErrorCode status = U_ZERO_ERROR;
     Integer* singleton0 = new Integer(0);
     service.registerInstance(singleton0, "en_US", status);
     {
@@ -442,11 +457,11 @@ ICUServiceTest::testAPI_One()
         confirmEqual("17) get invisible", result, singleton5);
         delete result;
     }
-       
+    
     // should not be able to locate invisible services
     {
         UErrorCode status = U_ZERO_ERROR;
-        UVector ids(uhash_deleteUnicodeString, uhash_compareUnicodeString, status);
+        UVector ids(uprv_deleteUObject, uhash_compareUnicodeString, status);
         service.getVisibleIDs(ids, status);
         UnicodeString target = "en_US_BAR";
         confirmBoolean("18) find invisible", !ids.contains(&target));
@@ -460,6 +475,25 @@ ICUServiceTest::testAPI_One()
 /*
  ******************************************************************
  */
+class TestStringSimpleKeyService : public ICUService {
+public:
+        virtual ICUServiceFactory* createSimpleFactory(UObject* obj, const UnicodeString& id, UBool visible, UErrorCode& status) 
+    {
+                // We could put this type check into ICUService itself, but we'd still
+                // have to implement cloneInstance.  Otherwise we could just tell the service
+                // what the object type is when we create it, and the default implementation
+                // could handle everything for us.  Phooey.
+        if (obj && dynamic_cast<UnicodeString*>(obj) != NULL) {
+                        return ICUService::createSimpleFactory(obj, id, visible, status);
+        }
+        return NULL;
+    }
+
+    virtual UObject* cloneInstance(UObject* instance) const {
+        return instance ? new UnicodeString(*(UnicodeString*)instance) : NULL;
+    }
+};
 
 class TestStringService : public ICUService {
     public:
@@ -467,10 +501,11 @@ class TestStringService : public ICUService {
         return LocaleKey::createWithCanonicalFallback(id, NULL, status); // no fallback locale
     }
 
-    virtual ICUServiceFactory* createSimpleFactory(UObject* obj, const UnicodeString& id, UBool visible, UErrorCode& status
+  virtual ICUServiceFactory* createSimpleFactory(UObject* obj, const UnicodeString& id, UBool visible, UErrorCode& /* status */
     {
-        if (obj && obj->getDynamicClassID() == UnicodeString::getStaticClassID()) {
-            return new SimpleFactory((UnicodeString*)obj, id, visible);
+        UnicodeString* s;
+        if (obj && (s = dynamic_cast<UnicodeString*>(obj)) != NULL) {
+            return new SimpleFactory(s, id, visible);
         }
         return NULL;
     }
@@ -484,7 +519,7 @@ class TestStringService : public ICUService {
 class AnonymousStringFactory : public ICUServiceFactory
 {
     public:
-    virtual UObject* create(const ICUServiceKey& key, const ICUService* service, UErrorCode& status) const {
+    virtual UObject* create(const ICUServiceKey& key, const ICUService* /* service */, UErrorCode& /* status */) const {
         return new UnicodeString(key.getID());
     }
 
@@ -497,14 +532,14 @@ class AnonymousStringFactory : public ICUServiceFactory
         return result;
     }
 
-    virtual UClassID getDynamicClassID() const {
-        return getStaticClassID();
-    }
-
     static UClassID getStaticClassID() {
         return (UClassID)&fgClassID;
     }
 
+    virtual UClassID getDynamicClassID() const {
+        return getStaticClassID();
+    }
+
     private:
     static const char fgClassID;
 };
@@ -519,7 +554,7 @@ class TestMultipleKeyStringFactory : public ICUServiceFactory {
     public:
     TestMultipleKeyStringFactory(const UnicodeString ids[], int32_t count, const UnicodeString& factoryID)
         : _status(U_ZERO_ERROR)
-        , _ids(uhash_deleteUnicodeString, uhash_compareUnicodeString, count, _status)
+        , _ids(uprv_deleteUObject, uhash_compareUnicodeString, count, _status)
         , _factoryID(factoryID + ": ") 
     {
         for (int i = 0; i < count; ++i) {
@@ -530,12 +565,19 @@ class TestMultipleKeyStringFactory : public ICUServiceFactory {
     ~TestMultipleKeyStringFactory() {
     }
 
-    UObject* create(const ICUServiceKey& key, const ICUService* service, UErrorCode& status) const {
+    UObject* create(const ICUServiceKey& key, const ICUService* /* service */, UErrorCode& status) const {
+        if (U_FAILURE(status)) {
+        return NULL;
+        }
         UnicodeString temp;
         key.currentID(temp);
-        if (U_SUCCESS(_status) && _ids.contains(&temp)) {
-            return new UnicodeString(_factoryID + temp);
+        if (U_SUCCESS(_status)) {
+        if (_ids.contains(&temp)) {
+                return new UnicodeString(_factoryID + temp);
         }
+        } else {
+        status = _status;
+    }
         return NULL;
     }
 
@@ -566,14 +608,14 @@ class TestMultipleKeyStringFactory : public ICUServiceFactory {
         return result;
     }
 
-    virtual UClassID getDynamicClassID() const {
-        return getStaticClassID();
-    }
-
     static UClassID getStaticClassID() {
         return (UClassID)&fgClassID;
     }
 
+    virtual UClassID getDynamicClassID() const {
+        return getStaticClassID();
+    }
+
     private:
     static const char fgClassID;
 };
@@ -583,7 +625,7 @@ const char TestMultipleKeyStringFactory::fgClassID = '\0';
 void 
 ICUServiceTest::testAPI_Two()
 {
-       UErrorCode status = U_ZERO_ERROR;
+    UErrorCode status = U_ZERO_ERROR;
     TestStringService service;
     service.registerFactory(new AnonymousStringFactory(), status);
 
@@ -632,7 +674,7 @@ ICUServiceTest::testAPI_Two()
             "en_US_SURFER_GAL",
             "en_US_SURFER_DUDE"
         };
-        int32_t count = sizeof(xids)/sizeof(UnicodeString);
+        int32_t count = UPRV_LENGTHOF(xids);
 
         ICUServiceFactory* f = new TestMultipleKeyStringFactory(xids, count, "Later");
         service.registerFactory(f, status);
@@ -641,7 +683,7 @@ ICUServiceTest::testAPI_Two()
     // iterate over the visual ids returned by the multiple factory
     {
         UErrorCode status = U_ZERO_ERROR;
-        UVector ids(uhash_deleteUnicodeString, uhash_compareUnicodeString, 0, status);
+        UVector ids(uprv_deleteUObject, uhash_compareUnicodeString, 0, status);
         service.getVisibleIDs(ids, status);
         for (int i = 0; i < ids.size(); ++i) {
             const UnicodeString* id = (const UnicodeString*)ids[i];
@@ -660,8 +702,8 @@ ICUServiceTest::testAPI_Two()
     // iterate over the display names
     {
         UErrorCode status = U_ZERO_ERROR;
-        UVector names(deleteStringPair, NULL, status);
-        service.getDisplayNames(names, Locale::getGerman(), status);
+        UVector names(status);
+        service.getDisplayNames(names, status);
         for (int i = 0; i < names.size(); ++i) {
             const StringPair* pair = (const StringPair*)names[i];
             logln("  " + pair->displayName + " --> " + pair->id);
@@ -690,7 +732,7 @@ ICUServiceTest::testAPI_Two()
             "en_US_SILICON", 
             "en_US_SILICON_GEEK",
         };
-        int32_t count = sizeof(xids)/sizeof(UnicodeString);
+        int32_t count = UPRV_LENGTHOF(xids);
 
         ICUServiceFactory* f = new TestMultipleKeyStringFactory(xids, count, "Rad dude");
         service.registerFactory(f, status);
@@ -700,13 +742,13 @@ ICUServiceTest::testAPI_Two()
     // Rad dude's surfer gal 'replaces' Later's surfer gal
     {
         UErrorCode status = U_ZERO_ERROR;
-        UVector names(deleteStringPair, NULL, status);
+        UVector names(status);
         service.getDisplayNames(names, Locale("es"), status);
         for (int i = 0; i < names.size(); ++i) {
             const StringPair* pair = (const StringPair*)names[i];
             logln("  " + pair->displayName + " --> " + pair->id);
         }
-        confirmIdentical("26) display names", names.size(), 7);
+        confirmIdentical("29) display names", names.size(), 7);
     }
 
     // we should get the display name corresponding to the actual id
@@ -762,7 +804,7 @@ ICUServiceTest::testAPI_Two()
 
     {
         UErrorCode status = U_ZERO_ERROR;
-        UVector ids(uhash_deleteUnicodeString, uhash_compareUnicodeString, 0, status);
+        UVector ids(uprv_deleteUObject, uhash_compareUnicodeString, 0, status);
         service.getVisibleIDs(ids, status);
         for (int i = 0; i < ids.size(); ++i) {
             const UnicodeString* id = (const UnicodeString*)ids[i];
@@ -851,14 +893,14 @@ void
 ICUServiceTest::testRBF()
 {
     // resource bundle factory.
-       UErrorCode status = U_ZERO_ERROR;
+    UErrorCode status = U_ZERO_ERROR;
     TestStringService service;
     service.registerFactory(new ICUResourceBundleFactory(), status);
 
     // list all of the resources 
     {
         UErrorCode status = U_ZERO_ERROR;
-        UVector ids(uhash_deleteUnicodeString, uhash_compareUnicodeString, 0, status);
+        UVector ids(uprv_deleteUObject, uhash_compareUnicodeString, 0, status);
         service.getVisibleIDs(ids, status);
         logln("all visible ids:");
         for (int i = 0; i < ids.size(); ++i) {
@@ -871,7 +913,7 @@ ICUServiceTest::testRBF()
     // this should be fast since the display names were cached.
     {
         UErrorCode status = U_ZERO_ERROR;
-        UVector names(deleteStringPair, NULL, status);
+        UVector names(status);
         service.getDisplayNames(names, Locale::getGermany(), status);
         logln("service display names for de_DE");
         for (int i = 0; i < names.size(); ++i) {
@@ -891,13 +933,13 @@ ICUServiceTest::testRBF()
             CalifornioLanguageFactory::surfer, 
             CalifornioLanguageFactory::geek,
         };
-        int32_t count = sizeof(idNames)/sizeof(idNames[0]);
+        int32_t count = UPRV_LENGTHOF(idNames);
 
         for (int i = 0; i < count; ++i) {
             logln(UnicodeString("\n  --- ") + idNames[i] + " ---");
             {
                 UErrorCode status = U_ZERO_ERROR;
-                UVector names(deleteStringPair, NULL, status);
+                UVector names(status);
                 service.getDisplayNames(names, idNames[i], status);
                 for (int i = 0; i < names.size(); ++i) {
                     const StringPair* pair = (const StringPair*)names[i];
@@ -911,11 +953,10 @@ ICUServiceTest::testRBF()
 
 class SimpleListener : public ServiceListener {
     ICUServiceTest* _test;
-    int32_t _n;
     UnicodeString _name;
 
     public:
-    SimpleListener(ICUServiceTest* test, const UnicodeString& name) : _test(test), _n(0), _name(name) {}
+    SimpleListener(ICUServiceTest* test, const UnicodeString& name) : _test(test), _name(name) {}
 
     virtual void serviceChanged(const ICUService& service) const {
         UnicodeString serviceName = "listener ";
@@ -995,7 +1036,7 @@ class TestStringLocaleService : public ICULocaleService {
 };
 
 void ICUServiceTest::testLocale() {
-       UErrorCode status = U_ZERO_ERROR;
+    UErrorCode status = U_ZERO_ERROR;
     TestStringLocaleService service;
 
     UnicodeString* root = new UnicodeString("root");
@@ -1007,7 +1048,7 @@ void ICUServiceTest::testLocale() {
     service.registerInstance(root, "", status);
     service.registerInstance(german, "de", status);
     service.registerInstance(germany, Locale::getGermany(), status);
-    service.registerInstance(japanese, "ja", status);
+    service.registerInstance(japanese, (UnicodeString)"ja", TRUE, status);
     service.registerInstance(japan, Locale::getJapan(), status);
 
     {
@@ -1085,7 +1126,7 @@ void ICUServiceTest::testLocale() {
     }
 
     {
-               UErrorCode status = U_ZERO_ERROR;
+        UErrorCode status = U_ZERO_ERROR;
         UnicodeString english = "en";
         Locale localeResult;
         UnicodeString result;
@@ -1125,7 +1166,7 @@ void ICUServiceTest::testLocale() {
 
     {
         UErrorCode status = U_ZERO_ERROR;
-        UVector ids(uhash_deleteUnicodeString, uhash_compareUnicodeString, 0, status);
+        UVector ids(uprv_deleteUObject, uhash_compareUnicodeString, 0, status);
         service.getVisibleIDs(ids, status);
         logln("all visible ids:");
         for (int i = 0; i < ids.size(); ++i) {
@@ -1137,7 +1178,7 @@ void ICUServiceTest::testLocale() {
     Locale::setDefault(loc, status);
     {
         UErrorCode status = U_ZERO_ERROR;
-        UVector ids(uhash_deleteUnicodeString, uhash_compareUnicodeString, 0, status);
+        UVector ids(uprv_deleteUObject, uhash_compareUnicodeString, 0, status);
         service.getVisibleIDs(ids, status);
         logln("all visible ids:");
         for (int i = 0; i < ids.size(); ++i) {
@@ -1157,7 +1198,7 @@ void ICUServiceTest::testLocale() {
         UErrorCode status = U_ZERO_ERROR;
         StringEnumeration* locales = service.getAvailableLocales();
         if (locales) {
-            confirmIdentical("test available locales", locales->count(status), 5);
+            confirmIdentical("test available locales", locales->count(status), 6);
             logln("locales: ");
             {
                 const char* p;
@@ -1177,7 +1218,7 @@ class WrapFactory : public ICUServiceFactory {
     public:
     static const UnicodeString& getGreetingID() {
       if (greetingID == NULL) {
-       greetingID = new UnicodeString("greeting");
+    greetingID = new UnicodeString("greeting");
       }
       return *greetingID;
     }
@@ -1208,7 +1249,7 @@ class WrapFactory : public ICUServiceFactory {
         }
     }
 
-    UnicodeString& getDisplayName(const UnicodeString& id, const Locale& locale, UnicodeString& result) const {
+    UnicodeString& getDisplayName(const UnicodeString& id, const Locale& /* locale */, UnicodeString& result) const {
         result.append("wrap '");
         result.append(id);
         result.append("'");
@@ -1218,14 +1259,14 @@ class WrapFactory : public ICUServiceFactory {
     /**
      * UObject boilerplate.
      */
-    virtual UClassID getDynamicClassID() const {
-        return getStaticClassID();
-    }
-
     static UClassID getStaticClassID() { 
         return (UClassID)&fgClassID;
     }
 
+    virtual UClassID getDynamicClassID() const {
+        return getStaticClassID();
+    }
+
     private:
     static const char fgClassID;
     static UnicodeString* greetingID;
@@ -1239,7 +1280,7 @@ ICUServiceTest::testWrapFactory()
 {
     UnicodeString* greeting = new UnicodeString("Hello There");
     UnicodeString greetingID = "greeting";
-       UErrorCode status = U_ZERO_ERROR;
+    UErrorCode status = U_ZERO_ERROR;
     TestStringService service;
     service.registerInstance(greeting, greetingID, status);
 
@@ -1296,18 +1337,45 @@ void ICUServiceTest::testCoverage()
     }
 
     // ICUService
-    TestStringService service;
-    service.registerFactory(sf, status);
-
-    {
-      UnicodeString* result = (UnicodeString*)service.get("object", status);
-      if (result) {
-       logln("object is: " + *result);
-       delete result;
-      } else {
-       errln("could not get object");
-      }
-    }
+        {
+                TestStringService service;
+                service.registerFactory(sf,     status);
+
+                {
+                        UnicodeString* result   = (UnicodeString*)service.get("object", status);
+                        if (result) {
+                                logln("object is: "     + *result);
+                                delete result;
+                        }       else {
+                                errln("could not get object");
+                        }
+                }
+        }
+  }
+  
+  // ICUServiceKey
+  {
+      UErrorCode status = U_ZERO_ERROR;
+          UnicodeString* howdy = new UnicodeString("Howdy");
+
+          TestStringSimpleKeyService service;
+          service.registerInstance(howdy, "Greetings", status);
+          {
+                  UnicodeString* result = (UnicodeString*)service.get("Greetings",      status);
+                  if (result) {
+                          logln("object is: "   + *result);
+                          delete result;
+                  }     else {
+                          errln("could not get object");
+                  }
+          }
+
+      UVector ids(uprv_deleteUObject, uhash_compareUnicodeString, status);
+          // yuck, this is awkward to use.  All because we pass null in an overload.
+          // TODO: change this.
+          UnicodeString str("Greet");
+      service.getVisibleIDs(ids, &str, status);
+      confirmIdentical("no fallback of greet", ids.size(), 0);
   }
 
   // ICULocaleService
@@ -1367,15 +1435,40 @@ void ICUServiceTest::testCoverage()
     }
     delete obj;
     delete key;
-  }
 
+        key = LocaleKey::createWithCanonicalFallback(&primary, &fallback, 123, status);
+        if (U_SUCCESS(status)) {
+                UnicodeString str;
+                key->currentDescriptor(str);
+                key->parsePrefix(str);
+                if (str != "123") {
+                        errln("did not get expected prefix");
+                }
+                delete key;
+        }
 
-#if 0
-  // ResourceBundleFactory
-  ICUResourceBundleFactory rbf = new ICUResourceBundleFactory();
-  logln("RB: " + rbf.create(lkey, null));
+        // coverage, getSupportedIDs is either overridden or the calling method is
+        LKFSubclass0 lkFactory;
+        Hashtable table0;
+        lkFactory.updateVisibleIDs(table0, status);
+        if (table0.count() != 0) {
+                errln("LKF returned non-empty hashtable");
+        }
+
+
+        // ResourceBundleFactory
+    key = LocaleKey::createWithCanonicalFallback(&primary, &fallback, status);
+        ICUResourceBundleFactory rbf;
+        UObject* icurb = rbf.create(*key, NULL, status);
+        if (icurb != NULL) {
+                logln("got resource bundle for key");
+                delete icurb;
+        }
+        delete key;
+  }
 
-  // ICUNotifier
+ #if 0
+ // ICUNotifier
   ICUNotifier nf = new ICUNSubclass();
   try {
     nf.addListener(null);