1 // 2016 and later: Unicode, Inc. and others. 2 // License & terms of use: http://www.unicode.org/copyright.html 3 /******************************************************************** 4 * COPYRIGHT: 5 * Copyright (c) 1997-2016, International Business Machines Corporation and 6 * others. All Rights Reserved. 7 ********************************************************************/ 8 9 10 /** 11 * IntlTestUtilities is the medium level test class for everything in the directory "utility". 12 */ 13 14 #include "unicode/utypes.h" 15 #include "unicode/errorcode.h" 16 #include "unicode/localpointer.h" 17 #include "charstr.h" 18 #include "itutil.h" 19 #include "strtest.h" 20 #include "loctest.h" 21 #include "citrtest.h" 22 #include "ustrtest.h" 23 #include "ucdtest.h" 24 #include "restest.h" 25 #include "restsnew.h" 26 #include "tsmthred.h" 27 #include "tsputil.h" 28 #include "uobjtest.h" 29 #include "utxttest.h" 30 #include "v32test.h" 31 #include "uvectest.h" 32 #include "aliastst.h" 33 #include "usettest.h" 34 35 extern IntlTest *createBytesTrieTest(); 36 static IntlTest *createLocalPointerTest(); 37 extern IntlTest *createUCharsTrieTest(); 38 static IntlTest *createEnumSetTest(); 39 extern IntlTest *createSimpleFormatterTest(); 40 extern IntlTest *createUnifiedCacheTest(); 41 extern IntlTest *createQuantityFormatterTest(); 42 extern IntlTest *createPluralMapTest(); 43 #if !UCONFIG_NO_FORMATTING 44 extern IntlTest *createStaticUnicodeSetsTest(); 45 #endif 46 47 48 #define CASE(id, test) case id: \ 49 name = #test; \ 50 if (exec) { \ 51 logln(#test "---"); logln(); \ 52 test t; \ 53 callTest(t, par); \ 54 } \ 55 break 56 57 void IntlTestUtilities::runIndexedTest( int32_t index, UBool exec, const char* &name, char* par ) 58 { 59 if (exec) logln("TestSuite Utilities: "); 60 switch (index) { 61 CASE(0, MultithreadTest); 62 CASE(1, StringTest); 63 CASE(2, UnicodeStringTest); 64 CASE(3, LocaleTest); 65 CASE(4, CharIterTest); 66 CASE(5, UObjectTest); 67 CASE(6, UnicodeTest); 68 CASE(7, ResourceBundleTest); 69 CASE(8, NewResourceBundleTest); 70 CASE(9, PUtilTest); 71 CASE(10, UVector32Test); 72 CASE(11, UVectorTest); 73 CASE(12, UTextTest); 74 CASE(13, LocaleAliasTest); 75 CASE(14, UnicodeSetTest); 76 CASE(15, ErrorCodeTest); 77 case 16: 78 name = "LocalPointerTest"; 79 if (exec) { 80 logln("TestSuite LocalPointerTest---"); logln(); 81 LocalPointer<IntlTest> test(createLocalPointerTest()); 82 callTest(*test, par); 83 } 84 break; 85 case 17: 86 name = "BytesTrieTest"; 87 if (exec) { 88 logln("TestSuite BytesTrieTest---"); logln(); 89 LocalPointer<IntlTest> test(createBytesTrieTest()); 90 callTest(*test, par); 91 } 92 break; 93 case 18: 94 name = "UCharsTrieTest"; 95 if (exec) { 96 logln("TestSuite UCharsTrieTest---"); logln(); 97 LocalPointer<IntlTest> test(createUCharsTrieTest()); 98 callTest(*test, par); 99 } 100 break; 101 case 19: 102 name = "EnumSetTest"; 103 if (exec) { 104 logln("TestSuite EnumSetTest---"); logln(); 105 LocalPointer<IntlTest> test(createEnumSetTest()); 106 callTest(*test, par); 107 } 108 break; 109 case 20: 110 name = "SimpleFormatterTest"; 111 if (exec) { 112 logln("TestSuite SimpleFormatterTest---"); logln(); 113 LocalPointer<IntlTest> test(createSimpleFormatterTest()); 114 callTest(*test, par); 115 } 116 break; 117 case 21: 118 name = "UnifiedCacheTest"; 119 if (exec) { 120 logln("TestSuite UnifiedCacheTest---"); logln(); 121 LocalPointer<IntlTest> test(createUnifiedCacheTest()); 122 callTest(*test, par); 123 } 124 break; 125 case 22: 126 name = "QuantityFormatterTest"; 127 if (exec) { 128 logln("TestSuite QuantityFormatterTest---"); logln(); 129 LocalPointer<IntlTest> test(createQuantityFormatterTest()); 130 callTest(*test, par); 131 } 132 break; 133 case 23: 134 name = "PluralMapTest"; 135 if (exec) { 136 logln("TestSuite PluralMapTest---"); logln(); 137 LocalPointer<IntlTest> test(createPluralMapTest()); 138 callTest(*test, par); 139 } 140 break; 141 case 24: 142 name = "StaticUnicodeSetsTest"; 143 #if !UCONFIG_NO_FORMATTING 144 if (exec) { 145 logln("TestSuite StaticUnicodeSetsTest---"); logln(); 146 LocalPointer<IntlTest> test(createStaticUnicodeSetsTest()); 147 callTest(*test, par); 148 } 149 #endif 150 break; 151 default: name = ""; break; //needed to end loop 152 } 153 } 154 155 void ErrorCodeTest::runIndexedTest(int32_t index, UBool exec, const char* &name, char* /*par*/) { 156 if (exec) logln("TestSuite Utilities: "); 157 switch (index) { 158 case 0: name = "TestErrorCode"; if (exec) TestErrorCode(); break; 159 case 1: name = "TestSubclass"; if (exec) TestSubclass(); break; 160 case 2: name = "TestIcuTestErrorCode"; if (exec) TestIcuTestErrorCode(); break; 161 default: name = ""; break; //needed to end loop 162 } 163 } 164 165 static void RefPlusOne(UErrorCode &code) { code=(UErrorCode)(code+1); } 166 static void PtrPlusTwo(UErrorCode *code) { *code=(UErrorCode)(*code+2); } 167 168 void ErrorCodeTest::TestErrorCode() { 169 ErrorCode errorCode; 170 if(errorCode.get()!=U_ZERO_ERROR || !errorCode.isSuccess() || errorCode.isFailure()) { 171 errln("ErrorCode did not initialize properly"); 172 return; 173 } 174 errorCode.assertSuccess(); 175 if(errorCode.errorName()!=u_errorName(U_ZERO_ERROR)) { 176 errln("ErrorCode did not format error message string properly"); 177 } 178 RefPlusOne(errorCode); 179 if(errorCode.get()!=U_ILLEGAL_ARGUMENT_ERROR || errorCode.isSuccess() || !errorCode.isFailure()) { 180 errln("ErrorCode did not yield a writable reference"); 181 } 182 PtrPlusTwo(errorCode); 183 if(errorCode.get()!=U_INVALID_FORMAT_ERROR || errorCode.isSuccess() || !errorCode.isFailure()) { 184 errln("ErrorCode did not yield a writable pointer"); 185 } 186 errorCode.set(U_PARSE_ERROR); 187 if(errorCode.get()!=U_PARSE_ERROR || errorCode.isSuccess() || !errorCode.isFailure()) { 188 errln("ErrorCode.set() failed"); 189 } 190 if( errorCode.reset()!=U_PARSE_ERROR || errorCode.get()!=U_ZERO_ERROR || 191 !errorCode.isSuccess() || errorCode.isFailure() 192 ) { 193 errln("ErrorCode did not reset properly"); 194 } 195 } 196 197 class MyErrorCode: public ErrorCode { 198 public: 199 MyErrorCode(int32_t &countChecks, int32_t &countDests) 200 : checks(countChecks), dests(countDests) {} 201 ~MyErrorCode() { 202 if(isFailure()) { 203 ++dests; 204 } 205 } 206 private: 207 virtual void handleFailure() const { 208 ++checks; 209 } 210 int32_t &checks; 211 int32_t &dests; 212 }; 213 214 void ErrorCodeTest::TestSubclass() { 215 int32_t countChecks=0; 216 int32_t countDests=0; 217 { 218 MyErrorCode errorCode(countChecks, countDests); 219 if( errorCode.get()!=U_ZERO_ERROR || !errorCode.isSuccess() || errorCode.isFailure() || 220 countChecks!=0 || countDests!=0 221 ) { 222 errln("ErrorCode did not initialize properly"); 223 return; 224 } 225 errorCode.assertSuccess(); 226 if(countChecks!=0) { 227 errln("ErrorCode.assertSuccess() called handleFailure() despite success"); 228 } 229 RefPlusOne(errorCode); 230 if(errorCode.get()!=U_ILLEGAL_ARGUMENT_ERROR || errorCode.isSuccess() || !errorCode.isFailure()) { 231 errln("ErrorCode did not yield a writable reference"); 232 } 233 errorCode.assertSuccess(); 234 if(countChecks!=1) { 235 errln("ErrorCode.assertSuccess() did not handleFailure()"); 236 } 237 PtrPlusTwo(errorCode); 238 if(errorCode.get()!=U_INVALID_FORMAT_ERROR || errorCode.isSuccess() || !errorCode.isFailure()) { 239 errln("ErrorCode did not yield a writable pointer"); 240 } 241 errorCode.assertSuccess(); 242 if(countChecks!=2) { 243 errln("ErrorCode.assertSuccess() did not handleFailure()"); 244 } 245 errorCode.set(U_PARSE_ERROR); 246 if(errorCode.get()!=U_PARSE_ERROR || errorCode.isSuccess() || !errorCode.isFailure()) { 247 errln("ErrorCode.set() failed"); 248 } 249 if( errorCode.reset()!=U_PARSE_ERROR || errorCode.get()!=U_ZERO_ERROR || 250 !errorCode.isSuccess() || errorCode.isFailure() 251 ) { 252 errln("ErrorCode did not reset properly"); 253 } 254 errorCode.assertSuccess(); 255 if(countChecks!=2) { 256 errln("ErrorCode.assertSuccess() called handleFailure() despite success"); 257 } 258 } 259 if(countDests!=0) { 260 errln("MyErrorCode destructor detected failure despite success"); 261 } 262 countChecks=countDests=0; 263 { 264 MyErrorCode errorCode(countChecks, countDests); 265 errorCode.set(U_PARSE_ERROR); 266 } 267 if(countDests!=1) { 268 errln("MyErrorCode destructor failed to detect failure"); 269 } 270 } 271 272 class IcuTestErrorCodeTestHelper : public IntlTest { 273 public: 274 void errln( const UnicodeString &message ) U_OVERRIDE { 275 test->assertFalse("Already saw an error", seenError); 276 seenError = TRUE; 277 test->assertEquals("Message for Error", expectedErrln, message); 278 if (expectedDataErr) { 279 test->errln("Got non-data error, but expected data error"); 280 } 281 } 282 283 void dataerrln( const UnicodeString &message ) U_OVERRIDE { 284 test->assertFalse("Already saw an error", seenError); 285 seenError = TRUE; 286 test->assertEquals("Message for Error", expectedErrln, message); 287 if (!expectedDataErr) { 288 test->errln("Got data error, but expected non-data error"); 289 } 290 } 291 292 IntlTest* test; 293 UBool expectedDataErr; 294 UnicodeString expectedErrln; 295 UBool seenError; 296 }; 297 298 void ErrorCodeTest::TestIcuTestErrorCode() { 299 IcuTestErrorCodeTestHelper helper; 300 helper.test = this; 301 302 // Test destructor message 303 helper.expectedErrln = u"AAA destructor: expected success but got error: U_ILLEGAL_PAD_POSITION"; 304 helper.expectedDataErr = FALSE; 305 helper.seenError = FALSE; 306 { 307 IcuTestErrorCode testStatus(helper, "AAA"); 308 testStatus.set(U_ILLEGAL_PAD_POSITION); 309 } 310 assertTrue("Should have seen an error", helper.seenError); 311 312 // Test destructor message with scope 313 helper.expectedErrln = u"BBB destructor: expected success but got error: U_ILLEGAL_PAD_POSITION scope: foo"; 314 helper.expectedDataErr = FALSE; 315 helper.seenError = FALSE; 316 { 317 IcuTestErrorCode testStatus(helper, "BBB"); 318 testStatus.setScope("foo"); 319 testStatus.set(U_ILLEGAL_PAD_POSITION); 320 } 321 assertTrue("Should have seen an error", helper.seenError); 322 323 // Check errIfFailure message with scope 324 helper.expectedErrln = u"CCC expected success but got error: U_ILLEGAL_PAD_POSITION scope: foo"; 325 helper.expectedDataErr = FALSE; 326 helper.seenError = FALSE; 327 { 328 IcuTestErrorCode testStatus(helper, "CCC"); 329 testStatus.setScope("foo"); 330 testStatus.set(U_ILLEGAL_PAD_POSITION); 331 testStatus.errIfFailureAndReset(); 332 assertTrue("Should have seen an error", helper.seenError); 333 helper.seenError = FALSE; 334 helper.expectedErrln = u"CCC expected success but got error: U_ILLEGAL_CHAR_FOUND scope: foo - 5.4300"; 335 testStatus.set(U_ILLEGAL_CHAR_FOUND); 336 testStatus.errIfFailureAndReset("%6.4f", 5.43); 337 assertTrue("Should have seen an error", helper.seenError); 338 } 339 340 // Check errDataIfFailure message without scope 341 helper.expectedErrln = u"DDD data: expected success but got error: U_ILLEGAL_PAD_POSITION"; 342 helper.expectedDataErr = TRUE; 343 helper.seenError = FALSE; 344 { 345 IcuTestErrorCode testStatus(helper, "DDD"); 346 testStatus.set(U_ILLEGAL_PAD_POSITION); 347 testStatus.errDataIfFailureAndReset(); 348 assertTrue("Should have seen an error", helper.seenError); 349 helper.seenError = FALSE; 350 helper.expectedErrln = u"DDD data: expected success but got error: U_ILLEGAL_CHAR_FOUND - 5.4300"; 351 testStatus.set(U_ILLEGAL_CHAR_FOUND); 352 testStatus.errDataIfFailureAndReset("%6.4f", 5.43); 353 assertTrue("Should have seen an error", helper.seenError); 354 } 355 356 // Check expectFailure 357 helper.expectedErrln = u"EEE expected: U_ILLEGAL_CHAR_FOUND but got error: U_ILLEGAL_PAD_POSITION"; 358 helper.expectedDataErr = FALSE; 359 helper.seenError = FALSE; 360 { 361 IcuTestErrorCode testStatus(helper, "EEE"); 362 testStatus.set(U_ILLEGAL_PAD_POSITION); 363 testStatus.expectErrorAndReset(U_ILLEGAL_PAD_POSITION); 364 assertFalse("Should NOT have seen an error", helper.seenError); 365 testStatus.set(U_ILLEGAL_PAD_POSITION); 366 testStatus.expectErrorAndReset(U_ILLEGAL_CHAR_FOUND); 367 assertTrue("Should have seen an error", helper.seenError); 368 helper.seenError = FALSE; 369 helper.expectedErrln = u"EEE expected: U_ILLEGAL_CHAR_FOUND but got error: U_ZERO_ERROR scope: scopety scope - 5.4300"; 370 testStatus.setScope("scopety scope"); 371 testStatus.set(U_ILLEGAL_PAD_POSITION); 372 testStatus.expectErrorAndReset(U_ILLEGAL_PAD_POSITION, "%6.4f", 5.43); 373 assertFalse("Should NOT have seen an error", helper.seenError); 374 testStatus.expectErrorAndReset(U_ILLEGAL_CHAR_FOUND, "%6.4f", 5.43); 375 assertTrue("Should have seen an error", helper.seenError); 376 } 377 } 378 379 380 class LocalPointerTest : public IntlTest { 381 public: 382 LocalPointerTest() {} 383 384 void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par=NULL); 385 386 void TestLocalPointer(); 387 void TestLocalPointerMoveSwap(); 388 void TestLocalArray(); 389 void TestLocalArrayMoveSwap(); 390 void TestLocalXyzPointer(); 391 void TestLocalXyzPointerMoveSwap(); 392 void TestLocalXyzPointerNull(); 393 }; 394 395 static IntlTest *createLocalPointerTest() { 396 return new LocalPointerTest(); 397 } 398 399 void LocalPointerTest::runIndexedTest(int32_t index, UBool exec, const char *&name, char * /*par*/) { 400 if(exec) { 401 logln("TestSuite LocalPointerTest: "); 402 } 403 TESTCASE_AUTO_BEGIN; 404 TESTCASE_AUTO(TestLocalPointer); 405 TESTCASE_AUTO(TestLocalPointerMoveSwap); 406 TESTCASE_AUTO(TestLocalArray); 407 TESTCASE_AUTO(TestLocalArrayMoveSwap); 408 TESTCASE_AUTO(TestLocalXyzPointer); 409 TESTCASE_AUTO(TestLocalXyzPointerMoveSwap); 410 TESTCASE_AUTO(TestLocalXyzPointerNull); 411 TESTCASE_AUTO_END; 412 } 413 414 // Exercise almost every LocalPointer and LocalPointerBase method. 415 void LocalPointerTest::TestLocalPointer() { 416 // constructor 417 LocalPointer<UnicodeString> s(new UnicodeString((UChar32)0x50005)); 418 // isNULL(), isValid(), operator==(), operator!=() 419 if(s.isNull() || !s.isValid() || s==NULL || !(s!=NULL)) { 420 errln("LocalPointer constructor or NULL test failure"); 421 return; 422 } 423 // getAlias(), operator->, operator* 424 if(s.getAlias()->length()!=2 || s->length()!=2 || (*s).length()!=2) { 425 errln("LocalPointer access failure"); 426 } 427 // adoptInstead(), orphan() 428 s.adoptInstead(new UnicodeString((UChar)0xfffc)); 429 if(s->length()!=1) { 430 errln("LocalPointer adoptInstead(U+FFFC) failure"); 431 } 432 UnicodeString *orphan=s.orphan(); 433 if(orphan==NULL || orphan->length()!=1 || s.isValid() || s!=NULL) { 434 errln("LocalPointer orphan() failure"); 435 } 436 delete orphan; 437 s.adoptInstead(new UnicodeString()); 438 if(s->length()!=0) { 439 errln("LocalPointer adoptInstead(empty) failure"); 440 } 441 442 // LocalPointer(p, errorCode) sets U_MEMORY_ALLOCATION_ERROR if p==NULL. 443 UErrorCode errorCode = U_ZERO_ERROR; 444 LocalPointer<CharString> csx(new CharString("some chars", errorCode), errorCode); 445 if(csx.isNull() && U_SUCCESS(errorCode)) { 446 errln("LocalPointer(p, errorCode) failure"); 447 return; 448 } 449 errorCode = U_ZERO_ERROR; 450 csx.adoptInsteadAndCheckErrorCode(new CharString("different chars", errorCode), errorCode); 451 if(csx.isNull() && U_SUCCESS(errorCode)) { 452 errln("adoptInsteadAndCheckErrorCode(p, errorCode) failure"); 453 return; 454 } 455 // Incoming failure: Keep the current object and delete the input object. 456 errorCode = U_ILLEGAL_ARGUMENT_ERROR; 457 csx.adoptInsteadAndCheckErrorCode(new CharString("unused", errorCode), errorCode); 458 if(csx.isValid() && strcmp(csx->data(), "different chars") != 0) { 459 errln("adoptInsteadAndCheckErrorCode(p, U_FAILURE) did not retain the old object"); 460 return; 461 } 462 errorCode = U_ZERO_ERROR; 463 csx.adoptInsteadAndCheckErrorCode(NULL, errorCode); 464 if(errorCode != U_MEMORY_ALLOCATION_ERROR) { 465 errln("adoptInsteadAndCheckErrorCode(NULL, errorCode) did not set U_MEMORY_ALLOCATION_ERROR"); 466 return; 467 } 468 if(csx.isValid()) { 469 errln("adoptInsteadAndCheckErrorCode(NULL, errorCode) kept the object"); 470 return; 471 } 472 errorCode = U_ZERO_ERROR; 473 LocalPointer<CharString> null(NULL, errorCode); 474 if(errorCode != U_MEMORY_ALLOCATION_ERROR) { 475 errln("LocalPointer(NULL, errorCode) did not set U_MEMORY_ALLOCATION_ERROR"); 476 return; 477 } 478 479 // destructor 480 } 481 482 void LocalPointerTest::TestLocalPointerMoveSwap() { 483 UnicodeString *p1 = new UnicodeString((UChar)0x61); 484 UnicodeString *p2 = new UnicodeString((UChar)0x62); 485 LocalPointer<UnicodeString> s1(p1); 486 LocalPointer<UnicodeString> s2(p2); 487 s1.swap(s2); 488 if(s1.getAlias() != p2 || s2.getAlias() != p1) { 489 errln("LocalPointer.swap() did not swap"); 490 } 491 swap(s1, s2); 492 if(s1.getAlias() != p1 || s2.getAlias() != p2) { 493 errln("swap(LocalPointer) did not swap back"); 494 } 495 LocalPointer<UnicodeString> s3; 496 s3.moveFrom(s1); 497 if(s3.getAlias() != p1 || s1.isValid()) { 498 errln("LocalPointer.moveFrom() did not move"); 499 } 500 infoln("TestLocalPointerMoveSwap() with rvalue references"); 501 s1 = static_cast<LocalPointer<UnicodeString> &&>(s3); 502 if(s1.getAlias() != p1 || s3.isValid()) { 503 errln("LocalPointer move assignment operator did not move"); 504 } 505 LocalPointer<UnicodeString> s4(static_cast<LocalPointer<UnicodeString> &&>(s2)); 506 if(s4.getAlias() != p2 || s2.isValid()) { 507 errln("LocalPointer move constructor did not move"); 508 } 509 510 // Move self assignment leaves the object valid but in an undefined state. 511 // Do it to make sure there is no crash, 512 // but do not check for any particular resulting value. 513 s1.moveFrom(s1); 514 s3.moveFrom(s3); 515 } 516 517 // Exercise almost every LocalArray method (but not LocalPointerBase). 518 void LocalPointerTest::TestLocalArray() { 519 // constructor 520 LocalArray<UnicodeString> a(new UnicodeString[2]); 521 // operator[]() 522 a[0].append((UChar)0x61); 523 a[1].append((UChar32)0x60006); 524 if(a[0].length()!=1 || a[1].length()!=2) { 525 errln("LocalArray access failure"); 526 } 527 // adoptInstead() 528 a.adoptInstead(new UnicodeString[4]); 529 a[3].append((UChar)0x62).append((UChar)0x63).reverse(); 530 if(a[3].length()!=2 || a[3][1]!=0x62) { 531 errln("LocalArray adoptInstead() failure"); 532 } 533 534 // LocalArray(p, errorCode) sets U_MEMORY_ALLOCATION_ERROR if p==NULL. 535 UErrorCode errorCode = U_ZERO_ERROR; 536 LocalArray<UnicodeString> ua(new UnicodeString[3], errorCode); 537 if(ua.isNull() && U_SUCCESS(errorCode)) { 538 errln("LocalArray(p, errorCode) failure"); 539 return; 540 } 541 errorCode = U_ZERO_ERROR; 542 UnicodeString *u4 = new UnicodeString[4]; 543 ua.adoptInsteadAndCheckErrorCode(u4, errorCode); 544 if(ua.isNull() && U_SUCCESS(errorCode)) { 545 errln("adoptInsteadAndCheckErrorCode(p, errorCode) failure"); 546 return; 547 } 548 // Incoming failure: Keep the current object and delete the input object. 549 errorCode = U_ILLEGAL_ARGUMENT_ERROR; 550 ua.adoptInsteadAndCheckErrorCode(new UnicodeString[5], errorCode); 551 if(ua.isValid() && ua.getAlias() != u4) { 552 errln("adoptInsteadAndCheckErrorCode(p, U_FAILURE) did not retain the old array"); 553 return; 554 } 555 errorCode = U_ZERO_ERROR; 556 ua.adoptInsteadAndCheckErrorCode(NULL, errorCode); 557 if(errorCode != U_MEMORY_ALLOCATION_ERROR) { 558 errln("adoptInsteadAndCheckErrorCode(NULL, errorCode) did not set U_MEMORY_ALLOCATION_ERROR"); 559 return; 560 } 561 if(ua.isValid()) { 562 errln("adoptInsteadAndCheckErrorCode(NULL, errorCode) kept the array"); 563 return; 564 } 565 errorCode = U_ZERO_ERROR; 566 LocalArray<UnicodeString> null(NULL, errorCode); 567 if(errorCode != U_MEMORY_ALLOCATION_ERROR) { 568 errln("LocalArray(NULL, errorCode) did not set U_MEMORY_ALLOCATION_ERROR"); 569 return; 570 } 571 572 // destructor 573 } 574 575 void LocalPointerTest::TestLocalArrayMoveSwap() { 576 UnicodeString *p1 = new UnicodeString[2]; 577 UnicodeString *p2 = new UnicodeString[3]; 578 LocalArray<UnicodeString> a1(p1); 579 LocalArray<UnicodeString> a2(p2); 580 a1.swap(a2); 581 if(a1.getAlias() != p2 || a2.getAlias() != p1) { 582 errln("LocalArray.swap() did not swap"); 583 } 584 swap(a1, a2); 585 if(a1.getAlias() != p1 || a2.getAlias() != p2) { 586 errln("swap(LocalArray) did not swap back"); 587 } 588 LocalArray<UnicodeString> a3; 589 a3.moveFrom(a1); 590 if(a3.getAlias() != p1 || a1.isValid()) { 591 errln("LocalArray.moveFrom() did not move"); 592 } 593 infoln("TestLocalArrayMoveSwap() with rvalue references"); 594 a1 = static_cast<LocalArray<UnicodeString> &&>(a3); 595 if(a1.getAlias() != p1 || a3.isValid()) { 596 errln("LocalArray move assignment operator did not move"); 597 } 598 LocalArray<UnicodeString> a4(static_cast<LocalArray<UnicodeString> &&>(a2)); 599 if(a4.getAlias() != p2 || a2.isValid()) { 600 errln("LocalArray move constructor did not move"); 601 } 602 603 // Move self assignment leaves the object valid but in an undefined state. 604 // Do it to make sure there is no crash, 605 // but do not check for any particular resulting value. 606 a1.moveFrom(a1); 607 a3.moveFrom(a3); 608 } 609 610 #include "unicode/ucnvsel.h" 611 #include "unicode/ucal.h" 612 #include "unicode/udatpg.h" 613 #include "unicode/uidna.h" 614 #include "unicode/uldnames.h" 615 #include "unicode/umsg.h" 616 #include "unicode/unorm2.h" 617 #include "unicode/uregex.h" 618 #include "unicode/utrans.h" 619 620 // Use LocalXyzPointer types that are not covered elsewhere in the intltest suite. 621 void LocalPointerTest::TestLocalXyzPointer() { 622 IcuTestErrorCode errorCode(*this, "TestLocalXyzPointer"); 623 624 static const char *const encoding="ISO-8859-1"; 625 LocalUConverterSelectorPointer sel( 626 ucnvsel_open(&encoding, 1, NULL, UCNV_ROUNDTRIP_SET, errorCode)); 627 if(errorCode.errIfFailureAndReset("ucnvsel_open()")) { 628 return; 629 } 630 if(sel.isNull()) { 631 errln("LocalUConverterSelectorPointer failure"); 632 return; 633 } 634 635 #if !UCONFIG_NO_FORMATTING 636 LocalUCalendarPointer cal(ucal_open(NULL, 0, "root", UCAL_GREGORIAN, errorCode)); 637 if(errorCode.errDataIfFailureAndReset("ucal_open()")) { 638 return; 639 } 640 if(cal.isNull()) { 641 errln("LocalUCalendarPointer failure"); 642 return; 643 } 644 645 LocalUDateTimePatternGeneratorPointer patgen(udatpg_open("root", errorCode)); 646 if(errorCode.errDataIfFailureAndReset("udatpg_open()")) { 647 return; 648 } 649 if(patgen.isNull()) { 650 errln("LocalUDateTimePatternGeneratorPointer failure"); 651 return; 652 } 653 654 LocalULocaleDisplayNamesPointer ldn(uldn_open("de-CH", ULDN_STANDARD_NAMES, errorCode)); 655 if(errorCode.errIfFailureAndReset("uldn_open()")) { 656 return; 657 } 658 if(ldn.isNull()) { 659 errln("LocalULocaleDisplayNamesPointer failure"); 660 return; 661 } 662 663 UnicodeString hello=UNICODE_STRING_SIMPLE("Hello {0}!"); 664 LocalUMessageFormatPointer msg( 665 umsg_open(hello.getBuffer(), hello.length(), "root", NULL, errorCode)); 666 if(errorCode.errIfFailureAndReset("umsg_open()")) { 667 return; 668 } 669 if(msg.isNull()) { 670 errln("LocalUMessageFormatPointer failure"); 671 return; 672 } 673 #endif /* UCONFIG_NO_FORMATTING */ 674 675 #if !UCONFIG_NO_NORMALIZATION 676 const UNormalizer2 *nfc=unorm2_getNFCInstance(errorCode); 677 UnicodeSet emptySet; 678 LocalUNormalizer2Pointer fn2(unorm2_openFiltered(nfc, emptySet.toUSet(), errorCode)); 679 if(errorCode.errIfFailureAndReset("unorm2_openFiltered()")) { 680 return; 681 } 682 if(fn2.isNull()) { 683 errln("LocalUNormalizer2Pointer failure"); 684 return; 685 } 686 #endif /* !UCONFIG_NO_NORMALIZATION */ 687 688 #if !UCONFIG_NO_IDNA 689 LocalUIDNAPointer idna(uidna_openUTS46(0, errorCode)); 690 if(errorCode.errIfFailureAndReset("uidna_openUTS46()")) { 691 return; 692 } 693 if(idna.isNull()) { 694 errln("LocalUIDNAPointer failure"); 695 return; 696 } 697 #endif /* !UCONFIG_NO_IDNA */ 698 699 #if !UCONFIG_NO_REGULAR_EXPRESSIONS 700 UnicodeString pattern=UNICODE_STRING_SIMPLE("abc|xy+z"); 701 LocalURegularExpressionPointer regex( 702 uregex_open(pattern.getBuffer(), pattern.length(), 0, NULL, errorCode)); 703 if(errorCode.errIfFailureAndReset("uregex_open()")) { 704 return; 705 } 706 if(regex.isNull()) { 707 errln("LocalURegularExpressionPointer failure"); 708 return; 709 } 710 #endif /* UCONFIG_NO_REGULAR_EXPRESSIONS */ 711 712 #if !UCONFIG_NO_TRANSLITERATION 713 UnicodeString id=UNICODE_STRING_SIMPLE("Grek-Latn"); 714 LocalUTransliteratorPointer trans( 715 utrans_openU(id.getBuffer(), id.length(), UTRANS_FORWARD, NULL, 0, NULL, errorCode)); 716 if(errorCode.errIfFailureAndReset("utrans_open()")) { 717 return; 718 } 719 if(trans.isNull()) { 720 errln("LocalUTransliteratorPointer failure"); 721 return; 722 } 723 #endif /* !UCONFIG_NO_TRANSLITERATION */ 724 725 // destructors 726 } 727 728 void LocalPointerTest::TestLocalXyzPointerMoveSwap() { 729 #if !UCONFIG_NO_NORMALIZATION 730 IcuTestErrorCode errorCode(*this, "TestLocalXyzPointerMoveSwap"); 731 const UNormalizer2 *nfc=unorm2_getNFCInstance(errorCode); 732 const UNormalizer2 *nfd=unorm2_getNFDInstance(errorCode); 733 if(errorCode.errIfFailureAndReset("unorm2_getNF[CD]Instance()")) { 734 return; 735 } 736 UnicodeSet emptySet; 737 UNormalizer2 *p1 = unorm2_openFiltered(nfc, emptySet.toUSet(), errorCode); 738 UNormalizer2 *p2 = unorm2_openFiltered(nfd, emptySet.toUSet(), errorCode); 739 LocalUNormalizer2Pointer f1(p1); 740 LocalUNormalizer2Pointer f2(p2); 741 if(errorCode.errIfFailureAndReset("unorm2_openFiltered()")) { 742 return; 743 } 744 if(f1.isNull() || f2.isNull()) { 745 errln("LocalUNormalizer2Pointer failure"); 746 return; 747 } 748 f1.swap(f2); 749 if(f1.getAlias() != p2 || f2.getAlias() != p1) { 750 errln("LocalUNormalizer2Pointer.swap() did not swap"); 751 } 752 swap(f1, f2); 753 if(f1.getAlias() != p1 || f2.getAlias() != p2) { 754 errln("swap(LocalUNormalizer2Pointer) did not swap back"); 755 } 756 LocalUNormalizer2Pointer f3; 757 f3.moveFrom(f1); 758 if(f3.getAlias() != p1 || f1.isValid()) { 759 errln("LocalUNormalizer2Pointer.moveFrom() did not move"); 760 } 761 infoln("TestLocalXyzPointerMoveSwap() with rvalue references"); 762 f1 = static_cast<LocalUNormalizer2Pointer &&>(f3); 763 if(f1.getAlias() != p1 || f3.isValid()) { 764 errln("LocalUNormalizer2Pointer move assignment operator did not move"); 765 } 766 LocalUNormalizer2Pointer f4(static_cast<LocalUNormalizer2Pointer &&>(f2)); 767 if(f4.getAlias() != p2 || f2.isValid()) { 768 errln("LocalUNormalizer2Pointer move constructor did not move"); 769 } 770 // Move self assignment leaves the object valid but in an undefined state. 771 // Do it to make sure there is no crash, 772 // but do not check for any particular resulting value. 773 f1.moveFrom(f1); 774 f3.moveFrom(f3); 775 #endif /* !UCONFIG_NO_NORMALIZATION */ 776 } 777 778 // Try LocalXyzPointer types with NULL pointers. 779 void LocalPointerTest::TestLocalXyzPointerNull() { 780 { 781 IcuTestErrorCode errorCode(*this, "TestLocalXyzPointerNull/LocalUConverterSelectorPointer"); 782 static const char *const encoding="ISO-8859-1"; 783 LocalUConverterSelectorPointer null; 784 LocalUConverterSelectorPointer sel( 785 ucnvsel_open(&encoding, 1, NULL, UCNV_ROUNDTRIP_SET, errorCode)); 786 sel.adoptInstead(NULL); 787 } 788 #if !UCONFIG_NO_FORMATTING 789 { 790 IcuTestErrorCode errorCode(*this, "TestLocalXyzPointerNull/LocalUCalendarPointer"); 791 LocalUCalendarPointer null; 792 LocalUCalendarPointer cal(ucal_open(NULL, 0, "root", UCAL_GREGORIAN, errorCode)); 793 if(!errorCode.errDataIfFailureAndReset("ucal_open()")) { 794 cal.adoptInstead(NULL); 795 } 796 } 797 { 798 IcuTestErrorCode errorCode(*this, "TestLocalXyzPointerNull/LocalUDateTimePatternGeneratorPointer"); 799 LocalUDateTimePatternGeneratorPointer null; 800 LocalUDateTimePatternGeneratorPointer patgen(udatpg_open("root", errorCode)); 801 patgen.adoptInstead(NULL); 802 } 803 { 804 IcuTestErrorCode errorCode(*this, "TestLocalXyzPointerNull/LocalUMessageFormatPointer"); 805 UnicodeString hello=UNICODE_STRING_SIMPLE("Hello {0}!"); 806 LocalUMessageFormatPointer null; 807 LocalUMessageFormatPointer msg( 808 umsg_open(hello.getBuffer(), hello.length(), "root", NULL, errorCode)); 809 msg.adoptInstead(NULL); 810 } 811 #endif /* !UCONFIG_NO_FORMATTING */ 812 813 #if !UCONFIG_NO_REGULAR_EXPRESSIONS 814 { 815 IcuTestErrorCode errorCode(*this, "TestLocalXyzPointerNull/LocalURegularExpressionPointer"); 816 UnicodeString pattern=UNICODE_STRING_SIMPLE("abc|xy+z"); 817 LocalURegularExpressionPointer null; 818 LocalURegularExpressionPointer regex( 819 uregex_open(pattern.getBuffer(), pattern.length(), 0, NULL, errorCode)); 820 if(!errorCode.errDataIfFailureAndReset("urege_open()")) { 821 regex.adoptInstead(NULL); 822 } 823 } 824 #endif /* !UCONFIG_NO_REGULAR_EXPRESSIONS */ 825 826 #if !UCONFIG_NO_TRANSLITERATION 827 { 828 IcuTestErrorCode errorCode(*this, "TestLocalXyzPointerNull/LocalUTransliteratorPointer"); 829 UnicodeString id=UNICODE_STRING_SIMPLE("Grek-Latn"); 830 LocalUTransliteratorPointer null; 831 LocalUTransliteratorPointer trans( 832 utrans_openU(id.getBuffer(), id.length(), UTRANS_FORWARD, NULL, 0, NULL, errorCode)); 833 if(!errorCode.errDataIfFailureAndReset("utrans_openU()")) { 834 trans.adoptInstead(NULL); 835 } 836 } 837 #endif /* !UCONFIG_NO_TRANSLITERATION */ 838 839 } 840 841 /** EnumSet test **/ 842 #include "unicode/enumset.h" 843 844 class EnumSetTest : public IntlTest { 845 public: 846 EnumSetTest() {} 847 virtual void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par=NULL); 848 void TestEnumSet(); 849 }; 850 851 static IntlTest *createEnumSetTest() { 852 return new EnumSetTest(); 853 } 854 855 void EnumSetTest::runIndexedTest(int32_t index, UBool exec, const char *&name, char * /*par*/) { 856 TESTCASE_AUTO_BEGIN; 857 TESTCASE_AUTO(TestEnumSet); 858 TESTCASE_AUTO_END; 859 } 860 enum myEnum { 861 MAX_NONBOOLEAN=-1, 862 THING1, 863 THING2, 864 THING3, 865 LIMIT_BOOLEAN 866 }; 867 868 void EnumSetTest::TestEnumSet() { 869 EnumSet<myEnum, 870 MAX_NONBOOLEAN+1, 871 LIMIT_BOOLEAN> 872 flags; 873 874 logln("Enum is from [%d..%d]\n", MAX_NONBOOLEAN+1, 875 LIMIT_BOOLEAN); 876 877 TEST_ASSERT_TRUE(flags.get(THING1) == FALSE); 878 TEST_ASSERT_TRUE(flags.get(THING2) == FALSE); 879 TEST_ASSERT_TRUE(flags.get(THING3) == FALSE); 880 881 logln("get(thing1)=%d, get(thing2)=%d, get(thing3)=%d\n", flags.get(THING1), flags.get(THING2), flags.get(THING3)); 882 logln("Value now: %d\n", flags.getAll()); 883 flags.clear(); 884 logln("clear -Value now: %d\n", flags.getAll()); 885 logln("get(thing1)=%d, get(thing2)=%d, get(thing3)=%d\n", flags.get(THING1), flags.get(THING2), flags.get(THING3)); 886 TEST_ASSERT_TRUE(flags.get(THING1) == FALSE); 887 TEST_ASSERT_TRUE(flags.get(THING2) == FALSE); 888 TEST_ASSERT_TRUE(flags.get(THING3) == FALSE); 889 flags.add(THING1); 890 logln("set THING1 -Value now: %d\n", flags.getAll()); 891 TEST_ASSERT_TRUE(flags.get(THING1) == TRUE); 892 TEST_ASSERT_TRUE(flags.get(THING2) == FALSE); 893 TEST_ASSERT_TRUE(flags.get(THING3) == FALSE); 894 logln("get(thing1)=%d, get(thing2)=%d, get(thing3)=%d\n", flags.get(THING1), flags.get(THING2), flags.get(THING3)); 895 flags.add(THING3); 896 logln("set THING3 -Value now: %d\n", flags.getAll()); 897 TEST_ASSERT_TRUE(flags.get(THING1) == TRUE); 898 TEST_ASSERT_TRUE(flags.get(THING2) == FALSE); 899 TEST_ASSERT_TRUE(flags.get(THING3) == TRUE); 900 logln("get(thing1)=%d, get(thing2)=%d, get(thing3)=%d\n", flags.get(THING1), flags.get(THING2), flags.get(THING3)); 901 flags.remove(THING2); 902 TEST_ASSERT_TRUE(flags.get(THING1) == TRUE); 903 TEST_ASSERT_TRUE(flags.get(THING2) == FALSE); 904 TEST_ASSERT_TRUE(flags.get(THING3) == TRUE); 905 logln("remove THING2 -Value now: %d\n", flags.getAll()); 906 logln("get(thing1)=%d, get(thing2)=%d, get(thing3)=%d\n", flags.get(THING1), flags.get(THING2), flags.get(THING3)); 907 flags.remove(THING1); 908 TEST_ASSERT_TRUE(flags.get(THING1) == FALSE); 909 TEST_ASSERT_TRUE(flags.get(THING2) == FALSE); 910 TEST_ASSERT_TRUE(flags.get(THING3) == TRUE); 911 logln("remove THING1 -Value now: %d\n", flags.getAll()); 912 logln("get(thing1)=%d, get(thing2)=%d, get(thing3)=%d\n", flags.get(THING1), flags.get(THING2), flags.get(THING3)); 913 914 flags.clear(); 915 logln("clear -Value now: %d\n", flags.getAll()); 916 logln("get(thing1)=%d, get(thing2)=%d, get(thing3)=%d\n", flags.get(THING1), flags.get(THING2), flags.get(THING3)); 917 TEST_ASSERT_TRUE(flags.get(THING1) == FALSE); 918 TEST_ASSERT_TRUE(flags.get(THING2) == FALSE); 919 TEST_ASSERT_TRUE(flags.get(THING3) == FALSE); 920 } 921