1 /** 2 ******************************************************************************* 3 * Copyright (C) 2001-2009, International Business Machines Corporation and * 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" 15 #include "servloc.h" 16 #include <stdio.h> 17 18 19 class MyListener : public EventListener { 20 }; 21 22 class WrongListener : public EventListener { 23 }; 24 25 class ICUNSubclass : public ICUNotifier { 26 public: 27 UBool acceptsListener(const EventListener& /*l*/) const { 28 return TRUE; 29 // return l instanceof MyListener; 30 } 31 32 virtual void notifyListener(EventListener& /*l*/) const { 33 } 34 }; 35 36 // This factory does nothing 37 class LKFSubclass0 : public LocaleKeyFactory { 38 public: 39 LKFSubclass0() 40 : LocaleKeyFactory(VISIBLE, "LKFSubclass0") 41 { 42 } 43 }; 44 45 class LKFSubclass : public LocaleKeyFactory { 46 Hashtable table; 47 48 public: 49 LKFSubclass(UBool visible) 50 : LocaleKeyFactory(visible ? VISIBLE : INVISIBLE, "LKFSubclass") 51 { 52 UErrorCode status = U_ZERO_ERROR; 53 table.put("en_US", this, status); 54 } 55 56 protected: 57 virtual const Hashtable* getSupportedIDs(UErrorCode &/*status*/) const { 58 return &table; 59 } 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 74 public: 75 /** 76 * UObject boilerplate. 77 */ 78 static UClassID getStaticClassID() { 79 return (UClassID)&fgClassID; 80 } 81 82 virtual UClassID getDynamicClassID() const { 83 return getStaticClassID(); 84 } 85 86 virtual UBool operator==(const UObject& other) const 87 { 88 return other.getDynamicClassID() == getStaticClassID() && 89 _val == ((Integer&)other)._val; 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()) { 165 sprintf(buffer, "%d", (int)((Integer*)obj)->_val); 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 dataerrln(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) { 312 UnicodeString* str = (UnicodeString*)obj; 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 329 UErrorCode status = U_ZERO_ERROR; 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 } 454 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 */ 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 }; 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 498 virtual ICUServiceFactory* createSimpleFactory(UObject* obj, const UnicodeString& id, UBool visible, UErrorCode& /* status */) 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: 515 virtual UObject* create(const ICUServiceKey& key, const ICUService* /* service */, UErrorCode& /* status */) const { 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 528 static UClassID getStaticClassID() { 529 return (UClassID)&fgClassID; 530 } 531 532 virtual UClassID getDynamicClassID() const { 533 return getStaticClassID(); 534 } 535 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 561 UObject* create(const ICUServiceKey& key, const ICUService* /* service */, UErrorCode& status) const { 562 if (U_FAILURE(status)) { 563 return NULL; 564 } 565 UnicodeString temp; 566 key.currentID(temp); 567 if (U_SUCCESS(_status)) { 568 if (_ids.contains(&temp)) { 569 return new UnicodeString(_factoryID + temp); 570 } 571 } else { 572 status = _status; 573 } 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 604 static UClassID getStaticClassID() { 605 return (UClassID)&fgClassID; 606 } 607 608 virtual UClassID getDynamicClassID() const { 609 return getStaticClassID(); 610 } 611 612 private: 613 static const char fgClassID; 614 }; 615 616 const char TestMultipleKeyStringFactory::fgClassID = '\0'; 617 618 void 619 ICUServiceTest::testAPI_Two() 620 { 621 UErrorCode status = U_ZERO_ERROR; 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; 698 UVector names(status); 699 service.getDisplayNames(names, status); 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; 738 UVector names(status); 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("29) 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. 889 UErrorCode status = U_ZERO_ERROR; 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; 909 UVector names(status); 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; 935 UVector names(status); 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() { 1033 UErrorCode status = U_ZERO_ERROR; 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); 1045 service.registerInstance(japanese, (UnicodeString)"ja", TRUE, status); 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 { 1123 UErrorCode status = U_ZERO_ERROR; 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) { 1195 confirmIdentical("test available locales", locales->count(status), 6); 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) { 1215 greetingID = new UnicodeString("greeting"); 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 1246 UnicodeString& getDisplayName(const UnicodeString& id, const Locale& /* locale */, UnicodeString& result) const { 1247 result.append("wrap '"); 1248 result.append(id); 1249 result.append("'"); 1250 return result; 1251 } 1252 1253 /** 1254 * UObject boilerplate. 1255 */ 1256 static UClassID getStaticClassID() { 1257 return (UClassID)&fgClassID; 1258 } 1259 1260 virtual UClassID getDynamicClassID() const { 1261 return getStaticClassID(); 1262 } 1263 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"; 1277 UErrorCode status = U_ZERO_ERROR; 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 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); 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; 1432 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 } 1451 1452 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 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 1512