]>
Commit | Line | Data |
---|---|---|
b75a7d8f A |
1 | /** |
2 | ******************************************************************************* | |
73c04bcf | 3 | * Copyright (C) 2001-2005, International Business Machines Corporation and * |
b75a7d8f A |
4 | * others. All Rights Reserved. * |
5 | ******************************************************************************* | |
6 | * | |
7 | ******************************************************************************* | |
8 | */ | |
9 | ||
10 | #include "unicode/utypes.h" | |
11 | ||
12 | #if !UCONFIG_NO_SERVICE | |
13 | ||
14 | #include "icusvtst.h" | |
73c04bcf | 15 | #include "servloc.h" |
374ca955 | 16 | #include <stdio.h> |
b75a7d8f A |
17 | |
18 | ||
19 | class MyListener : public EventListener { | |
20 | }; | |
21 | ||
22 | class WrongListener : public EventListener { | |
23 | }; | |
24 | ||
25 | class ICUNSubclass : public ICUNotifier { | |
26 | public: | |
73c04bcf | 27 | UBool acceptsListener(const EventListener& /*l*/) const { |
b75a7d8f A |
28 | return TRUE; |
29 | // return l instanceof MyListener; | |
30 | } | |
31 | ||
73c04bcf | 32 | virtual void notifyListener(EventListener& /*l*/) const { |
b75a7d8f A |
33 | } |
34 | }; | |
35 | ||
73c04bcf A |
36 | // This factory does nothing |
37 | class LKFSubclass0 : public LocaleKeyFactory { | |
38 | public: | |
39 | LKFSubclass0() | |
40 | : LocaleKeyFactory(VISIBLE, "LKFSubclass0") | |
41 | { | |
42 | } | |
43 | }; | |
44 | ||
b75a7d8f | 45 | class LKFSubclass : public LocaleKeyFactory { |
374ca955 | 46 | Hashtable table; |
b75a7d8f A |
47 | |
48 | public: | |
49 | LKFSubclass(UBool visible) | |
50 | : LocaleKeyFactory(visible ? VISIBLE : INVISIBLE, "LKFSubclass") | |
51 | { | |
374ca955 A |
52 | UErrorCode status = U_ZERO_ERROR; |
53 | table.put("en_US", this, status); | |
b75a7d8f A |
54 | } |
55 | ||
56 | protected: | |
374ca955 A |
57 | virtual const Hashtable* getSupportedIDs(UErrorCode &/*status*/) const { |
58 | return &table; | |
59 | } | |
b75a7d8f A |
60 | }; |
61 | ||
62 | class Integer : public UObject { | |
63 | public: | |
64 | const int32_t _val; | |
65 | ||
66 | Integer(int32_t val) : _val(val) { | |
67 | } | |
68 | ||
69 | Integer(const Integer& rhs) : UObject(rhs), _val(rhs._val) { | |
70 | } | |
71 | virtual ~Integer() { | |
72 | } | |
73 | ||
b75a7d8f A |
74 | public: |
75 | /** | |
76 | * UObject boilerplate. | |
77 | */ | |
73c04bcf A |
78 | static UClassID getStaticClassID() { |
79 | return (UClassID)&fgClassID; | |
80 | } | |
81 | ||
b75a7d8f A |
82 | virtual UClassID getDynamicClassID() const { |
83 | return getStaticClassID(); | |
84 | } | |
85 | ||
73c04bcf A |
86 | virtual UBool operator==(const UObject& other) const |
87 | { | |
88 | return other.getDynamicClassID() == getStaticClassID() && | |
89 | _val == ((Integer&)other)._val; | |
b75a7d8f A |
90 | } |
91 | ||
92 | public: | |
93 | virtual UnicodeString& debug(UnicodeString& result) const { | |
94 | debugClass(result); | |
95 | result.append(" val: "); | |
96 | result.append(_val); | |
97 | return result; | |
98 | } | |
99 | ||
100 | virtual UnicodeString& debugClass(UnicodeString& result) const { | |
101 | return result.append("Integer"); | |
102 | } | |
103 | ||
104 | private: | |
105 | static const char fgClassID; | |
106 | }; | |
107 | ||
108 | const char Integer::fgClassID = '\0'; | |
109 | ||
110 | // use locale keys | |
111 | class TestIntegerService : public ICUService { | |
112 | public: | |
113 | ICUServiceKey* createKey(const UnicodeString* id, UErrorCode& status) const { | |
114 | return LocaleKey::createWithCanonicalFallback(id, NULL, status); // no fallback locale | |
115 | } | |
116 | ||
117 | virtual ICUServiceFactory* createSimpleFactory(UObject* obj, const UnicodeString& id, UBool visible, UErrorCode& status) | |
118 | { | |
119 | if (U_SUCCESS(status) && obj && obj->getDynamicClassID() == Integer::getStaticClassID()) { | |
120 | return new SimpleFactory((Integer*)obj, id, visible); | |
121 | } | |
122 | return NULL; | |
123 | } | |
124 | ||
125 | virtual UObject* cloneInstance(UObject* instance) const { | |
126 | return instance ? new Integer(*(Integer*)instance) : NULL; | |
127 | } | |
128 | }; | |
129 | ||
130 | ||
131 | ICUServiceTest::ICUServiceTest() { | |
132 | } | |
133 | ||
134 | ICUServiceTest::~ICUServiceTest() { | |
135 | } | |
136 | ||
137 | void | |
138 | ICUServiceTest::runIndexedTest(int32_t index, UBool exec, const char* &name, | |
139 | char* /*par*/) | |
140 | { | |
141 | switch (index) { | |
142 | TESTCASE(0,testAPI_One); | |
143 | TESTCASE(1,testAPI_Two); | |
144 | TESTCASE(2,testRBF); | |
145 | TESTCASE(3,testNotification); | |
146 | TESTCASE(4,testLocale); | |
147 | TESTCASE(5,testWrapFactory); | |
148 | TESTCASE(6,testCoverage); | |
149 | default: name = ""; break; | |
150 | } | |
151 | } | |
152 | ||
153 | UnicodeString append(UnicodeString& result, const UObject* obj) | |
154 | { | |
155 | char buffer[128]; | |
156 | if (obj == NULL) { | |
157 | result.append("NULL"); | |
158 | } else { | |
159 | UClassID id = obj->getDynamicClassID(); | |
160 | if (id == UnicodeString::getStaticClassID()) { | |
161 | result.append(*(UnicodeString*)obj); | |
162 | } else if (id == Locale::getStaticClassID()) { | |
163 | result.append(((Locale*)obj)->getName()); | |
164 | } else if (id == Integer::getStaticClassID()) { | |
374ca955 | 165 | sprintf(buffer, "%d", (int)((Integer*)obj)->_val); |
b75a7d8f A |
166 | result.append(buffer); |
167 | } else { | |
168 | sprintf(buffer, "%p", (const void*)obj); | |
169 | result.append(buffer); | |
170 | } | |
171 | } | |
172 | return result; | |
173 | } | |
174 | ||
175 | UnicodeString& | |
176 | ICUServiceTest::lrmsg(UnicodeString& result, const UnicodeString& message, const UObject* lhs, const UObject* rhs) const | |
177 | { | |
178 | result.append(message); | |
179 | result.append(" lhs: "); | |
180 | append(result, lhs); | |
181 | result.append(", rhs: "); | |
182 | append(result, rhs); | |
183 | return result; | |
184 | } | |
185 | ||
186 | void | |
187 | ICUServiceTest::confirmBoolean(const UnicodeString& message, UBool val) | |
188 | { | |
189 | if (val) { | |
190 | logln(message); | |
191 | } else { | |
192 | errln(message); | |
193 | } | |
194 | } | |
195 | ||
196 | #if 0 | |
197 | void | |
198 | ICUServiceTest::confirmEqual(const UnicodeString& message, const UObject* lhs, const UObject* rhs) | |
199 | { | |
200 | UBool equ = (lhs == NULL) | |
201 | ? (rhs == NULL) | |
202 | : (rhs != NULL && lhs->operator==(*rhs)); | |
203 | ||
204 | UnicodeString temp; | |
205 | lrmsg(temp, message, lhs, rhs); | |
206 | ||
207 | if (equ) { | |
208 | logln(temp); | |
209 | } else { | |
210 | errln(temp); | |
211 | } | |
212 | } | |
213 | #else | |
214 | void | |
215 | ICUServiceTest::confirmEqual(const UnicodeString& message, const Integer* lhs, const Integer* rhs) | |
216 | { | |
217 | UBool equ = (lhs == NULL) | |
218 | ? (rhs == NULL) | |
219 | : (rhs != NULL && lhs->operator==(*rhs)); | |
220 | ||
221 | UnicodeString temp; | |
222 | lrmsg(temp, message, lhs, rhs); | |
223 | ||
224 | if (equ) { | |
225 | logln(temp); | |
226 | } else { | |
227 | errln(temp); | |
228 | } | |
229 | } | |
230 | ||
231 | void | |
232 | ICUServiceTest::confirmEqual(const UnicodeString& message, const UnicodeString* lhs, const UnicodeString* rhs) | |
233 | { | |
234 | UBool equ = (lhs == NULL) | |
235 | ? (rhs == NULL) | |
236 | : (rhs != NULL && lhs->operator==(*rhs)); | |
237 | ||
238 | UnicodeString temp; | |
239 | lrmsg(temp, message, lhs, rhs); | |
240 | ||
241 | if (equ) { | |
242 | logln(temp); | |
243 | } else { | |
244 | errln(temp); | |
245 | } | |
246 | } | |
247 | ||
248 | void | |
249 | ICUServiceTest::confirmEqual(const UnicodeString& message, const Locale* lhs, const Locale* rhs) | |
250 | { | |
251 | UBool equ = (lhs == NULL) | |
252 | ? (rhs == NULL) | |
253 | : (rhs != NULL && lhs->operator==(*rhs)); | |
254 | ||
255 | UnicodeString temp; | |
256 | lrmsg(temp, message, lhs, rhs); | |
257 | ||
258 | if (equ) { | |
259 | logln(temp); | |
260 | } else { | |
261 | errln(temp); | |
262 | } | |
263 | } | |
264 | #endif | |
265 | ||
266 | // use these for now | |
267 | void | |
268 | ICUServiceTest::confirmStringsEqual(const UnicodeString& message, const UnicodeString& lhs, const UnicodeString& rhs) | |
269 | { | |
270 | UBool equ = lhs == rhs; | |
271 | ||
272 | UnicodeString temp = message; | |
273 | temp.append(" lhs: "); | |
274 | temp.append(lhs); | |
275 | temp.append(" rhs: "); | |
276 | temp.append(rhs); | |
277 | ||
278 | if (equ) { | |
279 | logln(temp); | |
280 | } else { | |
281 | errln(temp); | |
282 | } | |
283 | } | |
284 | ||
285 | ||
286 | void | |
287 | ICUServiceTest::confirmIdentical(const UnicodeString& message, const UObject* lhs, const UObject *rhs) | |
288 | { | |
289 | UnicodeString temp; | |
290 | lrmsg(temp, message, lhs, rhs); | |
291 | if (lhs == rhs) { | |
292 | logln(temp); | |
293 | } else { | |
294 | errln(temp); | |
295 | } | |
296 | } | |
297 | ||
298 | void | |
299 | ICUServiceTest::confirmIdentical(const UnicodeString& message, int32_t lhs, int32_t rhs) | |
300 | { | |
301 | if (lhs == rhs) { | |
302 | logln(message + " lhs: " + lhs + " rhs: " + rhs); | |
303 | } else { | |
304 | errln(message + " lhs: " + lhs + " rhs: " + rhs); | |
305 | } | |
306 | } | |
307 | ||
308 | void | |
309 | ICUServiceTest::msgstr(const UnicodeString& message, UObject* obj, UBool err) | |
310 | { | |
311 | if (obj) { | |
374ca955 | 312 | UnicodeString* str = (UnicodeString*)obj; |
b75a7d8f A |
313 | logln(message + *str); |
314 | delete str; | |
315 | } else if (err) { | |
316 | errln("Error " + message + "string is NULL"); | |
317 | } | |
318 | } | |
319 | ||
320 | void | |
321 | ICUServiceTest::testAPI_One() | |
322 | { | |
323 | // create a service using locale keys, | |
324 | TestIntegerService service; | |
325 | ||
326 | // register an object with one locale, | |
327 | // search for an object with a more specific locale | |
328 | // should return the original object | |
374ca955 | 329 | UErrorCode status = U_ZERO_ERROR; |
b75a7d8f A |
330 | Integer* singleton0 = new Integer(0); |
331 | service.registerInstance(singleton0, "en_US", status); | |
332 | { | |
333 | UErrorCode status = U_ZERO_ERROR; | |
334 | Integer* result = (Integer*)service.get("en_US_FOO", status); | |
335 | confirmEqual("1) en_US_FOO -> en_US", result, singleton0); | |
336 | delete result; | |
337 | } | |
338 | ||
339 | // register a new object with the more specific locale | |
340 | // search for an object with that locale | |
341 | // should return the new object | |
342 | Integer* singleton1 = new Integer(1); | |
343 | service.registerInstance(singleton1, "en_US_FOO", status); | |
344 | { | |
345 | UErrorCode status = U_ZERO_ERROR; | |
346 | Integer* result = (Integer*)service.get("en_US_FOO", status); | |
347 | confirmEqual("2) en_US_FOO -> en_US_FOO", result, singleton1); | |
348 | delete result; | |
349 | } | |
350 | ||
351 | // search for an object that falls back to the first registered locale | |
352 | { | |
353 | UErrorCode status = U_ZERO_ERROR; | |
354 | Integer* result = (Integer*)service.get("en_US_BAR", status); | |
355 | confirmEqual("3) en_US_BAR -> en_US", result, singleton0); | |
356 | delete result; | |
357 | } | |
358 | ||
359 | // get a list of the factories, should be two | |
360 | { | |
361 | confirmIdentical("4) factory size", service.countFactories(), 2); | |
362 | } | |
363 | ||
364 | // register a new object with yet another locale | |
365 | Integer* singleton2 = new Integer(2); | |
366 | service.registerInstance(singleton2, "en", status); | |
367 | { | |
368 | confirmIdentical("5) factory size", service.countFactories(), 3); | |
369 | } | |
370 | ||
371 | // search for an object with the new locale | |
372 | // stack of factories is now en, en_US_FOO, en_US | |
373 | // search for en_US should still find en_US object | |
374 | { | |
375 | UErrorCode status = U_ZERO_ERROR; | |
376 | Integer* result = (Integer*)service.get("en_US_BAR", status); | |
377 | confirmEqual("6) en_US_BAR -> en_US", result, singleton0); | |
378 | delete result; | |
379 | } | |
380 | ||
381 | // register a new object with an old id, should hide earlier factory using this id, but leave it there | |
382 | Integer* singleton3 = new Integer(3); | |
383 | URegistryKey s3key = service.registerInstance(singleton3, "en_US", status); | |
384 | { | |
385 | confirmIdentical("9) factory size", service.countFactories(), 4); | |
386 | } | |
387 | ||
388 | // should get data from that new factory | |
389 | { | |
390 | UErrorCode status = U_ZERO_ERROR; | |
391 | Integer* result = (Integer*)service.get("en_US_BAR", status); | |
392 | confirmEqual("10) en_US_BAR -> (3)", result, singleton3); | |
393 | delete result; | |
394 | } | |
395 | ||
396 | // remove new factory | |
397 | // should have fewer factories again | |
398 | // singleton3 dead! | |
399 | { | |
400 | UErrorCode status = U_ZERO_ERROR; | |
401 | service.unregister(s3key, status); | |
402 | confirmIdentical("11) factory size", service.countFactories(), 3); | |
403 | } | |
404 | ||
405 | // should get original data again after remove factory | |
406 | { | |
407 | UErrorCode status = U_ZERO_ERROR; | |
408 | Integer* result = (Integer*)service.get("en_US_BAR", status); | |
409 | confirmEqual("12) en_US_BAR -> (3)", result, singleton0); | |
410 | delete result; | |
411 | } | |
412 | ||
413 | // shouldn't find unregistered ids | |
414 | { | |
415 | UErrorCode status = U_ZERO_ERROR; | |
416 | Integer* result = (Integer*)service.get("foo", status); | |
417 | confirmIdentical("13) foo -> null", result, NULL); | |
418 | delete result; | |
419 | } | |
420 | ||
421 | // should find non-canonical strings | |
422 | { | |
423 | UnicodeString resultID; | |
424 | UErrorCode status = U_ZERO_ERROR; | |
425 | Integer* result = (Integer*)service.get("EN_us_fOo", &resultID, status); | |
426 | confirmEqual("14a) find-non-canonical", result, singleton1); | |
427 | confirmStringsEqual("14b) find non-canonical", resultID, "en_US_FOO"); | |
428 | delete result; | |
429 | } | |
430 | ||
431 | // should be able to register non-canonical strings and get them canonicalized | |
432 | Integer* singleton4 = new Integer(4); | |
433 | service.registerInstance(singleton4, "eN_ca_dUde", status); | |
434 | { | |
435 | UnicodeString resultID; | |
436 | UErrorCode status = U_ZERO_ERROR; | |
437 | Integer* result = (Integer*)service.get("En_Ca_DuDe", &resultID, status); | |
438 | confirmEqual("15a) find-non-canonical", result, singleton4); | |
439 | confirmStringsEqual("15b) register non-canonical", resultID, "en_CA_DUDE"); | |
440 | delete result; | |
441 | } | |
442 | ||
443 | // should be able to register invisible factories, these will not | |
444 | // be visible by default, but if you know the secret password you | |
445 | // can still access these services... | |
446 | Integer* singleton5 = new Integer(5); | |
447 | service.registerInstance(singleton5, "en_US_BAR", FALSE, status); | |
448 | { | |
449 | UErrorCode status = U_ZERO_ERROR; | |
450 | Integer* result = (Integer*)service.get("en_US_BAR", status); | |
451 | confirmEqual("17) get invisible", result, singleton5); | |
452 | delete result; | |
453 | } | |
374ca955 | 454 | |
b75a7d8f A |
455 | // should not be able to locate invisible services |
456 | { | |
457 | UErrorCode status = U_ZERO_ERROR; | |
458 | UVector ids(uhash_deleteUnicodeString, uhash_compareUnicodeString, status); | |
459 | service.getVisibleIDs(ids, status); | |
460 | UnicodeString target = "en_US_BAR"; | |
461 | confirmBoolean("18) find invisible", !ids.contains(&target)); | |
462 | } | |
463 | ||
464 | // clear factory and caches | |
465 | service.reset(); | |
466 | confirmBoolean("19) is default", service.isDefault()); | |
467 | } | |
468 | ||
469 | /* | |
470 | ****************************************************************** | |
471 | */ | |
73c04bcf A |
472 | class TestStringSimpleKeyService : public ICUService { |
473 | public: | |
474 | ||
475 | virtual ICUServiceFactory* createSimpleFactory(UObject* obj, const UnicodeString& id, UBool visible, UErrorCode& status) | |
476 | { | |
477 | // We could put this type check into ICUService itself, but we'd still | |
478 | // have to implement cloneInstance. Otherwise we could just tell the service | |
479 | // what the object type is when we create it, and the default implementation | |
480 | // could handle everything for us. Phooey. | |
481 | if (obj && obj->getDynamicClassID() == UnicodeString::getStaticClassID()) { | |
482 | return ICUService::createSimpleFactory(obj, id, visible, status); | |
483 | } | |
484 | return NULL; | |
485 | } | |
486 | ||
487 | virtual UObject* cloneInstance(UObject* instance) const { | |
488 | return instance ? new UnicodeString(*(UnicodeString*)instance) : NULL; | |
489 | } | |
490 | }; | |
b75a7d8f A |
491 | |
492 | class TestStringService : public ICUService { | |
493 | public: | |
494 | ICUServiceKey* createKey(const UnicodeString* id, UErrorCode& status) const { | |
495 | return LocaleKey::createWithCanonicalFallback(id, NULL, status); // no fallback locale | |
496 | } | |
497 | ||
374ca955 | 498 | virtual ICUServiceFactory* createSimpleFactory(UObject* obj, const UnicodeString& id, UBool visible, UErrorCode& /* status */) |
b75a7d8f A |
499 | { |
500 | if (obj && obj->getDynamicClassID() == UnicodeString::getStaticClassID()) { | |
501 | return new SimpleFactory((UnicodeString*)obj, id, visible); | |
502 | } | |
503 | return NULL; | |
504 | } | |
505 | ||
506 | virtual UObject* cloneInstance(UObject* instance) const { | |
507 | return instance ? new UnicodeString(*(UnicodeString*)instance) : NULL; | |
508 | } | |
509 | }; | |
510 | ||
511 | // this creates a string for any id, but doesn't report anything | |
512 | class AnonymousStringFactory : public ICUServiceFactory | |
513 | { | |
514 | public: | |
374ca955 | 515 | virtual UObject* create(const ICUServiceKey& key, const ICUService* /* service */, UErrorCode& /* status */) const { |
b75a7d8f A |
516 | return new UnicodeString(key.getID()); |
517 | } | |
518 | ||
519 | virtual void updateVisibleIDs(Hashtable& /*result*/, UErrorCode& /*status*/) const { | |
520 | // do nothing | |
521 | } | |
522 | ||
523 | virtual UnicodeString& getDisplayName(const UnicodeString& /*id*/, const Locale& /*locale*/, UnicodeString& result) const { | |
524 | // do nothing | |
525 | return result; | |
526 | } | |
527 | ||
b75a7d8f A |
528 | static UClassID getStaticClassID() { |
529 | return (UClassID)&fgClassID; | |
530 | } | |
531 | ||
73c04bcf A |
532 | virtual UClassID getDynamicClassID() const { |
533 | return getStaticClassID(); | |
534 | } | |
535 | ||
b75a7d8f A |
536 | private: |
537 | static const char fgClassID; | |
538 | }; | |
539 | ||
540 | const char AnonymousStringFactory::fgClassID = '\0'; | |
541 | ||
542 | class TestMultipleKeyStringFactory : public ICUServiceFactory { | |
543 | UErrorCode _status; | |
544 | UVector _ids; | |
545 | UnicodeString _factoryID; | |
546 | ||
547 | public: | |
548 | TestMultipleKeyStringFactory(const UnicodeString ids[], int32_t count, const UnicodeString& factoryID) | |
549 | : _status(U_ZERO_ERROR) | |
550 | , _ids(uhash_deleteUnicodeString, uhash_compareUnicodeString, count, _status) | |
551 | , _factoryID(factoryID + ": ") | |
552 | { | |
553 | for (int i = 0; i < count; ++i) { | |
554 | _ids.addElement(new UnicodeString(ids[i]), _status); | |
555 | } | |
556 | } | |
557 | ||
558 | ~TestMultipleKeyStringFactory() { | |
559 | } | |
560 | ||
374ca955 A |
561 | UObject* create(const ICUServiceKey& key, const ICUService* /* service */, UErrorCode& status) const { |
562 | if (U_FAILURE(status)) { | |
563 | return NULL; | |
564 | } | |
b75a7d8f A |
565 | UnicodeString temp; |
566 | key.currentID(temp); | |
374ca955 A |
567 | if (U_SUCCESS(_status)) { |
568 | if (_ids.contains(&temp)) { | |
569 | return new UnicodeString(_factoryID + temp); | |
b75a7d8f | 570 | } |
374ca955 A |
571 | } else { |
572 | status = _status; | |
573 | } | |
b75a7d8f A |
574 | return NULL; |
575 | } | |
576 | ||
577 | void updateVisibleIDs(Hashtable& result, UErrorCode& status) const { | |
578 | if (U_SUCCESS(_status)) { | |
579 | for (int32_t i = 0; i < _ids.size(); ++i) { | |
580 | result.put(*(UnicodeString*)_ids[i], (void*)this, status); | |
581 | } | |
582 | } | |
583 | } | |
584 | ||
585 | UnicodeString& getDisplayName(const UnicodeString& id, const Locale& locale, UnicodeString& result) const { | |
586 | if (U_SUCCESS(_status) && _ids.contains((void*)&id)) { | |
587 | char buffer[128]; | |
588 | UErrorCode status = U_ZERO_ERROR; | |
589 | int32_t len = id.extract(buffer, sizeof(buffer), NULL, status); | |
590 | if (U_SUCCESS(status)) { | |
591 | if (len == sizeof(buffer)) { | |
592 | --len; | |
593 | } | |
594 | buffer[len] = 0; | |
595 | Locale loc = Locale::createFromName(buffer); | |
596 | loc.getDisplayName(locale, result); | |
597 | return result; | |
598 | } | |
599 | } | |
600 | result.setToBogus(); // shouldn't happen | |
601 | return result; | |
602 | } | |
603 | ||
b75a7d8f A |
604 | static UClassID getStaticClassID() { |
605 | return (UClassID)&fgClassID; | |
606 | } | |
607 | ||
73c04bcf A |
608 | virtual UClassID getDynamicClassID() const { |
609 | return getStaticClassID(); | |
610 | } | |
611 | ||
b75a7d8f A |
612 | private: |
613 | static const char fgClassID; | |
614 | }; | |
615 | ||
616 | const char TestMultipleKeyStringFactory::fgClassID = '\0'; | |
617 | ||
618 | void | |
619 | ICUServiceTest::testAPI_Two() | |
620 | { | |
374ca955 | 621 | UErrorCode status = U_ZERO_ERROR; |
b75a7d8f A |
622 | TestStringService service; |
623 | service.registerFactory(new AnonymousStringFactory(), status); | |
624 | ||
625 | // anonymous factory will still handle the id | |
626 | { | |
627 | UErrorCode status = U_ZERO_ERROR; | |
628 | const UnicodeString en_US = "en_US"; | |
629 | UnicodeString* result = (UnicodeString*)service.get(en_US, status); | |
630 | confirmEqual("21) locale", result, &en_US); | |
631 | delete result; | |
632 | } | |
633 | ||
634 | // still normalizes id | |
635 | { | |
636 | UErrorCode status = U_ZERO_ERROR; | |
637 | const UnicodeString en_US_BAR = "en_US_BAR"; | |
638 | UnicodeString resultID; | |
639 | UnicodeString* result = (UnicodeString*)service.get("EN_us_bar", &resultID, status); | |
640 | confirmEqual("22) locale", &resultID, &en_US_BAR); | |
641 | delete result; | |
642 | } | |
643 | ||
644 | // we can override for particular ids | |
645 | UnicodeString* singleton0 = new UnicodeString("Zero"); | |
646 | service.registerInstance(singleton0, "en_US_BAR", status); | |
647 | { | |
648 | UErrorCode status = U_ZERO_ERROR; | |
649 | UnicodeString* result = (UnicodeString*)service.get("en_US_BAR", status); | |
650 | confirmEqual("23) override super", result, singleton0); | |
651 | delete result; | |
652 | } | |
653 | ||
654 | // empty service should not recognize anything | |
655 | service.reset(); | |
656 | { | |
657 | UErrorCode status = U_ZERO_ERROR; | |
658 | UnicodeString* result = (UnicodeString*)service.get("en_US", status); | |
659 | confirmIdentical("24) empty", result, NULL); | |
660 | } | |
661 | ||
662 | // create a custom multiple key factory | |
663 | { | |
664 | UnicodeString xids[] = { | |
665 | "en_US_VALLEY_GIRL", | |
666 | "en_US_VALLEY_BOY", | |
667 | "en_US_SURFER_GAL", | |
668 | "en_US_SURFER_DUDE" | |
669 | }; | |
670 | int32_t count = sizeof(xids)/sizeof(UnicodeString); | |
671 | ||
672 | ICUServiceFactory* f = new TestMultipleKeyStringFactory(xids, count, "Later"); | |
673 | service.registerFactory(f, status); | |
674 | } | |
675 | ||
676 | // iterate over the visual ids returned by the multiple factory | |
677 | { | |
678 | UErrorCode status = U_ZERO_ERROR; | |
679 | UVector ids(uhash_deleteUnicodeString, uhash_compareUnicodeString, 0, status); | |
680 | service.getVisibleIDs(ids, status); | |
681 | for (int i = 0; i < ids.size(); ++i) { | |
682 | const UnicodeString* id = (const UnicodeString*)ids[i]; | |
683 | UnicodeString* result = (UnicodeString*)service.get(*id, status); | |
684 | if (result) { | |
685 | logln(" " + *id + " --> " + *result); | |
686 | delete result; | |
687 | } else { | |
688 | errln("could not find " + *id); | |
689 | } | |
690 | } | |
691 | // four visible ids | |
692 | confirmIdentical("25) visible ids", ids.size(), 4); | |
693 | } | |
694 | ||
695 | // iterate over the display names | |
696 | { | |
697 | UErrorCode status = U_ZERO_ERROR; | |
374ca955 | 698 | UVector names(userv_deleteStringPair, NULL, status); |
73c04bcf | 699 | service.getDisplayNames(names, status); |
b75a7d8f A |
700 | for (int i = 0; i < names.size(); ++i) { |
701 | const StringPair* pair = (const StringPair*)names[i]; | |
702 | logln(" " + pair->displayName + " --> " + pair->id); | |
703 | } | |
704 | confirmIdentical("26) display names", names.size(), 4); | |
705 | } | |
706 | ||
707 | // no valid display name | |
708 | { | |
709 | UnicodeString name; | |
710 | service.getDisplayName("en_US_VALLEY_GEEK", name); | |
711 | confirmBoolean("27) get display name", name.isBogus()); | |
712 | } | |
713 | ||
714 | { | |
715 | UnicodeString name; | |
716 | service.getDisplayName("en_US_SURFER_DUDE", name, Locale::getEnglish()); | |
717 | confirmStringsEqual("28) get display name", name, "English (United States, SURFER_DUDE)"); | |
718 | } | |
719 | ||
720 | // register another multiple factory | |
721 | { | |
722 | UnicodeString xids[] = { | |
723 | "en_US_SURFER", | |
724 | "en_US_SURFER_GAL", | |
725 | "en_US_SILICON", | |
726 | "en_US_SILICON_GEEK", | |
727 | }; | |
728 | int32_t count = sizeof(xids)/sizeof(UnicodeString); | |
729 | ||
730 | ICUServiceFactory* f = new TestMultipleKeyStringFactory(xids, count, "Rad dude"); | |
731 | service.registerFactory(f, status); | |
732 | } | |
733 | ||
734 | // this time, we have seven display names | |
735 | // Rad dude's surfer gal 'replaces' Later's surfer gal | |
736 | { | |
737 | UErrorCode status = U_ZERO_ERROR; | |
374ca955 | 738 | UVector names(userv_deleteStringPair, NULL, status); |
b75a7d8f A |
739 | service.getDisplayNames(names, Locale("es"), status); |
740 | for (int i = 0; i < names.size(); ++i) { | |
741 | const StringPair* pair = (const StringPair*)names[i]; | |
742 | logln(" " + pair->displayName + " --> " + pair->id); | |
743 | } | |
744 | confirmIdentical("26) display names", names.size(), 7); | |
745 | } | |
746 | ||
747 | // we should get the display name corresponding to the actual id | |
748 | // returned by the id we used. | |
749 | { | |
750 | UErrorCode status = U_ZERO_ERROR; | |
751 | UnicodeString actualID; | |
752 | UnicodeString id = "en_us_surfer_gal"; | |
753 | UnicodeString* gal = (UnicodeString*)service.get(id, &actualID, status); | |
754 | if (gal != NULL) { | |
755 | UnicodeString displayName; | |
756 | logln("actual id: " + actualID); | |
757 | service.getDisplayName(actualID, displayName, Locale::getEnglish()); | |
758 | logln("found actual: " + *gal + " with display name: " + displayName); | |
759 | confirmBoolean("30) found display name for actual", !displayName.isBogus()); | |
760 | ||
761 | service.getDisplayName(id, displayName, Locale::getEnglish()); | |
762 | logln("found actual: " + *gal + " with display name: " + displayName); | |
763 | confirmBoolean("31) found display name for query", displayName.isBogus()); | |
764 | ||
765 | delete gal; | |
766 | } else { | |
767 | errln("30) service could not find entry for " + id); | |
768 | } | |
769 | } | |
770 | ||
771 | // this should be handled by the 'dude' factory, since it overrides en_US_SURFER. | |
772 | { | |
773 | UErrorCode status = U_ZERO_ERROR; | |
774 | UnicodeString actualID; | |
775 | UnicodeString id = "en_US_SURFER_BOZO"; | |
776 | UnicodeString* bozo = (UnicodeString*)service.get(id, &actualID, status); | |
777 | if (bozo != NULL) { | |
778 | UnicodeString displayName; | |
779 | service.getDisplayName(actualID, displayName, Locale::getEnglish()); | |
780 | logln("found actual: " + *bozo + " with display name: " + displayName); | |
781 | confirmBoolean("32) found display name for actual", !displayName.isBogus()); | |
782 | ||
783 | service.getDisplayName(id, displayName, Locale::getEnglish()); | |
784 | logln("found actual: " + *bozo + " with display name: " + displayName); | |
785 | confirmBoolean("33) found display name for query", displayName.isBogus()); | |
786 | ||
787 | delete bozo; | |
788 | } else { | |
789 | errln("32) service could not find entry for " + id); | |
790 | } | |
791 | } | |
792 | ||
793 | // certainly not default... | |
794 | { | |
795 | confirmBoolean("34) is default ", !service.isDefault()); | |
796 | } | |
797 | ||
798 | { | |
799 | UErrorCode status = U_ZERO_ERROR; | |
800 | UVector ids(uhash_deleteUnicodeString, uhash_compareUnicodeString, 0, status); | |
801 | service.getVisibleIDs(ids, status); | |
802 | for (int i = 0; i < ids.size(); ++i) { | |
803 | const UnicodeString* id = (const UnicodeString*)ids[i]; | |
804 | msgstr(*id + "? ", service.get(*id, status)); | |
805 | } | |
806 | ||
807 | logstr("valleygirl? ", service.get("en_US_VALLEY_GIRL", status)); | |
808 | logstr("valleyboy? ", service.get("en_US_VALLEY_BOY", status)); | |
809 | logstr("valleydude? ", service.get("en_US_VALLEY_DUDE", status)); | |
810 | logstr("surfergirl? ", service.get("en_US_SURFER_GIRL", status)); | |
811 | } | |
812 | } | |
813 | ||
814 | ||
815 | class CalifornioLanguageFactory : public ICUResourceBundleFactory | |
816 | { | |
817 | public: | |
818 | static const char* californio; // = "en_US_CA"; | |
819 | static const char* valley; // = californio ## "_VALLEY"; | |
820 | static const char* surfer; // = californio ## "_SURFER"; | |
821 | static const char* geek; // = californio ## "_GEEK"; | |
822 | static Hashtable* supportedIDs; // = NULL; | |
823 | ||
824 | static void cleanup(void) { | |
825 | delete supportedIDs; | |
826 | supportedIDs = NULL; | |
827 | } | |
828 | ||
829 | const Hashtable* getSupportedIDs(UErrorCode& status) const | |
830 | { | |
831 | if (supportedIDs == NULL) { | |
832 | Hashtable* table = new Hashtable(); | |
833 | table->put(UnicodeString(californio), (void*)table, status); | |
834 | table->put(UnicodeString(valley), (void*)table, status); | |
835 | table->put(UnicodeString(surfer), (void*)table, status); | |
836 | table->put(UnicodeString(geek), (void*)table, status); | |
837 | ||
838 | // not necessarily atomic, but this is a test... | |
839 | supportedIDs = table; | |
840 | } | |
841 | return supportedIDs; | |
842 | } | |
843 | ||
844 | UnicodeString& getDisplayName(const UnicodeString& id, const Locale& locale, UnicodeString& result) const | |
845 | { | |
846 | UnicodeString prefix = ""; | |
847 | UnicodeString suffix = ""; | |
848 | UnicodeString ls = locale.getName(); | |
849 | if (LocaleUtility::isFallbackOf(californio, ls)) { | |
850 | if (!ls.caseCompare(valley, 0)) { | |
851 | prefix = "Like, you know, it's so totally "; | |
852 | } else if (!ls.caseCompare(surfer, 0)) { | |
853 | prefix = "Dude, it's "; | |
854 | } else if (!ls.caseCompare(geek, 0)) { | |
855 | prefix = "I'd estimate it is approximately "; | |
856 | } else { | |
857 | prefix = "Huh? Maybe "; | |
858 | } | |
859 | } | |
860 | if (LocaleUtility::isFallbackOf(californio, id)) { | |
861 | if (!id.caseCompare(valley, 0)) { | |
862 | suffix = "like the Valley, you know? Let's go to the mall!"; | |
863 | } else if (!id.caseCompare(surfer, 0)) { | |
864 | suffix = "time to hit those gnarly waves, Dude!!!"; | |
865 | } else if (!id.caseCompare(geek, 0)) { | |
866 | suffix = "all systems go. T-Minus 9, 8, 7..."; | |
867 | } else { | |
868 | suffix = "No Habla Englais"; | |
869 | } | |
870 | } else { | |
871 | suffix = ICUResourceBundleFactory::getDisplayName(id, locale, result); | |
872 | } | |
873 | ||
874 | result = prefix + suffix; | |
875 | return result; | |
876 | } | |
877 | }; | |
878 | ||
879 | const char* CalifornioLanguageFactory::californio = "en_US_CA"; | |
880 | const char* CalifornioLanguageFactory::valley = "en_US_CA_VALLEY"; | |
881 | const char* CalifornioLanguageFactory::surfer = "en_US_CA_SURFER"; | |
882 | const char* CalifornioLanguageFactory::geek = "en_US_CA_GEEK"; | |
883 | Hashtable* CalifornioLanguageFactory::supportedIDs = NULL; | |
884 | ||
885 | void | |
886 | ICUServiceTest::testRBF() | |
887 | { | |
888 | // resource bundle factory. | |
374ca955 | 889 | UErrorCode status = U_ZERO_ERROR; |
b75a7d8f A |
890 | TestStringService service; |
891 | service.registerFactory(new ICUResourceBundleFactory(), status); | |
892 | ||
893 | // list all of the resources | |
894 | { | |
895 | UErrorCode status = U_ZERO_ERROR; | |
896 | UVector ids(uhash_deleteUnicodeString, uhash_compareUnicodeString, 0, status); | |
897 | service.getVisibleIDs(ids, status); | |
898 | logln("all visible ids:"); | |
899 | for (int i = 0; i < ids.size(); ++i) { | |
900 | const UnicodeString* id = (const UnicodeString*)ids[i]; | |
901 | logln(*id); | |
902 | } | |
903 | } | |
904 | ||
905 | // get all the display names of these resources | |
906 | // this should be fast since the display names were cached. | |
907 | { | |
908 | UErrorCode status = U_ZERO_ERROR; | |
374ca955 | 909 | UVector names(userv_deleteStringPair, NULL, status); |
b75a7d8f A |
910 | service.getDisplayNames(names, Locale::getGermany(), status); |
911 | logln("service display names for de_DE"); | |
912 | for (int i = 0; i < names.size(); ++i) { | |
913 | const StringPair* pair = (const StringPair*)names[i]; | |
914 | logln(" " + pair->displayName + " --> " + pair->id); | |
915 | } | |
916 | } | |
917 | ||
918 | service.registerFactory(new CalifornioLanguageFactory(), status); | |
919 | ||
920 | // get all the display names of these resources | |
921 | { | |
922 | logln("californio language factory:"); | |
923 | const char* idNames[] = { | |
924 | CalifornioLanguageFactory::californio, | |
925 | CalifornioLanguageFactory::valley, | |
926 | CalifornioLanguageFactory::surfer, | |
927 | CalifornioLanguageFactory::geek, | |
928 | }; | |
929 | int32_t count = sizeof(idNames)/sizeof(idNames[0]); | |
930 | ||
931 | for (int i = 0; i < count; ++i) { | |
932 | logln(UnicodeString("\n --- ") + idNames[i] + " ---"); | |
933 | { | |
934 | UErrorCode status = U_ZERO_ERROR; | |
374ca955 | 935 | UVector names(userv_deleteStringPair, NULL, status); |
b75a7d8f A |
936 | service.getDisplayNames(names, idNames[i], status); |
937 | for (int i = 0; i < names.size(); ++i) { | |
938 | const StringPair* pair = (const StringPair*)names[i]; | |
939 | logln(" " + pair->displayName + " --> " + pair->id); | |
940 | } | |
941 | } | |
942 | } | |
943 | } | |
944 | CalifornioLanguageFactory::cleanup(); | |
945 | } | |
946 | ||
947 | class SimpleListener : public ServiceListener { | |
948 | ICUServiceTest* _test; | |
949 | int32_t _n; | |
950 | UnicodeString _name; | |
951 | ||
952 | public: | |
953 | SimpleListener(ICUServiceTest* test, const UnicodeString& name) : _test(test), _n(0), _name(name) {} | |
954 | ||
955 | virtual void serviceChanged(const ICUService& service) const { | |
956 | UnicodeString serviceName = "listener "; | |
957 | serviceName.append(_name); | |
958 | serviceName.append(" n++"); | |
959 | serviceName.append(" service changed: " ); | |
960 | service.getName(serviceName); | |
961 | _test->logln(serviceName); | |
962 | } | |
963 | }; | |
964 | ||
965 | void | |
966 | ICUServiceTest::testNotification() | |
967 | { | |
968 | SimpleListener one(this, "one"); | |
969 | SimpleListener two(this, "two"); | |
970 | { | |
971 | UErrorCode status = U_ZERO_ERROR; | |
972 | ||
973 | logln("simple registration notification"); | |
974 | TestStringService ls; | |
975 | ls.addListener(&one, status); | |
976 | ls.addListener(&two, status); | |
977 | ||
978 | logln("registering foo... "); | |
979 | ls.registerInstance(new UnicodeString("Foo"), "en_FOO", status); | |
980 | logln("registering bar... "); | |
981 | ls.registerInstance(new UnicodeString("Bar"), "en_BAR", status); | |
982 | logln("getting foo..."); | |
983 | UnicodeString* result = (UnicodeString*)ls.get("en_FOO", status); | |
984 | logln(*result); | |
985 | delete result; | |
986 | ||
987 | logln("removing listener 2..."); | |
988 | ls.removeListener(&two, status); | |
989 | logln("registering baz..."); | |
990 | ls.registerInstance(new UnicodeString("Baz"), "en_BAZ", status); | |
991 | logln("removing listener 1"); | |
992 | ls.removeListener(&one, status); | |
993 | logln("registering burp..."); | |
994 | ls.registerInstance(new UnicodeString("Burp"), "en_BURP", status); | |
995 | ||
996 | // should only get one notification even if register multiple times | |
997 | logln("... trying multiple registration"); | |
998 | ls.addListener(&one, status); | |
999 | ls.addListener(&one, status); | |
1000 | ls.addListener(&one, status); | |
1001 | ls.addListener(&two, status); | |
1002 | ls.registerInstance(new UnicodeString("Foo"), "en_FOO", status); | |
1003 | logln("... registered foo"); | |
1004 | } | |
1005 | #if 0 | |
1006 | // same thread, so we can't callback within notification, unlike Java | |
1007 | ServiceListener l3 = new ServiceListener() { | |
1008 | private int n; | |
1009 | public void serviceChanged(ICUService s) { | |
1010 | logln("listener 3 report " + n++ + " service changed..."); | |
1011 | if (s.get("en_BOINK") == null) { // don't recurse on ourselves!!! | |
1012 | logln("registering boink..."); | |
1013 | s.registerInstance("boink", "en_BOINK"); | |
1014 | } | |
1015 | } | |
1016 | }; | |
1017 | ls.addListener(l3); | |
1018 | logln("registering boo..."); | |
1019 | ls.registerInstance("Boo", "en_BOO"); | |
1020 | #endif | |
1021 | ||
1022 | logln("...done"); | |
1023 | } | |
1024 | ||
1025 | class TestStringLocaleService : public ICULocaleService { | |
1026 | public: | |
1027 | virtual UObject* cloneInstance(UObject* instance) const { | |
1028 | return instance ? new UnicodeString(*(UnicodeString*)instance) : NULL; | |
1029 | } | |
1030 | }; | |
1031 | ||
1032 | void ICUServiceTest::testLocale() { | |
374ca955 | 1033 | UErrorCode status = U_ZERO_ERROR; |
b75a7d8f A |
1034 | TestStringLocaleService service; |
1035 | ||
1036 | UnicodeString* root = new UnicodeString("root"); | |
1037 | UnicodeString* german = new UnicodeString("german"); | |
1038 | UnicodeString* germany = new UnicodeString("german_Germany"); | |
1039 | UnicodeString* japanese = new UnicodeString("japanese"); | |
1040 | UnicodeString* japan = new UnicodeString("japanese_Japan"); | |
1041 | ||
1042 | service.registerInstance(root, "", status); | |
1043 | service.registerInstance(german, "de", status); | |
1044 | service.registerInstance(germany, Locale::getGermany(), status); | |
73c04bcf | 1045 | service.registerInstance(japanese, (UnicodeString)"ja", TRUE, status); |
b75a7d8f A |
1046 | service.registerInstance(japan, Locale::getJapan(), status); |
1047 | ||
1048 | { | |
1049 | UErrorCode status = U_ZERO_ERROR; | |
1050 | UnicodeString* target = (UnicodeString*)service.get("de_US", status); | |
1051 | confirmEqual("test de_US", german, target); | |
1052 | delete target; | |
1053 | } | |
1054 | ||
1055 | { | |
1056 | UErrorCode status = U_ZERO_ERROR; | |
1057 | UnicodeString* target = (UnicodeString*)service.get("de_US", LocaleKey::KIND_ANY, status); | |
1058 | confirmEqual("test de_US 2", german, target); | |
1059 | delete target; | |
1060 | } | |
1061 | ||
1062 | { | |
1063 | UErrorCode status = U_ZERO_ERROR; | |
1064 | UnicodeString* target = (UnicodeString*)service.get("de_US", 1234, status); | |
1065 | confirmEqual("test de_US 3", german, target); | |
1066 | delete target; | |
1067 | } | |
1068 | ||
1069 | { | |
1070 | UErrorCode status = U_ZERO_ERROR; | |
1071 | Locale actualReturn; | |
1072 | UnicodeString* target = (UnicodeString*)service.get("de_US", &actualReturn, status); | |
1073 | confirmEqual("test de_US 5", german, target); | |
1074 | confirmEqual("test de_US 6", &actualReturn, &Locale::getGerman()); | |
1075 | delete target; | |
1076 | } | |
1077 | ||
1078 | { | |
1079 | UErrorCode status = U_ZERO_ERROR; | |
1080 | Locale actualReturn; | |
1081 | UnicodeString* target = (UnicodeString*)service.get("de_US", LocaleKey::KIND_ANY, &actualReturn, status); | |
1082 | confirmEqual("test de_US 7", &actualReturn, &Locale::getGerman()); | |
1083 | delete target; | |
1084 | } | |
1085 | ||
1086 | { | |
1087 | UErrorCode status = U_ZERO_ERROR; | |
1088 | Locale actualReturn; | |
1089 | UnicodeString* target = (UnicodeString*)service.get("de_US", 1234, &actualReturn, status); | |
1090 | confirmEqual("test de_US 8", german, target); | |
1091 | confirmEqual("test de_US 9", &actualReturn, &Locale::getGerman()); | |
1092 | delete target; | |
1093 | } | |
1094 | ||
1095 | UnicodeString* one = new UnicodeString("one/de_US"); | |
1096 | UnicodeString* two = new UnicodeString("two/de_US"); | |
1097 | ||
1098 | service.registerInstance(one, Locale("de_US"), 1, status); | |
1099 | service.registerInstance(two, Locale("de_US"), 2, status); | |
1100 | ||
1101 | { | |
1102 | UErrorCode status = U_ZERO_ERROR; | |
1103 | UnicodeString* target = (UnicodeString*)service.get("de_US", 1, status); | |
1104 | confirmEqual("test de_US kind 1", one, target); | |
1105 | delete target; | |
1106 | } | |
1107 | ||
1108 | { | |
1109 | UErrorCode status = U_ZERO_ERROR; | |
1110 | UnicodeString* target = (UnicodeString*)service.get("de_US", 2, status); | |
1111 | confirmEqual("test de_US kind 2", two, target); | |
1112 | delete target; | |
1113 | } | |
1114 | ||
1115 | { | |
1116 | UErrorCode status = U_ZERO_ERROR; | |
1117 | UnicodeString* target = (UnicodeString*)service.get("de_US", status); | |
1118 | confirmEqual("test de_US kind 3", german, target); | |
1119 | delete target; | |
1120 | } | |
1121 | ||
1122 | { | |
374ca955 | 1123 | UErrorCode status = U_ZERO_ERROR; |
b75a7d8f A |
1124 | UnicodeString english = "en"; |
1125 | Locale localeResult; | |
1126 | UnicodeString result; | |
1127 | LocaleKey* lkey = LocaleKey::createWithCanonicalFallback(&english, NULL, 1234, status); | |
1128 | logln("lkey prefix: " + lkey->prefix(result)); | |
1129 | result.remove(); | |
1130 | logln("lkey descriptor: " + lkey->currentDescriptor(result)); | |
1131 | result.remove(); | |
1132 | logln(UnicodeString("lkey current locale: ") + lkey->currentLocale(localeResult).getName()); | |
1133 | result.remove(); | |
1134 | ||
1135 | lkey->fallback(); | |
1136 | logln("lkey descriptor 2: " + lkey->currentDescriptor(result)); | |
1137 | result.remove(); | |
1138 | ||
1139 | lkey->fallback(); | |
1140 | logln("lkey descriptor 3: " + lkey->currentDescriptor(result)); | |
1141 | result.remove(); | |
1142 | delete lkey; // tentatively weiv | |
1143 | } | |
1144 | ||
1145 | { | |
1146 | UErrorCode status = U_ZERO_ERROR; | |
1147 | UnicodeString* target = (UnicodeString*)service.get("za_PPP", status); | |
1148 | confirmEqual("test zappp", root, target); | |
1149 | delete target; | |
1150 | } | |
1151 | ||
1152 | Locale loc = Locale::getDefault(); | |
1153 | Locale::setDefault(Locale::getJapanese(), status); | |
1154 | { | |
1155 | UErrorCode status = U_ZERO_ERROR; | |
1156 | UnicodeString* target = (UnicodeString*)service.get("za_PPP", status); | |
1157 | confirmEqual("test with ja locale", japanese, target); | |
1158 | delete target; | |
1159 | } | |
1160 | ||
1161 | { | |
1162 | UErrorCode status = U_ZERO_ERROR; | |
1163 | UVector ids(uhash_deleteUnicodeString, uhash_compareUnicodeString, 0, status); | |
1164 | service.getVisibleIDs(ids, status); | |
1165 | logln("all visible ids:"); | |
1166 | for (int i = 0; i < ids.size(); ++i) { | |
1167 | const UnicodeString* id = (const UnicodeString*)ids[i]; | |
1168 | logln(*id); | |
1169 | } | |
1170 | } | |
1171 | ||
1172 | Locale::setDefault(loc, status); | |
1173 | { | |
1174 | UErrorCode status = U_ZERO_ERROR; | |
1175 | UVector ids(uhash_deleteUnicodeString, uhash_compareUnicodeString, 0, status); | |
1176 | service.getVisibleIDs(ids, status); | |
1177 | logln("all visible ids:"); | |
1178 | for (int i = 0; i < ids.size(); ++i) { | |
1179 | const UnicodeString* id = (const UnicodeString*)ids[i]; | |
1180 | logln(*id); | |
1181 | } | |
1182 | } | |
1183 | ||
1184 | { | |
1185 | UErrorCode status = U_ZERO_ERROR; | |
1186 | UnicodeString* target = (UnicodeString*)service.get("za_PPP", status); | |
1187 | confirmEqual("test with en locale", root, target); | |
1188 | delete target; | |
1189 | } | |
1190 | ||
1191 | { | |
1192 | UErrorCode status = U_ZERO_ERROR; | |
1193 | StringEnumeration* locales = service.getAvailableLocales(); | |
1194 | if (locales) { | |
374ca955 | 1195 | confirmIdentical("test available locales", locales->count(status), 6); |
b75a7d8f A |
1196 | logln("locales: "); |
1197 | { | |
1198 | const char* p; | |
1199 | while ((p = locales->next(NULL, status))) { | |
1200 | logln(p); | |
1201 | } | |
1202 | } | |
1203 | logln(" "); | |
1204 | delete locales; | |
1205 | } else { | |
1206 | errln("could not create available locales"); | |
1207 | } | |
1208 | } | |
1209 | } | |
1210 | ||
1211 | class WrapFactory : public ICUServiceFactory { | |
1212 | public: | |
1213 | static const UnicodeString& getGreetingID() { | |
1214 | if (greetingID == NULL) { | |
374ca955 | 1215 | greetingID = new UnicodeString("greeting"); |
b75a7d8f A |
1216 | } |
1217 | return *greetingID; | |
1218 | } | |
1219 | ||
1220 | static void cleanup() { | |
1221 | delete greetingID; | |
1222 | greetingID = NULL; | |
1223 | } | |
1224 | ||
1225 | UObject* create(const ICUServiceKey& key, const ICUService* service, UErrorCode& status) const { | |
1226 | if (U_SUCCESS(status)) { | |
1227 | UnicodeString temp; | |
1228 | if (key.currentID(temp).compare(getGreetingID()) == 0) { | |
1229 | UnicodeString* previous = (UnicodeString*)service->getKey((ICUServiceKey&)key, NULL, this, status); | |
1230 | if (previous) { | |
1231 | previous->insert(0, "A different greeting: \""); | |
1232 | previous->append("\""); | |
1233 | return previous; | |
1234 | } | |
1235 | } | |
1236 | } | |
1237 | return NULL; | |
1238 | } | |
1239 | ||
1240 | void updateVisibleIDs(Hashtable& result, UErrorCode& status) const { | |
1241 | if (U_SUCCESS(status)) { | |
1242 | result.put("greeting", (void*)this, status); | |
1243 | } | |
1244 | } | |
1245 | ||
374ca955 | 1246 | UnicodeString& getDisplayName(const UnicodeString& id, const Locale& /* locale */, UnicodeString& result) const { |
b75a7d8f A |
1247 | result.append("wrap '"); |
1248 | result.append(id); | |
1249 | result.append("'"); | |
1250 | return result; | |
1251 | } | |
1252 | ||
1253 | /** | |
1254 | * UObject boilerplate. | |
1255 | */ | |
b75a7d8f A |
1256 | static UClassID getStaticClassID() { |
1257 | return (UClassID)&fgClassID; | |
1258 | } | |
1259 | ||
73c04bcf A |
1260 | virtual UClassID getDynamicClassID() const { |
1261 | return getStaticClassID(); | |
1262 | } | |
1263 | ||
b75a7d8f A |
1264 | private: |
1265 | static const char fgClassID; | |
1266 | static UnicodeString* greetingID; | |
1267 | }; | |
1268 | ||
1269 | UnicodeString* WrapFactory::greetingID = NULL; | |
1270 | const char WrapFactory::fgClassID = '\0'; | |
1271 | ||
1272 | void | |
1273 | ICUServiceTest::testWrapFactory() | |
1274 | { | |
1275 | UnicodeString* greeting = new UnicodeString("Hello There"); | |
1276 | UnicodeString greetingID = "greeting"; | |
374ca955 | 1277 | UErrorCode status = U_ZERO_ERROR; |
b75a7d8f A |
1278 | TestStringService service; |
1279 | service.registerInstance(greeting, greetingID, status); | |
1280 | ||
1281 | { | |
1282 | UErrorCode status = U_ZERO_ERROR; | |
1283 | UnicodeString* result = (UnicodeString*)service.get(greetingID, status); | |
1284 | if (result) { | |
1285 | logln("test one: " + *result); | |
1286 | delete result; | |
1287 | } | |
1288 | } | |
1289 | ||
1290 | service.registerFactory(new WrapFactory(), status); | |
1291 | { | |
1292 | UErrorCode status = U_ZERO_ERROR; | |
1293 | UnicodeString* result = (UnicodeString*)service.get(greetingID, status); | |
1294 | UnicodeString target = "A different greeting: \"Hello There\""; | |
1295 | confirmEqual("wrap test: ", result, &target); | |
1296 | delete result; | |
1297 | } | |
1298 | ||
1299 | WrapFactory::cleanup(); | |
1300 | } | |
1301 | ||
1302 | // misc coverage tests | |
1303 | void ICUServiceTest::testCoverage() | |
1304 | { | |
1305 | // ICUServiceKey | |
1306 | { | |
1307 | UnicodeString temp; | |
1308 | ICUServiceKey key("foobar"); | |
1309 | logln("ID: " + key.getID()); | |
1310 | logln("canonicalID: " + key.canonicalID(temp)); | |
1311 | logln("currentID: " + key.currentID(temp.remove())); | |
1312 | logln("has fallback: " + UnicodeString(key.fallback() ? "true" : "false")); | |
1313 | ||
1314 | if (key.getDynamicClassID() != ICUServiceKey::getStaticClassID()) { | |
1315 | errln("service key rtt failed."); | |
1316 | } | |
1317 | } | |
1318 | ||
1319 | // SimpleFactory | |
1320 | { | |
1321 | UErrorCode status = U_ZERO_ERROR; | |
1322 | ||
1323 | UnicodeString* obj = new UnicodeString("An Object"); | |
1324 | SimpleFactory* sf = new SimpleFactory(obj, "object"); | |
1325 | ||
1326 | UnicodeString temp; | |
1327 | logln(sf->getDisplayName("object", Locale::getDefault(), temp)); | |
1328 | ||
1329 | if (sf->getDynamicClassID() != SimpleFactory::getStaticClassID()) { | |
1330 | errln("simple factory rtti failed."); | |
1331 | } | |
1332 | ||
1333 | // ICUService | |
73c04bcf A |
1334 | { |
1335 | TestStringService service; | |
1336 | service.registerFactory(sf, status); | |
1337 | ||
1338 | { | |
1339 | UnicodeString* result = (UnicodeString*)service.get("object", status); | |
1340 | if (result) { | |
1341 | logln("object is: " + *result); | |
1342 | delete result; | |
1343 | } else { | |
1344 | errln("could not get object"); | |
1345 | } | |
1346 | } | |
1347 | } | |
1348 | } | |
1349 | ||
1350 | // ICUServiceKey | |
1351 | { | |
1352 | UErrorCode status = U_ZERO_ERROR; | |
1353 | UnicodeString* howdy = new UnicodeString("Howdy"); | |
1354 | ||
1355 | TestStringSimpleKeyService service; | |
1356 | service.registerInstance(howdy, "Greetings", status); | |
1357 | { | |
1358 | UnicodeString* result = (UnicodeString*)service.get("Greetings", status); | |
1359 | if (result) { | |
1360 | logln("object is: " + *result); | |
1361 | delete result; | |
1362 | } else { | |
1363 | errln("could not get object"); | |
1364 | } | |
1365 | } | |
1366 | ||
1367 | UVector ids(uhash_deleteUnicodeString, uhash_compareUnicodeString, status); | |
1368 | // yuck, this is awkward to use. All because we pass null in an overload. | |
1369 | // TODO: change this. | |
1370 | UnicodeString str("Greet"); | |
1371 | service.getVisibleIDs(ids, &str, status); | |
1372 | confirmIdentical("no fallback of greet", ids.size(), 0); | |
b75a7d8f A |
1373 | } |
1374 | ||
1375 | // ICULocaleService | |
1376 | ||
1377 | // LocaleKey | |
1378 | { | |
1379 | UnicodeString primary("en_US"); | |
1380 | UnicodeString fallback("ja_JP"); | |
1381 | UErrorCode status = U_ZERO_ERROR; | |
1382 | LocaleKey* key = LocaleKey::createWithCanonicalFallback(&primary, &fallback, status); | |
1383 | ||
1384 | if (key->getDynamicClassID() != LocaleKey::getStaticClassID()) { | |
1385 | errln("localekey rtti error"); | |
1386 | } | |
1387 | ||
1388 | if (!key->isFallbackOf("en_US_FOOBAR")) { | |
1389 | errln("localekey should be fallback for en_US_FOOBAR"); | |
1390 | } | |
1391 | if (!key->isFallbackOf("en_US")) { | |
1392 | errln("localekey should be fallback for en_US"); | |
1393 | } | |
1394 | if (key->isFallbackOf("en")) { | |
1395 | errln("localekey should not be fallback for en"); | |
1396 | } | |
1397 | ||
1398 | do { | |
1399 | Locale loc; | |
1400 | logln(UnicodeString("current locale: ") + key->currentLocale(loc).getName()); | |
1401 | logln(UnicodeString("canonical locale: ") + key->canonicalLocale(loc).getName()); | |
1402 | logln(UnicodeString("is fallback of en: ") + (key->isFallbackOf("en") ? "true" : " false")); | |
1403 | } while (key->fallback()); | |
1404 | delete key; | |
1405 | ||
1406 | // LocaleKeyFactory | |
1407 | key = LocaleKey::createWithCanonicalFallback(&primary, &fallback, status); | |
1408 | ||
1409 | UnicodeString result; | |
1410 | LKFSubclass lkf(TRUE); // empty | |
1411 | Hashtable table; | |
1412 | ||
1413 | UObject *obj = lkf.create(*key, NULL, status); | |
1414 | logln("obj: " + UnicodeString(obj ? "obj" : "null")); | |
1415 | logln(lkf.getDisplayName("en_US", Locale::getDefault(), result)); | |
1416 | lkf.updateVisibleIDs(table, status); | |
1417 | delete obj; | |
1418 | if (table.count() != 1) { | |
1419 | errln("visible IDs does not contain en_US"); | |
1420 | } | |
1421 | ||
1422 | LKFSubclass invisibleLKF(FALSE); | |
1423 | obj = lkf.create(*key, NULL, status); | |
1424 | logln("obj: " + UnicodeString(obj ? "obj" : "null")); | |
1425 | logln(invisibleLKF.getDisplayName("en_US", Locale::getDefault(), result.remove())); | |
1426 | invisibleLKF.updateVisibleIDs(table, status); | |
1427 | if (table.count() != 0) { | |
1428 | errln("visible IDs contains en_US"); | |
1429 | } | |
1430 | delete obj; | |
1431 | delete key; | |
b75a7d8f | 1432 | |
73c04bcf A |
1433 | key = LocaleKey::createWithCanonicalFallback(&primary, &fallback, 123, status); |
1434 | if (U_SUCCESS(status)) { | |
1435 | UnicodeString str; | |
1436 | key->currentDescriptor(str); | |
1437 | key->parsePrefix(str); | |
1438 | if (str != "123") { | |
1439 | errln("did not get expected prefix"); | |
1440 | } | |
1441 | delete key; | |
1442 | } | |
1443 | ||
1444 | // coverage, getSupportedIDs is either overridden or the calling method is | |
1445 | LKFSubclass0 lkFactory; | |
1446 | Hashtable table0; | |
1447 | lkFactory.updateVisibleIDs(table0, status); | |
1448 | if (table0.count() != 0) { | |
1449 | errln("LKF returned non-empty hashtable"); | |
1450 | } | |
b75a7d8f | 1451 | |
b75a7d8f | 1452 | |
73c04bcf A |
1453 | // ResourceBundleFactory |
1454 | key = LocaleKey::createWithCanonicalFallback(&primary, &fallback, status); | |
1455 | ICUResourceBundleFactory rbf; | |
1456 | UObject* icurb = rbf.create(*key, NULL, status); | |
1457 | if (icurb != NULL) { | |
1458 | logln("got resource bundle for key"); | |
1459 | delete icurb; | |
1460 | } | |
1461 | delete key; | |
1462 | } | |
1463 | ||
1464 | #if 0 | |
1465 | // ICUNotifier | |
b75a7d8f A |
1466 | ICUNotifier nf = new ICUNSubclass(); |
1467 | try { | |
1468 | nf.addListener(null); | |
1469 | errln("added null listener"); | |
1470 | } | |
1471 | catch (NullPointerException e) { | |
1472 | logln(e.getMessage()); | |
1473 | } | |
1474 | catch (Exception e) { | |
1475 | errln("got wrong exception"); | |
1476 | } | |
1477 | ||
1478 | try { | |
1479 | nf.addListener(new WrongListener()); | |
1480 | errln("added wrong listener"); | |
1481 | } | |
1482 | catch (InternalError e) { | |
1483 | logln(e.getMessage()); | |
1484 | } | |
1485 | catch (Exception e) { | |
1486 | errln("got wrong exception"); | |
1487 | } | |
1488 | ||
1489 | try { | |
1490 | nf.removeListener(null); | |
1491 | errln("removed null listener"); | |
1492 | } | |
1493 | catch (NullPointerException e) { | |
1494 | logln(e.getMessage()); | |
1495 | } | |
1496 | catch (Exception e) { | |
1497 | errln("got wrong exception"); | |
1498 | } | |
1499 | ||
1500 | nf.removeListener(new MyListener()); | |
1501 | nf.notifyChanged(); | |
1502 | nf.addListener(new MyListener()); | |
1503 | nf.removeListener(new MyListener()); | |
1504 | #endif | |
1505 | } | |
1506 | ||
1507 | ||
1508 | /* !UCONFIG_NO_SERVICE */ | |
1509 | #endif | |
1510 | ||
1511 |