You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1518 lines
46 KiB
1518 lines
46 KiB
// © 2016 and later: Unicode, Inc. and others.
|
|
// License & terms of use: http://www.unicode.org/copyright.html
|
|
/**
|
|
*******************************************************************************
|
|
* 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 "servloc.h"
|
|
#include <stdio.h>
|
|
|
|
|
|
class MyListener : public EventListener {
|
|
};
|
|
|
|
class WrongListener : public EventListener {
|
|
};
|
|
|
|
class ICUNSubclass : public ICUNotifier {
|
|
public:
|
|
UBool acceptsListener(const EventListener& /*l*/) const {
|
|
return TRUE;
|
|
// return l instanceof MyListener;
|
|
}
|
|
|
|
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;
|
|
|
|
public:
|
|
LKFSubclass(UBool visible)
|
|
: LocaleKeyFactory(visible ? VISIBLE : INVISIBLE, "LKFSubclass")
|
|
{
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
table.put("en_US", this, status);
|
|
}
|
|
|
|
protected:
|
|
virtual const Hashtable* getSupportedIDs(UErrorCode &/*status*/) const {
|
|
return &table;
|
|
}
|
|
};
|
|
|
|
class Integer : public UObject {
|
|
public:
|
|
const int32_t _val;
|
|
|
|
Integer(int32_t val) : _val(val) {
|
|
}
|
|
|
|
Integer(const Integer& rhs) : UObject(rhs), _val(rhs._val) {
|
|
}
|
|
virtual ~Integer() {
|
|
}
|
|
|
|
public:
|
|
/**
|
|
* UObject boilerplate.
|
|
*/
|
|
static UClassID getStaticClassID() {
|
|
return (UClassID)&fgClassID;
|
|
}
|
|
|
|
virtual UClassID getDynamicClassID() const {
|
|
return getStaticClassID();
|
|
}
|
|
|
|
virtual UBool operator==(const UObject& other) const
|
|
{
|
|
return typeid(*this) == typeid(other) &&
|
|
_val == ((Integer&)other)._val;
|
|
}
|
|
|
|
public:
|
|
virtual UnicodeString& debug(UnicodeString& result) const {
|
|
debugClass(result);
|
|
result.append(" val: ");
|
|
result.append(_val);
|
|
return result;
|
|
}
|
|
|
|
virtual UnicodeString& debugClass(UnicodeString& result) const {
|
|
return result.append("Integer");
|
|
}
|
|
|
|
private:
|
|
static const char fgClassID;
|
|
};
|
|
|
|
const char Integer::fgClassID = '\0';
|
|
|
|
// use locale keys
|
|
class TestIntegerService : public ICUService {
|
|
public:
|
|
ICUServiceKey* createKey(const UnicodeString* id, UErrorCode& status) const {
|
|
return LocaleKey::createWithCanonicalFallback(id, NULL, status); // no fallback locale
|
|
}
|
|
|
|
virtual ICUServiceFactory* createSimpleFactory(UObject* obj, const UnicodeString& id, UBool visible, UErrorCode& status)
|
|
{
|
|
Integer* i;
|
|
if (U_SUCCESS(status) && obj && (i = dynamic_cast<Integer*>(obj)) != NULL) {
|
|
return new SimpleFactory(i, id, visible);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
virtual UObject* cloneInstance(UObject* instance) const {
|
|
return instance ? new Integer(*(Integer*)instance) : NULL;
|
|
}
|
|
};
|
|
|
|
|
|
ICUServiceTest::ICUServiceTest() {
|
|
}
|
|
|
|
ICUServiceTest::~ICUServiceTest() {
|
|
}
|
|
|
|
void
|
|
ICUServiceTest::runIndexedTest(int32_t index, UBool exec, const char* &name,
|
|
char* /*par*/)
|
|
{
|
|
switch (index) {
|
|
TESTCASE(0,testAPI_One);
|
|
TESTCASE(1,testAPI_Two);
|
|
TESTCASE(2,testRBF);
|
|
TESTCASE(3,testNotification);
|
|
TESTCASE(4,testLocale);
|
|
TESTCASE(5,testWrapFactory);
|
|
TESTCASE(6,testCoverage);
|
|
default: name = ""; break;
|
|
}
|
|
}
|
|
|
|
UnicodeString append(UnicodeString& result, const UObject* obj)
|
|
{
|
|
char buffer[128];
|
|
if (obj == NULL) {
|
|
result.append("NULL");
|
|
} else {
|
|
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);
|
|
result.append(buffer);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
UnicodeString&
|
|
ICUServiceTest::lrmsg(UnicodeString& result, const UnicodeString& message, const UObject* lhs, const UObject* rhs) const
|
|
{
|
|
result.append(message);
|
|
result.append(" lhs: ");
|
|
append(result, lhs);
|
|
result.append(", rhs: ");
|
|
append(result, rhs);
|
|
return result;
|
|
}
|
|
|
|
void
|
|
ICUServiceTest::confirmBoolean(const UnicodeString& message, UBool val)
|
|
{
|
|
if (val) {
|
|
logln(message);
|
|
} else {
|
|
errln(message);
|
|
}
|
|
}
|
|
|
|
#if 0
|
|
void
|
|
ICUServiceTest::confirmEqual(const UnicodeString& message, const UObject* lhs, const UObject* rhs)
|
|
{
|
|
UBool equ = (lhs == NULL)
|
|
? (rhs == NULL)
|
|
: (rhs != NULL && lhs->operator==(*rhs));
|
|
|
|
UnicodeString temp;
|
|
lrmsg(temp, message, lhs, rhs);
|
|
|
|
if (equ) {
|
|
logln(temp);
|
|
} else {
|
|
errln(temp);
|
|
}
|
|
}
|
|
#else
|
|
void
|
|
ICUServiceTest::confirmEqual(const UnicodeString& message, const Integer* lhs, const Integer* rhs)
|
|
{
|
|
UBool equ = (lhs == NULL)
|
|
? (rhs == NULL)
|
|
: (rhs != NULL && lhs->operator==(*rhs));
|
|
|
|
UnicodeString temp;
|
|
lrmsg(temp, message, lhs, rhs);
|
|
|
|
if (equ) {
|
|
logln(temp);
|
|
} else {
|
|
errln(temp);
|
|
}
|
|
}
|
|
|
|
void
|
|
ICUServiceTest::confirmEqual(const UnicodeString& message, const UnicodeString* lhs, const UnicodeString* rhs)
|
|
{
|
|
UBool equ = (lhs == NULL)
|
|
? (rhs == NULL)
|
|
: (rhs != NULL && lhs->operator==(*rhs));
|
|
|
|
UnicodeString temp;
|
|
lrmsg(temp, message, lhs, rhs);
|
|
|
|
if (equ) {
|
|
logln(temp);
|
|
} else {
|
|
errln(temp);
|
|
}
|
|
}
|
|
|
|
void
|
|
ICUServiceTest::confirmEqual(const UnicodeString& message, const Locale* lhs, const Locale* rhs)
|
|
{
|
|
UBool equ = (lhs == NULL)
|
|
? (rhs == NULL)
|
|
: (rhs != NULL && lhs->operator==(*rhs));
|
|
|
|
UnicodeString temp;
|
|
lrmsg(temp, message, lhs, rhs);
|
|
|
|
if (equ) {
|
|
logln(temp);
|
|
} else {
|
|
errln(temp);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
// use these for now
|
|
void
|
|
ICUServiceTest::confirmStringsEqual(const UnicodeString& message, const UnicodeString& lhs, const UnicodeString& rhs)
|
|
{
|
|
UBool equ = lhs == rhs;
|
|
|
|
UnicodeString temp = message;
|
|
temp.append(" lhs: ");
|
|
temp.append(lhs);
|
|
temp.append(" rhs: ");
|
|
temp.append(rhs);
|
|
|
|
if (equ) {
|
|
logln(temp);
|
|
} else {
|
|
dataerrln(temp);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
ICUServiceTest::confirmIdentical(const UnicodeString& message, const UObject* lhs, const UObject *rhs)
|
|
{
|
|
UnicodeString temp;
|
|
lrmsg(temp, message, lhs, rhs);
|
|
if (lhs == rhs) {
|
|
logln(temp);
|
|
} else {
|
|
errln(temp);
|
|
}
|
|
}
|
|
|
|
void
|
|
ICUServiceTest::confirmIdentical(const UnicodeString& message, int32_t lhs, int32_t rhs)
|
|
{
|
|
if (lhs == rhs) {
|
|
logln(message + " lhs: " + lhs + " rhs: " + rhs);
|
|
} else {
|
|
errln(message + " lhs: " + lhs + " rhs: " + rhs);
|
|
}
|
|
}
|
|
|
|
void
|
|
ICUServiceTest::msgstr(const UnicodeString& message, UObject* obj, UBool err)
|
|
{
|
|
if (obj) {
|
|
UnicodeString* str = (UnicodeString*)obj;
|
|
logln(message + *str);
|
|
delete str;
|
|
} else if (err) {
|
|
errln("Error " + message + "string is NULL");
|
|
}
|
|
}
|
|
|
|
void
|
|
ICUServiceTest::testAPI_One()
|
|
{
|
|
// create a service using locale keys,
|
|
TestIntegerService service;
|
|
|
|
// 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;
|
|
Integer* singleton0 = new Integer(0);
|
|
service.registerInstance(singleton0, "en_US", status);
|
|
{
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
Integer* result = (Integer*)service.get("en_US_FOO", status);
|
|
confirmEqual("1) en_US_FOO -> en_US", result, singleton0);
|
|
delete result;
|
|
}
|
|
|
|
// register a new object with the more specific locale
|
|
// search for an object with that locale
|
|
// should return the new object
|
|
Integer* singleton1 = new Integer(1);
|
|
service.registerInstance(singleton1, "en_US_FOO", status);
|
|
{
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
Integer* result = (Integer*)service.get("en_US_FOO", status);
|
|
confirmEqual("2) en_US_FOO -> en_US_FOO", result, singleton1);
|
|
delete result;
|
|
}
|
|
|
|
// search for an object that falls back to the first registered locale
|
|
{
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
Integer* result = (Integer*)service.get("en_US_BAR", status);
|
|
confirmEqual("3) en_US_BAR -> en_US", result, singleton0);
|
|
delete result;
|
|
}
|
|
|
|
// get a list of the factories, should be two
|
|
{
|
|
confirmIdentical("4) factory size", service.countFactories(), 2);
|
|
}
|
|
|
|
// register a new object with yet another locale
|
|
Integer* singleton2 = new Integer(2);
|
|
service.registerInstance(singleton2, "en", status);
|
|
{
|
|
confirmIdentical("5) factory size", service.countFactories(), 3);
|
|
}
|
|
|
|
// search for an object with the new locale
|
|
// stack of factories is now en, en_US_FOO, en_US
|
|
// search for en_US should still find en_US object
|
|
{
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
Integer* result = (Integer*)service.get("en_US_BAR", status);
|
|
confirmEqual("6) en_US_BAR -> en_US", result, singleton0);
|
|
delete result;
|
|
}
|
|
|
|
// register a new object with an old id, should hide earlier factory using this id, but leave it there
|
|
Integer* singleton3 = new Integer(3);
|
|
URegistryKey s3key = service.registerInstance(singleton3, "en_US", status);
|
|
{
|
|
confirmIdentical("9) factory size", service.countFactories(), 4);
|
|
}
|
|
|
|
// should get data from that new factory
|
|
{
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
Integer* result = (Integer*)service.get("en_US_BAR", status);
|
|
confirmEqual("10) en_US_BAR -> (3)", result, singleton3);
|
|
delete result;
|
|
}
|
|
|
|
// remove new factory
|
|
// should have fewer factories again
|
|
// singleton3 dead!
|
|
{
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
service.unregister(s3key, status);
|
|
confirmIdentical("11) factory size", service.countFactories(), 3);
|
|
}
|
|
|
|
// should get original data again after remove factory
|
|
{
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
Integer* result = (Integer*)service.get("en_US_BAR", status);
|
|
confirmEqual("12) en_US_BAR -> (3)", result, singleton0);
|
|
delete result;
|
|
}
|
|
|
|
// shouldn't find unregistered ids
|
|
{
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
Integer* result = (Integer*)service.get("foo", status);
|
|
confirmIdentical("13) foo -> null", result, NULL);
|
|
delete result;
|
|
}
|
|
|
|
// should find non-canonical strings
|
|
{
|
|
UnicodeString resultID;
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
Integer* result = (Integer*)service.get("EN_us_fOo", &resultID, status);
|
|
confirmEqual("14a) find-non-canonical", result, singleton1);
|
|
confirmStringsEqual("14b) find non-canonical", resultID, "en_US_FOO");
|
|
delete result;
|
|
}
|
|
|
|
// should be able to register non-canonical strings and get them canonicalized
|
|
Integer* singleton4 = new Integer(4);
|
|
service.registerInstance(singleton4, "eN_ca_dUde", status);
|
|
{
|
|
UnicodeString resultID;
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
Integer* result = (Integer*)service.get("En_Ca_DuDe", &resultID, status);
|
|
confirmEqual("15a) find-non-canonical", result, singleton4);
|
|
confirmStringsEqual("15b) register non-canonical", resultID, "en_CA_DUDE");
|
|
delete result;
|
|
}
|
|
|
|
// should be able to register invisible factories, these will not
|
|
// be visible by default, but if you know the secret password you
|
|
// can still access these services...
|
|
Integer* singleton5 = new Integer(5);
|
|
service.registerInstance(singleton5, "en_US_BAR", FALSE, status);
|
|
{
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
Integer* result = (Integer*)service.get("en_US_BAR", status);
|
|
confirmEqual("17) get invisible", result, singleton5);
|
|
delete result;
|
|
}
|
|
|
|
// should not be able to locate invisible services
|
|
{
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
UVector ids(uprv_deleteUObject, uhash_compareUnicodeString, status);
|
|
service.getVisibleIDs(ids, status);
|
|
UnicodeString target = "en_US_BAR";
|
|
confirmBoolean("18) find invisible", !ids.contains(&target));
|
|
}
|
|
|
|
// clear factory and caches
|
|
service.reset();
|
|
confirmBoolean("19) is default", service.isDefault());
|
|
}
|
|
|
|
/*
|
|
******************************************************************
|
|
*/
|
|
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:
|
|
ICUServiceKey* createKey(const UnicodeString* id, UErrorCode& status) const {
|
|
return LocaleKey::createWithCanonicalFallback(id, NULL, status); // no fallback locale
|
|
}
|
|
|
|
virtual ICUServiceFactory* createSimpleFactory(UObject* obj, const UnicodeString& id, UBool visible, UErrorCode& /* status */)
|
|
{
|
|
UnicodeString* s;
|
|
if (obj && (s = dynamic_cast<UnicodeString*>(obj)) != NULL) {
|
|
return new SimpleFactory(s, id, visible);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
virtual UObject* cloneInstance(UObject* instance) const {
|
|
return instance ? new UnicodeString(*(UnicodeString*)instance) : NULL;
|
|
}
|
|
};
|
|
|
|
// this creates a string for any id, but doesn't report anything
|
|
class AnonymousStringFactory : public ICUServiceFactory
|
|
{
|
|
public:
|
|
virtual UObject* create(const ICUServiceKey& key, const ICUService* /* service */, UErrorCode& /* status */) const {
|
|
return new UnicodeString(key.getID());
|
|
}
|
|
|
|
virtual void updateVisibleIDs(Hashtable& /*result*/, UErrorCode& /*status*/) const {
|
|
// do nothing
|
|
}
|
|
|
|
virtual UnicodeString& getDisplayName(const UnicodeString& /*id*/, const Locale& /*locale*/, UnicodeString& result) const {
|
|
// do nothing
|
|
return result;
|
|
}
|
|
|
|
static UClassID getStaticClassID() {
|
|
return (UClassID)&fgClassID;
|
|
}
|
|
|
|
virtual UClassID getDynamicClassID() const {
|
|
return getStaticClassID();
|
|
}
|
|
|
|
private:
|
|
static const char fgClassID;
|
|
};
|
|
|
|
const char AnonymousStringFactory::fgClassID = '\0';
|
|
|
|
class TestMultipleKeyStringFactory : public ICUServiceFactory {
|
|
UErrorCode _status;
|
|
UVector _ids;
|
|
UnicodeString _factoryID;
|
|
|
|
public:
|
|
TestMultipleKeyStringFactory(const UnicodeString ids[], int32_t count, const UnicodeString& factoryID)
|
|
: _status(U_ZERO_ERROR)
|
|
, _ids(uprv_deleteUObject, uhash_compareUnicodeString, count, _status)
|
|
, _factoryID(factoryID + ": ")
|
|
{
|
|
for (int i = 0; i < count; ++i) {
|
|
_ids.addElement(new UnicodeString(ids[i]), _status);
|
|
}
|
|
}
|
|
|
|
~TestMultipleKeyStringFactory() {
|
|
}
|
|
|
|
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)) {
|
|
if (_ids.contains(&temp)) {
|
|
return new UnicodeString(_factoryID + temp);
|
|
}
|
|
} else {
|
|
status = _status;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void updateVisibleIDs(Hashtable& result, UErrorCode& status) const {
|
|
if (U_SUCCESS(_status)) {
|
|
for (int32_t i = 0; i < _ids.size(); ++i) {
|
|
result.put(*(UnicodeString*)_ids[i], (void*)this, status);
|
|
}
|
|
}
|
|
}
|
|
|
|
UnicodeString& getDisplayName(const UnicodeString& id, const Locale& locale, UnicodeString& result) const {
|
|
if (U_SUCCESS(_status) && _ids.contains((void*)&id)) {
|
|
char buffer[128];
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
int32_t len = id.extract(buffer, sizeof(buffer), NULL, status);
|
|
if (U_SUCCESS(status)) {
|
|
if (len == sizeof(buffer)) {
|
|
--len;
|
|
}
|
|
buffer[len] = 0;
|
|
Locale loc = Locale::createFromName(buffer);
|
|
loc.getDisplayName(locale, result);
|
|
return result;
|
|
}
|
|
}
|
|
result.setToBogus(); // shouldn't happen
|
|
return result;
|
|
}
|
|
|
|
static UClassID getStaticClassID() {
|
|
return (UClassID)&fgClassID;
|
|
}
|
|
|
|
virtual UClassID getDynamicClassID() const {
|
|
return getStaticClassID();
|
|
}
|
|
|
|
private:
|
|
static const char fgClassID;
|
|
};
|
|
|
|
const char TestMultipleKeyStringFactory::fgClassID = '\0';
|
|
|
|
void
|
|
ICUServiceTest::testAPI_Two()
|
|
{
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
TestStringService service;
|
|
service.registerFactory(new AnonymousStringFactory(), status);
|
|
|
|
// anonymous factory will still handle the id
|
|
{
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
const UnicodeString en_US = "en_US";
|
|
UnicodeString* result = (UnicodeString*)service.get(en_US, status);
|
|
confirmEqual("21) locale", result, &en_US);
|
|
delete result;
|
|
}
|
|
|
|
// still normalizes id
|
|
{
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
const UnicodeString en_US_BAR = "en_US_BAR";
|
|
UnicodeString resultID;
|
|
UnicodeString* result = (UnicodeString*)service.get("EN_us_bar", &resultID, status);
|
|
confirmEqual("22) locale", &resultID, &en_US_BAR);
|
|
delete result;
|
|
}
|
|
|
|
// we can override for particular ids
|
|
UnicodeString* singleton0 = new UnicodeString("Zero");
|
|
service.registerInstance(singleton0, "en_US_BAR", status);
|
|
{
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
UnicodeString* result = (UnicodeString*)service.get("en_US_BAR", status);
|
|
confirmEqual("23) override super", result, singleton0);
|
|
delete result;
|
|
}
|
|
|
|
// empty service should not recognize anything
|
|
service.reset();
|
|
{
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
UnicodeString* result = (UnicodeString*)service.get("en_US", status);
|
|
confirmIdentical("24) empty", result, NULL);
|
|
}
|
|
|
|
// create a custom multiple key factory
|
|
{
|
|
UnicodeString xids[] = {
|
|
"en_US_VALLEY_GIRL",
|
|
"en_US_VALLEY_BOY",
|
|
"en_US_SURFER_GAL",
|
|
"en_US_SURFER_DUDE"
|
|
};
|
|
int32_t count = UPRV_LENGTHOF(xids);
|
|
|
|
ICUServiceFactory* f = new TestMultipleKeyStringFactory(xids, count, "Later");
|
|
service.registerFactory(f, status);
|
|
}
|
|
|
|
// iterate over the visual ids returned by the multiple factory
|
|
{
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
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];
|
|
UnicodeString* result = (UnicodeString*)service.get(*id, status);
|
|
if (result) {
|
|
logln(" " + *id + " --> " + *result);
|
|
delete result;
|
|
} else {
|
|
errln("could not find " + *id);
|
|
}
|
|
}
|
|
// four visible ids
|
|
confirmIdentical("25) visible ids", ids.size(), 4);
|
|
}
|
|
|
|
// iterate over the display names
|
|
{
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
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);
|
|
}
|
|
confirmIdentical("26) display names", names.size(), 4);
|
|
}
|
|
|
|
// no valid display name
|
|
{
|
|
UnicodeString name;
|
|
service.getDisplayName("en_US_VALLEY_GEEK", name);
|
|
confirmBoolean("27) get display name", name.isBogus());
|
|
}
|
|
|
|
{
|
|
UnicodeString name;
|
|
service.getDisplayName("en_US_SURFER_DUDE", name, Locale::getEnglish());
|
|
confirmStringsEqual("28) get display name", name, "English (United States, SURFER_DUDE)");
|
|
}
|
|
|
|
// register another multiple factory
|
|
{
|
|
UnicodeString xids[] = {
|
|
"en_US_SURFER",
|
|
"en_US_SURFER_GAL",
|
|
"en_US_SILICON",
|
|
"en_US_SILICON_GEEK",
|
|
};
|
|
int32_t count = UPRV_LENGTHOF(xids);
|
|
|
|
ICUServiceFactory* f = new TestMultipleKeyStringFactory(xids, count, "Rad dude");
|
|
service.registerFactory(f, status);
|
|
}
|
|
|
|
// this time, we have seven display names
|
|
// Rad dude's surfer gal 'replaces' Later's surfer gal
|
|
{
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
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("29) display names", names.size(), 7);
|
|
}
|
|
|
|
// we should get the display name corresponding to the actual id
|
|
// returned by the id we used.
|
|
{
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
UnicodeString actualID;
|
|
UnicodeString id = "en_us_surfer_gal";
|
|
UnicodeString* gal = (UnicodeString*)service.get(id, &actualID, status);
|
|
if (gal != NULL) {
|
|
UnicodeString displayName;
|
|
logln("actual id: " + actualID);
|
|
service.getDisplayName(actualID, displayName, Locale::getEnglish());
|
|
logln("found actual: " + *gal + " with display name: " + displayName);
|
|
confirmBoolean("30) found display name for actual", !displayName.isBogus());
|
|
|
|
service.getDisplayName(id, displayName, Locale::getEnglish());
|
|
logln("found actual: " + *gal + " with display name: " + displayName);
|
|
confirmBoolean("31) found display name for query", displayName.isBogus());
|
|
|
|
delete gal;
|
|
} else {
|
|
errln("30) service could not find entry for " + id);
|
|
}
|
|
}
|
|
|
|
// this should be handled by the 'dude' factory, since it overrides en_US_SURFER.
|
|
{
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
UnicodeString actualID;
|
|
UnicodeString id = "en_US_SURFER_BOZO";
|
|
UnicodeString* bozo = (UnicodeString*)service.get(id, &actualID, status);
|
|
if (bozo != NULL) {
|
|
UnicodeString displayName;
|
|
service.getDisplayName(actualID, displayName, Locale::getEnglish());
|
|
logln("found actual: " + *bozo + " with display name: " + displayName);
|
|
confirmBoolean("32) found display name for actual", !displayName.isBogus());
|
|
|
|
service.getDisplayName(id, displayName, Locale::getEnglish());
|
|
logln("found actual: " + *bozo + " with display name: " + displayName);
|
|
confirmBoolean("33) found display name for query", displayName.isBogus());
|
|
|
|
delete bozo;
|
|
} else {
|
|
errln("32) service could not find entry for " + id);
|
|
}
|
|
}
|
|
|
|
// certainly not default...
|
|
{
|
|
confirmBoolean("34) is default ", !service.isDefault());
|
|
}
|
|
|
|
{
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
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];
|
|
msgstr(*id + "? ", service.get(*id, status));
|
|
}
|
|
|
|
logstr("valleygirl? ", service.get("en_US_VALLEY_GIRL", status));
|
|
logstr("valleyboy? ", service.get("en_US_VALLEY_BOY", status));
|
|
logstr("valleydude? ", service.get("en_US_VALLEY_DUDE", status));
|
|
logstr("surfergirl? ", service.get("en_US_SURFER_GIRL", status));
|
|
}
|
|
}
|
|
|
|
|
|
class CalifornioLanguageFactory : public ICUResourceBundleFactory
|
|
{
|
|
public:
|
|
static const char* californio; // = "en_US_CA";
|
|
static const char* valley; // = californio ## "_VALLEY";
|
|
static const char* surfer; // = californio ## "_SURFER";
|
|
static const char* geek; // = californio ## "_GEEK";
|
|
static Hashtable* supportedIDs; // = NULL;
|
|
|
|
static void cleanup(void) {
|
|
delete supportedIDs;
|
|
supportedIDs = NULL;
|
|
}
|
|
|
|
const Hashtable* getSupportedIDs(UErrorCode& status) const
|
|
{
|
|
if (supportedIDs == NULL) {
|
|
Hashtable* table = new Hashtable();
|
|
table->put(UnicodeString(californio), (void*)table, status);
|
|
table->put(UnicodeString(valley), (void*)table, status);
|
|
table->put(UnicodeString(surfer), (void*)table, status);
|
|
table->put(UnicodeString(geek), (void*)table, status);
|
|
|
|
// not necessarily atomic, but this is a test...
|
|
supportedIDs = table;
|
|
}
|
|
return supportedIDs;
|
|
}
|
|
|
|
UnicodeString& getDisplayName(const UnicodeString& id, const Locale& locale, UnicodeString& result) const
|
|
{
|
|
UnicodeString prefix = "";
|
|
UnicodeString suffix = "";
|
|
UnicodeString ls = locale.getName();
|
|
if (LocaleUtility::isFallbackOf(californio, ls)) {
|
|
if (!ls.caseCompare(valley, 0)) {
|
|
prefix = "Like, you know, it's so totally ";
|
|
} else if (!ls.caseCompare(surfer, 0)) {
|
|
prefix = "Dude, it's ";
|
|
} else if (!ls.caseCompare(geek, 0)) {
|
|
prefix = "I'd estimate it is approximately ";
|
|
} else {
|
|
prefix = "Huh? Maybe ";
|
|
}
|
|
}
|
|
if (LocaleUtility::isFallbackOf(californio, id)) {
|
|
if (!id.caseCompare(valley, 0)) {
|
|
suffix = "like the Valley, you know? Let's go to the mall!";
|
|
} else if (!id.caseCompare(surfer, 0)) {
|
|
suffix = "time to hit those gnarly waves, Dude!!!";
|
|
} else if (!id.caseCompare(geek, 0)) {
|
|
suffix = "all systems go. T-Minus 9, 8, 7...";
|
|
} else {
|
|
suffix = "No Habla Englais";
|
|
}
|
|
} else {
|
|
suffix = ICUResourceBundleFactory::getDisplayName(id, locale, result);
|
|
}
|
|
|
|
result = prefix + suffix;
|
|
return result;
|
|
}
|
|
};
|
|
|
|
const char* CalifornioLanguageFactory::californio = "en_US_CA";
|
|
const char* CalifornioLanguageFactory::valley = "en_US_CA_VALLEY";
|
|
const char* CalifornioLanguageFactory::surfer = "en_US_CA_SURFER";
|
|
const char* CalifornioLanguageFactory::geek = "en_US_CA_GEEK";
|
|
Hashtable* CalifornioLanguageFactory::supportedIDs = NULL;
|
|
|
|
void
|
|
ICUServiceTest::testRBF()
|
|
{
|
|
// resource bundle factory.
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
TestStringService service;
|
|
service.registerFactory(new ICUResourceBundleFactory(), status);
|
|
|
|
// list all of the resources
|
|
{
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
UVector ids(uprv_deleteUObject, uhash_compareUnicodeString, 0, status);
|
|
service.getVisibleIDs(ids, status);
|
|
logln("all visible ids:");
|
|
for (int i = 0; i < ids.size(); ++i) {
|
|
const UnicodeString* id = (const UnicodeString*)ids[i];
|
|
logln(*id);
|
|
}
|
|
}
|
|
|
|
// get all the display names of these resources
|
|
// this should be fast since the display names were cached.
|
|
{
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
UVector names(status);
|
|
service.getDisplayNames(names, Locale::getGermany(), status);
|
|
logln("service display names for de_DE");
|
|
for (int i = 0; i < names.size(); ++i) {
|
|
const StringPair* pair = (const StringPair*)names[i];
|
|
logln(" " + pair->displayName + " --> " + pair->id);
|
|
}
|
|
}
|
|
|
|
service.registerFactory(new CalifornioLanguageFactory(), status);
|
|
|
|
// get all the display names of these resources
|
|
{
|
|
logln("californio language factory:");
|
|
const char* idNames[] = {
|
|
CalifornioLanguageFactory::californio,
|
|
CalifornioLanguageFactory::valley,
|
|
CalifornioLanguageFactory::surfer,
|
|
CalifornioLanguageFactory::geek,
|
|
};
|
|
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(status);
|
|
service.getDisplayNames(names, idNames[i], status);
|
|
for (int i = 0; i < names.size(); ++i) {
|
|
const StringPair* pair = (const StringPair*)names[i];
|
|
logln(" " + pair->displayName + " --> " + pair->id);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
CalifornioLanguageFactory::cleanup();
|
|
}
|
|
|
|
class SimpleListener : public ServiceListener {
|
|
ICUServiceTest* _test;
|
|
UnicodeString _name;
|
|
|
|
public:
|
|
SimpleListener(ICUServiceTest* test, const UnicodeString& name) : _test(test), _name(name) {}
|
|
|
|
virtual void serviceChanged(const ICUService& service) const {
|
|
UnicodeString serviceName = "listener ";
|
|
serviceName.append(_name);
|
|
serviceName.append(" n++");
|
|
serviceName.append(" service changed: " );
|
|
service.getName(serviceName);
|
|
_test->logln(serviceName);
|
|
}
|
|
};
|
|
|
|
void
|
|
ICUServiceTest::testNotification()
|
|
{
|
|
SimpleListener one(this, "one");
|
|
SimpleListener two(this, "two");
|
|
{
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
|
|
logln("simple registration notification");
|
|
TestStringService ls;
|
|
ls.addListener(&one, status);
|
|
ls.addListener(&two, status);
|
|
|
|
logln("registering foo... ");
|
|
ls.registerInstance(new UnicodeString("Foo"), "en_FOO", status);
|
|
logln("registering bar... ");
|
|
ls.registerInstance(new UnicodeString("Bar"), "en_BAR", status);
|
|
logln("getting foo...");
|
|
UnicodeString* result = (UnicodeString*)ls.get("en_FOO", status);
|
|
logln(*result);
|
|
delete result;
|
|
|
|
logln("removing listener 2...");
|
|
ls.removeListener(&two, status);
|
|
logln("registering baz...");
|
|
ls.registerInstance(new UnicodeString("Baz"), "en_BAZ", status);
|
|
logln("removing listener 1");
|
|
ls.removeListener(&one, status);
|
|
logln("registering burp...");
|
|
ls.registerInstance(new UnicodeString("Burp"), "en_BURP", status);
|
|
|
|
// should only get one notification even if register multiple times
|
|
logln("... trying multiple registration");
|
|
ls.addListener(&one, status);
|
|
ls.addListener(&one, status);
|
|
ls.addListener(&one, status);
|
|
ls.addListener(&two, status);
|
|
ls.registerInstance(new UnicodeString("Foo"), "en_FOO", status);
|
|
logln("... registered foo");
|
|
}
|
|
#if 0
|
|
// same thread, so we can't callback within notification, unlike Java
|
|
ServiceListener l3 = new ServiceListener() {
|
|
private int n;
|
|
public void serviceChanged(ICUService s) {
|
|
logln("listener 3 report " + n++ + " service changed...");
|
|
if (s.get("en_BOINK") == null) { // don't recurse on ourselves!!!
|
|
logln("registering boink...");
|
|
s.registerInstance("boink", "en_BOINK");
|
|
}
|
|
}
|
|
};
|
|
ls.addListener(l3);
|
|
logln("registering boo...");
|
|
ls.registerInstance("Boo", "en_BOO");
|
|
#endif
|
|
|
|
logln("...done");
|
|
}
|
|
|
|
class TestStringLocaleService : public ICULocaleService {
|
|
public:
|
|
virtual UObject* cloneInstance(UObject* instance) const {
|
|
return instance ? new UnicodeString(*(UnicodeString*)instance) : NULL;
|
|
}
|
|
};
|
|
|
|
void ICUServiceTest::testLocale() {
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
TestStringLocaleService service;
|
|
|
|
UnicodeString* root = new UnicodeString("root");
|
|
UnicodeString* german = new UnicodeString("german");
|
|
UnicodeString* germany = new UnicodeString("german_Germany");
|
|
UnicodeString* japanese = new UnicodeString("japanese");
|
|
UnicodeString* japan = new UnicodeString("japanese_Japan");
|
|
|
|
service.registerInstance(root, "", status);
|
|
service.registerInstance(german, "de", status);
|
|
service.registerInstance(germany, Locale::getGermany(), status);
|
|
service.registerInstance(japanese, (UnicodeString)"ja", TRUE, status);
|
|
service.registerInstance(japan, Locale::getJapan(), status);
|
|
|
|
{
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
UnicodeString* target = (UnicodeString*)service.get("de_US", status);
|
|
confirmEqual("test de_US", german, target);
|
|
delete target;
|
|
}
|
|
|
|
{
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
UnicodeString* target = (UnicodeString*)service.get("de_US", LocaleKey::KIND_ANY, status);
|
|
confirmEqual("test de_US 2", german, target);
|
|
delete target;
|
|
}
|
|
|
|
{
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
UnicodeString* target = (UnicodeString*)service.get("de_US", 1234, status);
|
|
confirmEqual("test de_US 3", german, target);
|
|
delete target;
|
|
}
|
|
|
|
{
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
Locale actualReturn;
|
|
UnicodeString* target = (UnicodeString*)service.get("de_US", &actualReturn, status);
|
|
confirmEqual("test de_US 5", german, target);
|
|
confirmEqual("test de_US 6", &actualReturn, &Locale::getGerman());
|
|
delete target;
|
|
}
|
|
|
|
{
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
Locale actualReturn;
|
|
UnicodeString* target = (UnicodeString*)service.get("de_US", LocaleKey::KIND_ANY, &actualReturn, status);
|
|
confirmEqual("test de_US 7", &actualReturn, &Locale::getGerman());
|
|
delete target;
|
|
}
|
|
|
|
{
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
Locale actualReturn;
|
|
UnicodeString* target = (UnicodeString*)service.get("de_US", 1234, &actualReturn, status);
|
|
confirmEqual("test de_US 8", german, target);
|
|
confirmEqual("test de_US 9", &actualReturn, &Locale::getGerman());
|
|
delete target;
|
|
}
|
|
|
|
UnicodeString* one = new UnicodeString("one/de_US");
|
|
UnicodeString* two = new UnicodeString("two/de_US");
|
|
|
|
service.registerInstance(one, Locale("de_US"), 1, status);
|
|
service.registerInstance(two, Locale("de_US"), 2, status);
|
|
|
|
{
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
UnicodeString* target = (UnicodeString*)service.get("de_US", 1, status);
|
|
confirmEqual("test de_US kind 1", one, target);
|
|
delete target;
|
|
}
|
|
|
|
{
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
UnicodeString* target = (UnicodeString*)service.get("de_US", 2, status);
|
|
confirmEqual("test de_US kind 2", two, target);
|
|
delete target;
|
|
}
|
|
|
|
{
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
UnicodeString* target = (UnicodeString*)service.get("de_US", status);
|
|
confirmEqual("test de_US kind 3", german, target);
|
|
delete target;
|
|
}
|
|
|
|
{
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
UnicodeString english = "en";
|
|
Locale localeResult;
|
|
UnicodeString result;
|
|
LocaleKey* lkey = LocaleKey::createWithCanonicalFallback(&english, NULL, 1234, status);
|
|
logln("lkey prefix: " + lkey->prefix(result));
|
|
result.remove();
|
|
logln("lkey descriptor: " + lkey->currentDescriptor(result));
|
|
result.remove();
|
|
logln(UnicodeString("lkey current locale: ") + lkey->currentLocale(localeResult).getName());
|
|
result.remove();
|
|
|
|
lkey->fallback();
|
|
logln("lkey descriptor 2: " + lkey->currentDescriptor(result));
|
|
result.remove();
|
|
|
|
lkey->fallback();
|
|
logln("lkey descriptor 3: " + lkey->currentDescriptor(result));
|
|
result.remove();
|
|
delete lkey; // tentatively weiv
|
|
}
|
|
|
|
{
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
UnicodeString* target = (UnicodeString*)service.get("za_PPP", status);
|
|
confirmEqual("test zappp", root, target);
|
|
delete target;
|
|
}
|
|
|
|
Locale loc = Locale::getDefault();
|
|
Locale::setDefault(Locale::getJapanese(), status);
|
|
{
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
UnicodeString* target = (UnicodeString*)service.get("za_PPP", status);
|
|
confirmEqual("test with ja locale", japanese, target);
|
|
delete target;
|
|
}
|
|
|
|
{
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
UVector ids(uprv_deleteUObject, uhash_compareUnicodeString, 0, status);
|
|
service.getVisibleIDs(ids, status);
|
|
logln("all visible ids:");
|
|
for (int i = 0; i < ids.size(); ++i) {
|
|
const UnicodeString* id = (const UnicodeString*)ids[i];
|
|
logln(*id);
|
|
}
|
|
}
|
|
|
|
Locale::setDefault(loc, status);
|
|
{
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
UVector ids(uprv_deleteUObject, uhash_compareUnicodeString, 0, status);
|
|
service.getVisibleIDs(ids, status);
|
|
logln("all visible ids:");
|
|
for (int i = 0; i < ids.size(); ++i) {
|
|
const UnicodeString* id = (const UnicodeString*)ids[i];
|
|
logln(*id);
|
|
}
|
|
}
|
|
|
|
{
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
UnicodeString* target = (UnicodeString*)service.get("za_PPP", status);
|
|
confirmEqual("test with en locale", root, target);
|
|
delete target;
|
|
}
|
|
|
|
{
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
StringEnumeration* locales = service.getAvailableLocales();
|
|
if (locales) {
|
|
confirmIdentical("test available locales", locales->count(status), 6);
|
|
logln("locales: ");
|
|
{
|
|
const char* p;
|
|
while ((p = locales->next(NULL, status))) {
|
|
logln(p);
|
|
}
|
|
}
|
|
logln(" ");
|
|
delete locales;
|
|
} else {
|
|
errln("could not create available locales");
|
|
}
|
|
}
|
|
}
|
|
|
|
class WrapFactory : public ICUServiceFactory {
|
|
public:
|
|
static const UnicodeString& getGreetingID() {
|
|
if (greetingID == NULL) {
|
|
greetingID = new UnicodeString("greeting");
|
|
}
|
|
return *greetingID;
|
|
}
|
|
|
|
static void cleanup() {
|
|
delete greetingID;
|
|
greetingID = NULL;
|
|
}
|
|
|
|
UObject* create(const ICUServiceKey& key, const ICUService* service, UErrorCode& status) const {
|
|
if (U_SUCCESS(status)) {
|
|
UnicodeString temp;
|
|
if (key.currentID(temp).compare(getGreetingID()) == 0) {
|
|
UnicodeString* previous = (UnicodeString*)service->getKey((ICUServiceKey&)key, NULL, this, status);
|
|
if (previous) {
|
|
previous->insert(0, "A different greeting: \"");
|
|
previous->append("\"");
|
|
return previous;
|
|
}
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void updateVisibleIDs(Hashtable& result, UErrorCode& status) const {
|
|
if (U_SUCCESS(status)) {
|
|
result.put("greeting", (void*)this, status);
|
|
}
|
|
}
|
|
|
|
UnicodeString& getDisplayName(const UnicodeString& id, const Locale& /* locale */, UnicodeString& result) const {
|
|
result.append("wrap '");
|
|
result.append(id);
|
|
result.append("'");
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* UObject boilerplate.
|
|
*/
|
|
static UClassID getStaticClassID() {
|
|
return (UClassID)&fgClassID;
|
|
}
|
|
|
|
virtual UClassID getDynamicClassID() const {
|
|
return getStaticClassID();
|
|
}
|
|
|
|
private:
|
|
static const char fgClassID;
|
|
static UnicodeString* greetingID;
|
|
};
|
|
|
|
UnicodeString* WrapFactory::greetingID = NULL;
|
|
const char WrapFactory::fgClassID = '\0';
|
|
|
|
void
|
|
ICUServiceTest::testWrapFactory()
|
|
{
|
|
UnicodeString* greeting = new UnicodeString("Hello There");
|
|
UnicodeString greetingID = "greeting";
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
TestStringService service;
|
|
service.registerInstance(greeting, greetingID, status);
|
|
|
|
{
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
UnicodeString* result = (UnicodeString*)service.get(greetingID, status);
|
|
if (result) {
|
|
logln("test one: " + *result);
|
|
delete result;
|
|
}
|
|
}
|
|
|
|
service.registerFactory(new WrapFactory(), status);
|
|
{
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
UnicodeString* result = (UnicodeString*)service.get(greetingID, status);
|
|
UnicodeString target = "A different greeting: \"Hello There\"";
|
|
confirmEqual("wrap test: ", result, &target);
|
|
delete result;
|
|
}
|
|
|
|
WrapFactory::cleanup();
|
|
}
|
|
|
|
// misc coverage tests
|
|
void ICUServiceTest::testCoverage()
|
|
{
|
|
// ICUServiceKey
|
|
{
|
|
UnicodeString temp;
|
|
ICUServiceKey key("foobar");
|
|
logln("ID: " + key.getID());
|
|
logln("canonicalID: " + key.canonicalID(temp));
|
|
logln("currentID: " + key.currentID(temp.remove()));
|
|
logln("has fallback: " + UnicodeString(key.fallback() ? "true" : "false"));
|
|
|
|
if (key.getDynamicClassID() != ICUServiceKey::getStaticClassID()) {
|
|
errln("service key rtt failed.");
|
|
}
|
|
}
|
|
|
|
// SimpleFactory
|
|
{
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
|
|
UnicodeString* obj = new UnicodeString("An Object");
|
|
SimpleFactory* sf = new SimpleFactory(obj, "object");
|
|
|
|
UnicodeString temp;
|
|
logln(sf->getDisplayName("object", Locale::getDefault(), temp));
|
|
|
|
if (sf->getDynamicClassID() != SimpleFactory::getStaticClassID()) {
|
|
errln("simple factory rtti failed.");
|
|
}
|
|
|
|
// 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");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 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
|
|
|
|
// LocaleKey
|
|
{
|
|
UnicodeString primary("en_US");
|
|
UnicodeString fallback("ja_JP");
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
LocaleKey* key = LocaleKey::createWithCanonicalFallback(&primary, &fallback, status);
|
|
|
|
if (key->getDynamicClassID() != LocaleKey::getStaticClassID()) {
|
|
errln("localekey rtti error");
|
|
}
|
|
|
|
if (!key->isFallbackOf("en_US_FOOBAR")) {
|
|
errln("localekey should be fallback for en_US_FOOBAR");
|
|
}
|
|
if (!key->isFallbackOf("en_US")) {
|
|
errln("localekey should be fallback for en_US");
|
|
}
|
|
if (key->isFallbackOf("en")) {
|
|
errln("localekey should not be fallback for en");
|
|
}
|
|
|
|
do {
|
|
Locale loc;
|
|
logln(UnicodeString("current locale: ") + key->currentLocale(loc).getName());
|
|
logln(UnicodeString("canonical locale: ") + key->canonicalLocale(loc).getName());
|
|
logln(UnicodeString("is fallback of en: ") + (key->isFallbackOf("en") ? "true" : " false"));
|
|
} while (key->fallback());
|
|
delete key;
|
|
|
|
// LocaleKeyFactory
|
|
key = LocaleKey::createWithCanonicalFallback(&primary, &fallback, status);
|
|
|
|
UnicodeString result;
|
|
LKFSubclass lkf(TRUE); // empty
|
|
Hashtable table;
|
|
|
|
UObject *obj = lkf.create(*key, NULL, status);
|
|
logln("obj: " + UnicodeString(obj ? "obj" : "null"));
|
|
logln(lkf.getDisplayName("en_US", Locale::getDefault(), result));
|
|
lkf.updateVisibleIDs(table, status);
|
|
delete obj;
|
|
if (table.count() != 1) {
|
|
errln("visible IDs does not contain en_US");
|
|
}
|
|
|
|
LKFSubclass invisibleLKF(FALSE);
|
|
obj = lkf.create(*key, NULL, status);
|
|
logln("obj: " + UnicodeString(obj ? "obj" : "null"));
|
|
logln(invisibleLKF.getDisplayName("en_US", Locale::getDefault(), result.remove()));
|
|
invisibleLKF.updateVisibleIDs(table, status);
|
|
if (table.count() != 0) {
|
|
errln("visible IDs contains en_US");
|
|
}
|
|
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;
|
|
}
|
|
|
|
// 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;
|
|
}
|
|
|
|
#if 0
|
|
// ICUNotifier
|
|
ICUNotifier nf = new ICUNSubclass();
|
|
try {
|
|
nf.addListener(null);
|
|
errln("added null listener");
|
|
}
|
|
catch (NullPointerException e) {
|
|
logln(e.getMessage());
|
|
}
|
|
catch (Exception e) {
|
|
errln("got wrong exception");
|
|
}
|
|
|
|
try {
|
|
nf.addListener(new WrongListener());
|
|
errln("added wrong listener");
|
|
}
|
|
catch (InternalError e) {
|
|
logln(e.getMessage());
|
|
}
|
|
catch (Exception e) {
|
|
errln("got wrong exception");
|
|
}
|
|
|
|
try {
|
|
nf.removeListener(null);
|
|
errln("removed null listener");
|
|
}
|
|
catch (NullPointerException e) {
|
|
logln(e.getMessage());
|
|
}
|
|
catch (Exception e) {
|
|
errln("got wrong exception");
|
|
}
|
|
|
|
nf.removeListener(new MyListener());
|
|
nf.notifyChanged();
|
|
nf.addListener(new MyListener());
|
|
nf.removeListener(new MyListener());
|
|
#endif
|
|
}
|
|
|
|
|
|
/* !UCONFIG_NO_SERVICE */
|
|
#endif
|
|
|
|
|