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