]> git.saurik.com Git - apple/icu.git/blob - icuSources/test/intltest/svccoll.cpp
ICU-3.13.tar.gz
[apple/icu.git] / icuSources / test / intltest / svccoll.cpp
1 /*
2 *******************************************************************************
3 * Copyright (C) 2003, International Business Machines Corporation and *
4 * others. All Rights Reserved. *
5 *******************************************************************************
6 */
7
8 #include "unicode/utypes.h"
9
10 #if !UCONFIG_NO_COLLATION
11
12 #include "svccoll.h"
13 #include "unicode/coll.h"
14 #include "unicode/strenum.h"
15 #include "hash.h"
16
17 #include "ucol_imp.h" // internal api needed to test ucollator equality
18 #include "cstring.h" // internal api used to compare locale strings
19
20 void CollationServiceTest::TestRegister()
21 {
22 // register a singleton
23 const Locale& FR = Locale::getFrance();
24 const Locale& US = Locale::getUS();
25 const Locale US_FOO("en", "US", "FOO");
26
27 UErrorCode status = U_ZERO_ERROR;
28
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));
33 delete frcol;
34 delete uscol;
35 return;
36 }
37
38 { // try override en_US collator
39 URegistryKey key = Collator::registerInstance(frcol, US, status);
40
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");
44 }
45 // ensure original collator's params not touched
46 Locale loc = frcol->getLocale(ULOC_REQUESTED_LOCALE, status);
47 if (loc != FR) {
48 errln(UnicodeString("fr collator's requested locale changed to ") + loc.getName());
49 }
50 loc = frcol->getLocale(ULOC_VALID_LOCALE, status);
51 if (loc != FR) {
52 errln(UnicodeString("fr collator's valid locale changed to ") + loc.getName());
53 }
54
55 loc = ncol->getLocale(ULOC_REQUESTED_LOCALE, status);
56 if (loc != US_FOO) {
57 errln(UnicodeString("requested locale for en_US_FOO is not en_US_FOO but ") + loc.getName());
58 }
59 loc = ncol->getLocale(ULOC_VALID_LOCALE, status);
60 if (loc != US) {
61 errln(UnicodeString("valid locale for en_US_FOO is not en_US but ") + loc.getName());
62 }
63 loc = ncol->getLocale(ULOC_ACTUAL_LOCALE, status);
64 if (loc != US) {
65 errln(UnicodeString("actual locale for en_US_FOO is not en_US but ") + loc.getName());
66 }
67 delete ncol; ncol = NULL;
68
69 if (!Collator::unregister(key, status)) {
70 errln("failed to unregister french collator");
71 }
72 // !!! frcol pointer is now invalid !!!
73
74 ncol = Collator::createInstance(US, status);
75 if (*uscol != *ncol) {
76 errln("collator after unregister does not match original");
77 }
78 delete ncol; ncol = NULL;
79 }
80
81 // recreate frcol
82 frcol = Collator::createInstance(FR, status);
83
84 UCollator* frFR = ucol_open("fr_FR", &status);
85
86 { // try create collator for new locale
87 Locale fu_FU_FOO("fu", "FU", "FOO");
88 Locale fu_FU("fu", "FU", "");
89
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");
95 }
96
97 UnicodeString locName = fu_FU.getName();
98 StringEnumeration* localeEnum = Collator::getAvailableLocales();
99 UBool found = FALSE;
100 const UnicodeString* locStr;
101 for (locStr = localeEnum->snext(status);
102 !found && locStr != NULL;
103 locStr = localeEnum->snext(status)) {
104 //
105 if (locName == *locStr) {
106 found = TRUE;
107 }
108 }
109 delete localeEnum;
110
111 if (!found) {
112 errln("new locale fu_FU not reported as supported locale");
113 }
114
115 UnicodeString displayName;
116 Collator::getDisplayName(fu_FU, displayName);
117 if (displayName != "fu (FU)") {
118 errln(UnicodeString("found ") + displayName + " for fu_FU");
119 }
120
121 Collator::getDisplayName(fu_FU, fu_FU, displayName);
122 if (displayName != "fu (FU)") {
123 errln(UnicodeString("found ") + displayName + " for fu_FU");
124 }
125
126 // test ucol_open
127 UCollator* fufu = ucol_open("fu_FU_FOO", &status);
128 if (!fufu) {
129 errln("could not open fu_FU_FOO with ucol_open");
130 } else {
131 if (!ucol_equals(fufu, frFR)) {
132 errln("collator fufu != collator frFR");
133 }
134 }
135
136 if (!Collator::unregister(key, status)) {
137 errln("failed to unregister french collator");
138 }
139 // !!! note frcoll invalid again, but we're no longer using it
140
141 // other collators should still work ok
142 Locale nloc = ncol->getLocale(ULOC_VALID_LOCALE, status);
143 if (nloc != fu_FU) {
144 errln(UnicodeString("asked for nloc valid locale after close and got") + nloc.getName());
145 }
146 delete ncol; ncol = NULL;
147
148 if (fufu) {
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);
152 }
153 ucol_close(fufu);
154 }
155 ucol_close(frFR);
156
157 ncol = Collator::createInstance(fu_FU, status);
158 if (*fucol != *ncol) {
159 errln("collator after unregister does not match original fu_FU");
160 }
161 delete uscol; uscol = NULL;
162 delete ncol; ncol = NULL;
163 delete fucol; fucol = NULL;
164 }
165 }
166
167 // ------------------
168
169 struct CollatorInfo {
170 Locale locale;
171 Collator* collator;
172 Hashtable* displayNames; // locale name -> string
173
174 CollatorInfo(const Locale& locale, Collator* collatorToAdopt, Hashtable* displayNamesToAdopt);
175 ~CollatorInfo();
176 UnicodeString& getDisplayName(const Locale& displayLocale, UnicodeString& name) const;
177 };
178
179 CollatorInfo::CollatorInfo(const Locale& _locale, Collator* _collator, Hashtable* _displayNames)
180 : locale(_locale)
181 , collator(_collator)
182 , displayNames(_displayNames)
183 {
184 }
185
186 CollatorInfo::~CollatorInfo() {
187 delete collator;
188 delete displayNames;
189 }
190
191 UnicodeString&
192 CollatorInfo::getDisplayName(const Locale& displayLocale, UnicodeString& name) const {
193 if (displayNames) {
194 UnicodeString* val = (UnicodeString*)displayNames->get(displayLocale.getName());
195 if (val) {
196 name = *val;
197 return name;
198 }
199 }
200
201 return locale.getDisplayName(displayLocale, name);
202 }
203
204 // ---------------
205
206 class TestFactory : public CollatorFactory {
207 CollatorInfo** info;
208 int32_t count;
209 UnicodeString* ids;
210
211 const CollatorInfo* getInfo(const Locale& loc) const {
212 for (CollatorInfo** p = info; *p; ++p) {
213 if (loc == (**p).locale) {
214 return *p;
215 }
216 }
217 return NULL;
218 }
219
220 public:
221 TestFactory(CollatorInfo** _info)
222 : info(_info)
223 , count(0)
224 , ids(NULL)
225 {
226 CollatorInfo** p;
227 for (p = info; *p; ++p) {}
228 count = p - info;
229 }
230
231 ~TestFactory() {
232 for (CollatorInfo** p = info; *p; ++p) {
233 delete *p;
234 }
235 delete[] info;
236 delete[] ids;
237 }
238
239 virtual Collator* createCollator(const Locale& loc) {
240 const CollatorInfo* ci = getInfo(loc);
241 if (ci) {
242 return ci->collator->clone();
243 }
244 return NULL;
245 }
246
247 virtual UnicodeString& getDisplayName(const Locale& objectLocale,
248 const Locale& displayLocale,
249 UnicodeString& result)
250 {
251 const CollatorInfo* ci = getInfo(objectLocale);
252 if (ci) {
253 ci->getDisplayName(displayLocale, result);
254 } else {
255 result.setToBogus();
256 }
257 return result;
258 }
259
260 const UnicodeString* getSupportedIDs(int32_t& _count, UErrorCode& status) {
261 if (U_SUCCESS(status)) {
262 if (!ids) {
263 ids = new UnicodeString[count];
264 if (!ids) {
265 status = U_MEMORY_ALLOCATION_ERROR;
266 _count = 0;
267 return NULL;
268 }
269
270 for (int i = 0; i < count; ++i) {
271 ids[i] = info[i]->locale.getName();
272 }
273 }
274
275 _count = count;
276 return ids;
277 }
278 return NULL;
279 }
280
281 virtual inline UClassID getDynamicClassID() const {
282 return (UClassID)&gClassID;
283 }
284
285 static UClassID getStaticClassID() {
286 return (UClassID)&gClassID;
287 }
288
289 private:
290 static char gClassID;
291 };
292
293 char TestFactory::gClassID = 0;
294
295 void CollationServiceTest::TestRegisterFactory(void)
296 {
297 Locale fu_FU("fu", "FU", "");
298 Locale fu_FU_FOO("fu", "FU", "FOO");
299
300 UErrorCode status = U_ZERO_ERROR;
301
302 Hashtable* fuFUNames = new Hashtable(FALSE, status);
303 if (!fuFUNames) {
304 errln("memory allocation error");
305 return;
306 }
307 fuFUNames->setValueDeleter(uhash_deleteUnicodeString);
308
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);
312
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));
318 delete frcol;
319 delete gecol;
320 delete jpcol;
321 delete fuFUNames;
322 return;
323 }
324
325 CollatorInfo** info = new CollatorInfo*[4];
326 if (!info) {
327 errln("memory allocation error");
328 return;
329 }
330
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);
334 info[3] = NULL;
335
336 TestFactory* factory = new TestFactory(info);
337 if (!factory) {
338 errln("memory allocation error");
339 return;
340 }
341
342 Collator* uscol = Collator::createInstance(Locale::getUS(), status);
343 Collator* fucol = Collator::createInstance(fu_FU, status);
344
345 {
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");
350 }
351 delete ncol; ncol = NULL;
352
353 ncol = Collator::createInstance(fu_FU_FOO, status);
354 if (*jpcol != *ncol) {
355 errln("jpcol for fu_FU_FOO failed");
356 }
357
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());
361 }
362 loc = ncol->getLocale(ULOC_VALID_LOCALE, status);
363 if (loc != fu_FU) {
364 errln(UnicodeString("valid locale for fu_FU_FOO is not fu_FU but ") + loc.getName());
365 }
366 delete ncol; ncol = NULL;
367
368 UnicodeString locName = fu_FU.getName();
369 StringEnumeration* localeEnum = Collator::getAvailableLocales();
370 UBool found = FALSE;
371 const UnicodeString* locStr;
372 for (locStr = localeEnum->snext(status);
373 !found && locStr != NULL;
374 locStr = localeEnum->snext(status))
375 {
376 if (locName == *locStr) {
377 found = TRUE;
378 }
379 }
380 delete localeEnum;
381
382 if (!found) {
383 errln("new locale fu_FU not reported as supported locale");
384 }
385
386 UnicodeString name;
387 Collator::getDisplayName(fu_FU, name);
388 if (name != "little bunny Foo Foo") {
389 errln(UnicodeString("found ") + name + " for fu_FU");
390 }
391
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");
395 }
396
397 if (!Collator::unregister(key, status)) {
398 errln("failed to unregister factory");
399 }
400 // ja, fr, ge collators no longer valid
401
402 ncol = Collator::createInstance(fu_FU, status);
403 if (*fucol != *ncol) {
404 errln("collator after unregister does not match original fu_FU");
405 }
406 delete ncol;
407 }
408
409 delete fucol;
410 delete uscol;
411 }
412
413 void CollationServiceTest::runIndexedTest(int32_t index, UBool exec, const char* &name, char* /*par */)
414 {
415 if (exec) logln("TestSuite CollationServiceTest: ");
416 switch (index) {
417 TESTCASE(0, TestRegister);
418 TESTCASE(1, TestRegisterFactory);
419 default: name = ""; break;
420 }
421 }
422
423 #endif