2 *******************************************************************************
3 * Copyright (C) 2003, International Business Machines Corporation and *
4 * others. All Rights Reserved. *
5 *******************************************************************************
8 #include "unicode/utypes.h"
10 #if !UCONFIG_NO_COLLATION
13 #include "unicode/coll.h"
14 #include "unicode/strenum.h"
17 #include "ucol_imp.h" // internal api needed to test ucollator equality
18 #include "cstring.h" // internal api used to compare locale strings
20 void CollationServiceTest::TestRegister()
22 // register a singleton
23 const Locale
& FR
= Locale::getFrance();
24 const Locale
& US
= Locale::getUS();
25 const Locale
US_FOO("en", "US", "FOO");
27 UErrorCode status
= U_ZERO_ERROR
;
29 Collator
* frcol
= Collator::createInstance(FR
, status
);
30 Collator
* uscol
= Collator::createInstance(US
, status
);
31 if(U_FAILURE(status
)) {
32 errln("Failed to create collators with %s", u_errorName(status
));
38 { // try override en_US collator
39 URegistryKey key
= Collator::registerInstance(frcol
, US
, status
);
41 Collator
* ncol
= Collator::createInstance(US_FOO
, status
);
42 if (*frcol
!= *ncol
) {
43 errln("register of french collator for en_US failed on request for en_US_FOO");
45 // ensure original collator's params not touched
46 Locale loc
= frcol
->getLocale(ULOC_REQUESTED_LOCALE
, status
);
48 errln(UnicodeString("fr collator's requested locale changed to ") + loc
.getName());
50 loc
= frcol
->getLocale(ULOC_VALID_LOCALE
, status
);
52 errln(UnicodeString("fr collator's valid locale changed to ") + loc
.getName());
55 loc
= ncol
->getLocale(ULOC_REQUESTED_LOCALE
, status
);
57 errln(UnicodeString("requested locale for en_US_FOO is not en_US_FOO but ") + loc
.getName());
59 loc
= ncol
->getLocale(ULOC_VALID_LOCALE
, status
);
61 errln(UnicodeString("valid locale for en_US_FOO is not en_US but ") + loc
.getName());
63 loc
= ncol
->getLocale(ULOC_ACTUAL_LOCALE
, status
);
65 errln(UnicodeString("actual locale for en_US_FOO is not en_US but ") + loc
.getName());
67 delete ncol
; ncol
= NULL
;
69 if (!Collator::unregister(key
, status
)) {
70 errln("failed to unregister french collator");
72 // !!! frcol pointer is now invalid !!!
74 ncol
= Collator::createInstance(US
, status
);
75 if (*uscol
!= *ncol
) {
76 errln("collator after unregister does not match original");
78 delete ncol
; ncol
= NULL
;
82 frcol
= Collator::createInstance(FR
, status
);
84 UCollator
* frFR
= ucol_open("fr_FR", &status
);
86 { // try create collator for new locale
87 Locale
fu_FU_FOO("fu", "FU", "FOO");
88 Locale
fu_FU("fu", "FU", "");
90 Collator
* fucol
= Collator::createInstance(fu_FU
, status
);
91 URegistryKey key
= Collator::registerInstance(frcol
, fu_FU
, status
);
92 Collator
* ncol
= Collator::createInstance(fu_FU_FOO
, status
);
93 if (*frcol
!= *ncol
) {
94 errln("register of fr collator for fu_FU failed");
97 UnicodeString locName
= fu_FU
.getName();
98 StringEnumeration
* localeEnum
= Collator::getAvailableLocales();
100 const UnicodeString
* locStr
;
101 for (locStr
= localeEnum
->snext(status
);
102 !found
&& locStr
!= NULL
;
103 locStr
= localeEnum
->snext(status
)) {
105 if (locName
== *locStr
) {
112 errln("new locale fu_FU not reported as supported locale");
115 UnicodeString displayName
;
116 Collator::getDisplayName(fu_FU
, displayName
);
117 if (displayName
!= "fu (FU)") {
118 errln(UnicodeString("found ") + displayName
+ " for fu_FU");
121 Collator::getDisplayName(fu_FU
, fu_FU
, displayName
);
122 if (displayName
!= "fu (FU)") {
123 errln(UnicodeString("found ") + displayName
+ " for fu_FU");
127 UCollator
* fufu
= ucol_open("fu_FU_FOO", &status
);
129 errln("could not open fu_FU_FOO with ucol_open");
131 if (!ucol_equals(fufu
, frFR
)) {
132 errln("collator fufu != collator frFR");
136 if (!Collator::unregister(key
, status
)) {
137 errln("failed to unregister french collator");
139 // !!! note frcoll invalid again, but we're no longer using it
141 // other collators should still work ok
142 Locale nloc
= ncol
->getLocale(ULOC_VALID_LOCALE
, status
);
144 errln(UnicodeString("asked for nloc valid locale after close and got") + nloc
.getName());
146 delete ncol
; ncol
= NULL
;
149 const char* nlocstr
= ucol_getLocale(fufu
, ULOC_VALID_LOCALE
, &status
);
150 if (uprv_strcmp(nlocstr
, "fu_FU") != 0) {
151 errln(UnicodeString("asked for uloc valid locale after close and got ") + nlocstr
);
157 ncol
= Collator::createInstance(fu_FU
, status
);
158 if (*fucol
!= *ncol
) {
159 errln("collator after unregister does not match original fu_FU");
161 delete uscol
; uscol
= NULL
;
162 delete ncol
; ncol
= NULL
;
163 delete fucol
; fucol
= NULL
;
167 // ------------------
169 struct CollatorInfo
{
172 Hashtable
* displayNames
; // locale name -> string
174 CollatorInfo(const Locale
& locale
, Collator
* collatorToAdopt
, Hashtable
* displayNamesToAdopt
);
176 UnicodeString
& getDisplayName(const Locale
& displayLocale
, UnicodeString
& name
) const;
179 CollatorInfo::CollatorInfo(const Locale
& _locale
, Collator
* _collator
, Hashtable
* _displayNames
)
181 , collator(_collator
)
182 , displayNames(_displayNames
)
186 CollatorInfo::~CollatorInfo() {
192 CollatorInfo::getDisplayName(const Locale
& displayLocale
, UnicodeString
& name
) const {
194 UnicodeString
* val
= (UnicodeString
*)displayNames
->get(displayLocale
.getName());
201 return locale
.getDisplayName(displayLocale
, name
);
206 class TestFactory
: public CollatorFactory
{
211 const CollatorInfo
* getInfo(const Locale
& loc
) const {
212 for (CollatorInfo
** p
= info
; *p
; ++p
) {
213 if (loc
== (**p
).locale
) {
221 TestFactory(CollatorInfo
** _info
)
227 for (p
= info
; *p
; ++p
) {}
232 for (CollatorInfo
** p
= info
; *p
; ++p
) {
239 virtual Collator
* createCollator(const Locale
& loc
) {
240 const CollatorInfo
* ci
= getInfo(loc
);
242 return ci
->collator
->clone();
247 virtual UnicodeString
& getDisplayName(const Locale
& objectLocale
,
248 const Locale
& displayLocale
,
249 UnicodeString
& result
)
251 const CollatorInfo
* ci
= getInfo(objectLocale
);
253 ci
->getDisplayName(displayLocale
, result
);
260 const UnicodeString
* getSupportedIDs(int32_t& _count
, UErrorCode
& status
) {
261 if (U_SUCCESS(status
)) {
263 ids
= new UnicodeString
[count
];
265 status
= U_MEMORY_ALLOCATION_ERROR
;
270 for (int i
= 0; i
< count
; ++i
) {
271 ids
[i
] = info
[i
]->locale
.getName();
281 virtual inline UClassID
getDynamicClassID() const {
282 return (UClassID
)&gClassID
;
285 static UClassID
getStaticClassID() {
286 return (UClassID
)&gClassID
;
290 static char gClassID
;
293 char TestFactory::gClassID
= 0;
295 void CollationServiceTest::TestRegisterFactory(void)
297 Locale
fu_FU("fu", "FU", "");
298 Locale
fu_FU_FOO("fu", "FU", "FOO");
300 UErrorCode status
= U_ZERO_ERROR
;
302 Hashtable
* fuFUNames
= new Hashtable(FALSE
, status
);
304 errln("memory allocation error");
307 fuFUNames
->setValueDeleter(uhash_deleteUnicodeString
);
309 fuFUNames
->put(fu_FU
.getName(), new UnicodeString("ze leetle bunny Fu-Fu"), status
);
310 fuFUNames
->put(fu_FU_FOO
.getName(), new UnicodeString("zee leetel bunny Foo-Foo"), status
);
311 fuFUNames
->put(Locale::getUS().getName(), new UnicodeString("little bunny Foo Foo"), status
);
313 Collator
* frcol
= Collator::createInstance(Locale::getFrance(), status
);
314 Collator
* gecol
= Collator::createInstance(Locale::getGermany(), status
);
315 Collator
* jpcol
= Collator::createInstance(Locale::getJapan(), status
);
316 if(U_FAILURE(status
)) {
317 errln("Failed to create collators with %s", u_errorName(status
));
325 CollatorInfo
** info
= new CollatorInfo
*[4];
327 errln("memory allocation error");
331 info
[0] = new CollatorInfo(Locale::getUS(), frcol
, NULL
);
332 info
[1] = new CollatorInfo(Locale::getFrance(), gecol
, NULL
);
333 info
[2] = new CollatorInfo(fu_FU
, jpcol
, fuFUNames
);
336 TestFactory
* factory
= new TestFactory(info
);
338 errln("memory allocation error");
342 Collator
* uscol
= Collator::createInstance(Locale::getUS(), status
);
343 Collator
* fucol
= Collator::createInstance(fu_FU
, status
);
346 URegistryKey key
= Collator::registerFactory(factory
, status
);
347 Collator
* ncol
= Collator::createInstance(Locale::getUS(), status
);
348 if (*frcol
!= *ncol
) {
349 errln("frcoll for en_US failed");
351 delete ncol
; ncol
= NULL
;
353 ncol
= Collator::createInstance(fu_FU_FOO
, status
);
354 if (*jpcol
!= *ncol
) {
355 errln("jpcol for fu_FU_FOO failed");
358 Locale loc
= ncol
->getLocale(ULOC_REQUESTED_LOCALE
, status
);
359 if (loc
!= fu_FU_FOO
) {
360 errln(UnicodeString("requested locale for fu_FU_FOO is not fu_FU_FOO but ") + loc
.getName());
362 loc
= ncol
->getLocale(ULOC_VALID_LOCALE
, status
);
364 errln(UnicodeString("valid locale for fu_FU_FOO is not fu_FU but ") + loc
.getName());
366 delete ncol
; ncol
= NULL
;
368 UnicodeString locName
= fu_FU
.getName();
369 StringEnumeration
* localeEnum
= Collator::getAvailableLocales();
371 const UnicodeString
* locStr
;
372 for (locStr
= localeEnum
->snext(status
);
373 !found
&& locStr
!= NULL
;
374 locStr
= localeEnum
->snext(status
))
376 if (locName
== *locStr
) {
383 errln("new locale fu_FU not reported as supported locale");
387 Collator::getDisplayName(fu_FU
, name
);
388 if (name
!= "little bunny Foo Foo") {
389 errln(UnicodeString("found ") + name
+ " for fu_FU");
392 Collator::getDisplayName(fu_FU
, fu_FU_FOO
, name
);
393 if (name
!= "zee leetel bunny Foo-Foo") {
394 errln(UnicodeString("found ") + name
+ " for fu_FU in fu_FU_FOO");
397 if (!Collator::unregister(key
, status
)) {
398 errln("failed to unregister factory");
400 // ja, fr, ge collators no longer valid
402 ncol
= Collator::createInstance(fu_FU
, status
);
403 if (*fucol
!= *ncol
) {
404 errln("collator after unregister does not match original fu_FU");
413 void CollationServiceTest::runIndexedTest(int32_t index
, UBool exec
, const char* &name
, char* /*par */)
415 if (exec
) logln("TestSuite CollationServiceTest: ");
417 TESTCASE(0, TestRegister
);
418 TESTCASE(1, TestRegisterFactory
);
419 default: name
= ""; break;