1 // 2016 and later: Unicode, Inc. and others. 2 // License & terms of use: http://www.unicode.org/copyright.html 3 /******************************************************************** 4 * Copyright (c) 1997-2016, International Business Machines 5 * Corporation and others. All Rights Reserved. 6 ********************************************************************/ 7 8 #include "unicode/utypes.h" 9 10 #include "cmemory.h" 11 #include "cstring.h" 12 #include "unicode/unistr.h" 13 #include "unicode/resbund.h" 14 #include "restsnew.h" 15 16 #include <stdlib.h> 17 #include <time.h> 18 #include <string.h> 19 #include <limits.h> 20 21 //*************************************************************************************** 22 23 static const UChar kErrorUChars[] = { 0x45, 0x52, 0x52, 0x4f, 0x52, 0 }; 24 static const int32_t kErrorLength = 5; 25 static const int32_t kERROR_COUNT = -1234567; 26 27 //*************************************************************************************** 28 29 enum E_Where 30 { 31 e_Root, 32 e_te, 33 e_te_IN, 34 e_Where_count 35 }; 36 37 //*************************************************************************************** 38 39 #define CONFIRM_EQ(actual,expected) if ((expected)==(actual)) { record_pass(); } else { record_fail(); errln(action + (UnicodeString)" returned " + (actual) + (UnicodeString)" instead of " + (expected)); } 40 #define CONFIRM_GE(actual,expected) if ((actual)>=(expected)) { record_pass(); } else { record_fail(); errln(action + (UnicodeString)" returned " + (actual) + (UnicodeString)" instead of x >= " + (expected)); } 41 #define CONFIRM_NE(actual,expected) if ((expected)!=(actual)) { record_pass(); } else { record_fail(); errln(action + (UnicodeString)" returned " + (actual) + (UnicodeString)" instead of x != " + (expected)); } 42 43 #define CONFIRM_UErrorCode(actual,expected) if ((expected)==(actual)) { record_pass(); } else { record_fail(); errln(action + (UnicodeString)" returned " + (UnicodeString)u_errorName(actual) + (UnicodeString)" instead of " + (UnicodeString)u_errorName(expected)); } 44 45 //*************************************************************************************** 46 47 /** 48 * Convert an integer, positive or negative, to a character string radix 10. 49 */ 50 static char* 51 itoa(int32_t i, char* buf) 52 { 53 char* result = buf; 54 55 // Handle negative 56 if (i < 0) 57 { 58 *buf++ = '-'; 59 i = -i; 60 } 61 62 // Output digits in reverse order 63 char* p = buf; 64 do 65 { 66 *p++ = (char)('0' + (i % 10)); 67 i /= 10; 68 } 69 while (i); 70 *p-- = 0; 71 72 // Reverse the string 73 while (buf < p) 74 { 75 char c = *buf; 76 *buf++ = *p; 77 *p-- = c; 78 } 79 80 return result; 81 } 82 83 84 85 //*************************************************************************************** 86 87 // Array of our test objects 88 89 static struct 90 { 91 const char* name; 92 Locale *locale; 93 UErrorCode expected_constructor_status; 94 E_Where where; 95 UBool like[e_Where_count]; 96 UBool inherits[e_Where_count]; 97 } 98 param[] = 99 { 100 // "te" means test 101 // "IN" means inherits 102 // "NE" or "ne" means "does not exist" 103 104 { "root", 0, U_ZERO_ERROR, e_Root, { TRUE, FALSE, FALSE }, { TRUE, FALSE, FALSE } }, 105 { "te", 0, U_ZERO_ERROR, e_te, { FALSE, TRUE, FALSE }, { TRUE, TRUE, FALSE } }, 106 { "te_IN", 0, U_ZERO_ERROR, e_te_IN, { FALSE, FALSE, TRUE }, { TRUE, TRUE, TRUE } }, 107 { "te_NE", 0, U_USING_FALLBACK_WARNING, e_te, { FALSE, TRUE, FALSE }, { TRUE, TRUE, FALSE } }, 108 { "te_IN_NE", 0, U_USING_FALLBACK_WARNING, e_te_IN, { FALSE, FALSE, TRUE }, { TRUE, TRUE, TRUE } }, 109 { "ne", 0, U_USING_DEFAULT_WARNING, e_Root, { TRUE, FALSE, FALSE }, { TRUE, FALSE, FALSE } } 110 }; 111 112 static int32_t bundles_count = UPRV_LENGTHOF(param); 113 114 //*************************************************************************************** 115 116 /** 117 * Return a random unsigned long l where 0N <= l <= ULONG_MAX. 118 */ 119 120 static uint32_t 121 randul() 122 { 123 static UBool initialized = FALSE; 124 if (!initialized) 125 { 126 srand((unsigned)time(NULL)); 127 initialized = TRUE; 128 } 129 // Assume rand has at least 12 bits of precision 130 uint32_t l = 0; 131 for (uint32_t i=0; i<sizeof(l); ++i) 132 ((char*)&l)[i] = (char)((rand() & 0x0FF0) >> 4); 133 return l; 134 } 135 136 /** 137 * Return a random double x where 0.0 <= x < 1.0. 138 */ 139 static double 140 randd() 141 { 142 return (double)(randul() / ULONG_MAX); 143 } 144 145 /** 146 * Return a random integer i where 0 <= i < n. 147 */ 148 static int32_t randi(int32_t n) 149 { 150 return (int32_t)(randd() * n); 151 } 152 153 //*************************************************************************************** 154 155 /* 156 Don't use more than one of these at a time because of the Locale names 157 */ 158 NewResourceBundleTest::NewResourceBundleTest() 159 : pass(0), 160 fail(0) 161 { 162 if (param[5].locale == NULL) { 163 param[0].locale = new Locale("root"); 164 param[1].locale = new Locale("te"); 165 param[2].locale = new Locale("te", "IN"); 166 param[3].locale = new Locale("te", "NE"); 167 param[4].locale = new Locale("te", "IN", "NE"); 168 param[5].locale = new Locale("ne"); 169 } 170 } 171 172 NewResourceBundleTest::~NewResourceBundleTest() 173 { 174 if (param[5].locale) { 175 int idx; 176 for (idx = 0; idx < UPRV_LENGTHOF(param); idx++) { 177 delete param[idx].locale; 178 param[idx].locale = NULL; 179 } 180 } 181 } 182 183 void NewResourceBundleTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ ) 184 { 185 if (exec) logln("TestSuite ResourceBundleTest: "); 186 switch (index) { 187 #if !UCONFIG_NO_FILE_IO && !UCONFIG_NO_LEGACY_CONVERSION 188 case 0: name = "TestResourceBundles"; if (exec) TestResourceBundles(); break; 189 case 1: name = "TestConstruction"; if (exec) TestConstruction(); break; 190 case 2: name = "TestIteration"; if (exec) TestIteration(); break; 191 case 3: name = "TestOtherAPI"; if(exec) TestOtherAPI(); break; 192 case 4: name = "TestNewTypes"; if(exec) TestNewTypes(); break; 193 #else 194 case 0: case 1: case 2: case 3: case 4: name = "skip"; break; 195 #endif 196 197 case 5: name = "TestGetByFallback"; if(exec) TestGetByFallback(); break; 198 default: name = ""; break; //needed to end loop 199 } 200 } 201 202 //*************************************************************************************** 203 204 void 205 NewResourceBundleTest::TestResourceBundles() 206 { 207 UErrorCode status = U_ZERO_ERROR; 208 loadTestData(status); 209 if(U_FAILURE(status)) 210 { 211 dataerrln("Could not load testdata.dat %s " + UnicodeString(u_errorName(status))); 212 return; 213 } 214 215 /* Make sure that users using te_IN for the default locale don't get test failures. */ 216 Locale originalDefault; 217 if (Locale::getDefault() == Locale("te_IN")) { 218 Locale::setDefault(Locale("en_US"), status); 219 } 220 221 testTag("only_in_Root", TRUE, FALSE, FALSE); 222 testTag("only_in_te", FALSE, TRUE, FALSE); 223 testTag("only_in_te_IN", FALSE, FALSE, TRUE); 224 testTag("in_Root_te", TRUE, TRUE, FALSE); 225 testTag("in_Root_te_te_IN", TRUE, TRUE, TRUE); 226 testTag("in_Root_te_IN", TRUE, FALSE, TRUE); 227 testTag("in_te_te_IN", FALSE, TRUE, TRUE); 228 testTag("nonexistent", FALSE, FALSE, FALSE); 229 logln("Passed: %d\nFailed: %d", pass, fail); 230 231 /* Restore the default locale for the other tests. */ 232 Locale::setDefault(originalDefault, status); 233 } 234 235 void 236 NewResourceBundleTest::TestConstruction() 237 { 238 UErrorCode err = U_ZERO_ERROR; 239 Locale locale("te", "IN"); 240 241 const char* testdatapath; 242 testdatapath=loadTestData(err); 243 if(U_FAILURE(err)) 244 { 245 dataerrln("Could not load testdata.dat %s " + UnicodeString(u_errorName(err))); 246 return; 247 } 248 249 /* Make sure that users using te_IN for the default locale don't get test failures. */ 250 Locale originalDefault; 251 if (Locale::getDefault() == Locale("te_IN")) { 252 Locale::setDefault(Locale("en_US"), err); 253 } 254 255 ResourceBundle test1((UnicodeString)testdatapath, err); 256 ResourceBundle test2(testdatapath, locale, err); 257 258 UnicodeString result1; 259 UnicodeString result2; 260 261 result1 = test1.getStringEx("string_in_Root_te_te_IN", err); 262 result2 = test2.getStringEx("string_in_Root_te_te_IN", err); 263 if (U_FAILURE(err)) { 264 errln("Something threw an error in TestConstruction()"); 265 return; 266 } 267 268 logln("for string_in_Root_te_te_IN, root.txt had " + result1); 269 logln("for string_in_Root_te_te_IN, te_IN.txt had " + result2); 270 271 if (result1 != "ROOT" || result2 != "TE_IN") { 272 errln("Construction test failed; run verbose for more information"); 273 } 274 275 const char* version1; 276 const char* version2; 277 278 version1 = test1.getVersionNumber(); 279 version2 = test2.getVersionNumber(); 280 281 char *versionID1 = new char[1 + strlen(U_ICU_VERSION) + strlen(version1)]; // + 1 for zero byte 282 char *versionID2 = new char[1 + strlen(U_ICU_VERSION) + strlen(version2)]; // + 1 for zero byte 283 284 strcpy(versionID1, "44.0"); // hardcoded, please change if the default.txt file or ResourceBundle::kVersionSeparater is changed. 285 286 strcpy(versionID2, "55.0"); // hardcoded, please change if the te_IN.txt file or ResourceBundle::kVersionSeparater is changed. 287 288 logln(UnicodeString("getVersionNumber on default.txt returned ") + version1 + UnicodeString(" Expect: " ) + versionID1); 289 logln(UnicodeString("getVersionNumber on te_IN.txt returned ") + version2 + UnicodeString(" Expect: " ) + versionID2); 290 291 if (strcmp(version1, versionID1) != 0) { 292 errln("getVersionNumber(version1) failed. %s != %s", version1, versionID1); 293 } 294 if (strcmp(version2, versionID2) != 0) { 295 errln("getVersionNumber(version2) failed. %s != %s", version2, versionID2); 296 } 297 delete[] versionID1; 298 delete[] versionID2; 299 300 /* Restore the default locale for the other tests. */ 301 Locale::setDefault(originalDefault, err); 302 } 303 304 void 305 NewResourceBundleTest::TestIteration() 306 { 307 UErrorCode err = U_ZERO_ERROR; 308 const char* testdatapath; 309 const char* data[]={ 310 "string_in_Root_te_te_IN", "1", 311 "array_in_Root_te_te_IN", "5", 312 "array_2d_in_Root_te_te_IN", "4", 313 }; 314 315 Locale *locale=new Locale("te_IN"); 316 317 testdatapath=loadTestData(err); 318 if(U_FAILURE(err)) 319 { 320 dataerrln("Could not load testdata.dat %s " + UnicodeString(u_errorName(err))); 321 return; 322 } 323 324 ResourceBundle test1(testdatapath, *locale, err); 325 if(U_FAILURE(err)){ 326 errln("Construction failed"); 327 } 328 uint32_t i; 329 int32_t count, row=0, col=0; 330 char buf[5]; 331 UnicodeString expected; 332 UnicodeString element("TE_IN"); 333 UnicodeString action; 334 335 336 for(i=0; i<UPRV_LENGTHOF(data); i=i+2){ 337 action = "te_IN"; 338 action +=".get("; 339 action += data[i]; 340 action +=", err)"; 341 err=U_ZERO_ERROR; 342 ResourceBundle bundle = test1.get(data[i], err); 343 if(!U_FAILURE(err)){ 344 action = "te_IN"; 345 action +=".getKey()"; 346 347 CONFIRM_EQ((UnicodeString)bundle.getKey(), (UnicodeString)data[i]); 348 349 count=0; 350 row=0; 351 while(bundle.hasNext()){ 352 action = data[i]; 353 action +=".getNextString(err)"; 354 row=count; 355 UnicodeString got=bundle.getNextString(err); 356 if(U_SUCCESS(err)){ 357 expected=element; 358 if(bundle.getSize() > 1){ 359 CONFIRM_EQ(bundle.getType(), URES_ARRAY); 360 expected+=itoa(row, buf); 361 ResourceBundle rowbundle=bundle.get(row, err); 362 if(!U_FAILURE(err) && rowbundle.getSize()>1){ 363 col=0; 364 while(rowbundle.hasNext()){ 365 expected=element; 366 got=rowbundle.getNextString(err); 367 if(!U_FAILURE(err)){ 368 expected+=itoa(row, buf); 369 expected+=itoa(col, buf); 370 col++; 371 CONFIRM_EQ(got, expected); 372 } 373 } 374 CONFIRM_EQ(col, rowbundle.getSize()); 375 } 376 } 377 else{ 378 CONFIRM_EQ(bundle.getType(), (int32_t)URES_STRING); 379 } 380 } 381 CONFIRM_EQ(got, expected); 382 count++; 383 } 384 action = data[i]; 385 action +=".getSize()"; 386 CONFIRM_EQ(bundle.getSize(), count); 387 CONFIRM_EQ(count, atoi(data[i+1])); 388 //after reaching the end 389 err=U_ZERO_ERROR; 390 ResourceBundle errbundle=bundle.getNext(err); 391 action = "After reaching the end of the Iterator:- "; 392 action +=data[i]; 393 action +=".getNext()"; 394 CONFIRM_NE(err, (int32_t)U_ZERO_ERROR); 395 CONFIRM_EQ(u_errorName(err), u_errorName(U_INDEX_OUTOFBOUNDS_ERROR)); 396 //reset the iterator 397 err = U_ZERO_ERROR; 398 bundle.resetIterator(); 399 /* The following code is causing a crash 400 ****CRASH****** 401 */ 402 403 bundle.getNext(err); 404 if(U_FAILURE(err)){ 405 errln("ERROR: getNext() throw an error"); 406 } 407 } 408 } 409 delete locale; 410 } 411 412 // TODO: add operator== and != to ResourceBundle 413 static UBool 414 equalRB(ResourceBundle &a, ResourceBundle &b) { 415 UResType type; 416 UErrorCode status; 417 418 type=a.getType(); 419 status=U_ZERO_ERROR; 420 return 421 type==b.getType() && 422 a.getLocale()==b.getLocale() && 423 0==strcmp(a.getName(), b.getName()) && 424 type==URES_STRING ? 425 a.getString(status)==b.getString(status) : 426 type==URES_INT ? 427 a.getInt(status)==b.getInt(status) : 428 TRUE; 429 } 430 431 void 432 NewResourceBundleTest::TestOtherAPI(){ 433 UErrorCode err = U_ZERO_ERROR; 434 const char* testdatapath=loadTestData(err); 435 UnicodeString tDataPathUS = UnicodeString(testdatapath, ""); 436 437 if(U_FAILURE(err)) 438 { 439 dataerrln("Could not load testdata.dat %s " + UnicodeString(u_errorName(err))); 440 return; 441 } 442 443 /* Make sure that users using te_IN for the default locale don't get test failures. */ 444 Locale originalDefault; 445 if (Locale::getDefault() == Locale("te_IN")) { 446 Locale::setDefault(Locale("en_US"), err); 447 } 448 449 Locale *locale=new Locale("te_IN"); 450 451 ResourceBundle test0(tDataPathUS, *locale, err); 452 if(U_FAILURE(err)){ 453 errln("Construction failed"); 454 return; 455 } 456 457 ResourceBundle test1(testdatapath, *locale, err); 458 if(U_FAILURE(err)){ 459 errln("Construction failed"); 460 return; 461 } 462 463 logln("Testing getLocale()\n"); 464 if(strcmp(test1.getLocale().getName(), locale->getName()) !=0 ){ 465 errln("FAIL: ResourceBundle::getLocale() failed\n"); 466 } 467 468 delete locale; 469 470 logln("Testing ResourceBundle(UErrorCode)\n"); 471 ResourceBundle defaultresource(err); 472 ResourceBundle explicitdefaultresource(NULL, Locale::getDefault(), err); 473 if(U_FAILURE(err)){ 474 errcheckln(err, "Construction of default resourcebundle failed - %s", u_errorName(err)); 475 return; 476 } 477 // You can't compare the default locale to the resolved locale in the 478 // resource bundle due to aliasing, keywords in the default locale 479 // or the chance that the machine running these tests is using a locale 480 // that isn't available in ICU. 481 if(strcmp(defaultresource.getLocale().getName(), explicitdefaultresource.getLocale().getName()) != 0){ 482 errln("Construction of default resourcebundle didn't take the defaultlocale. Expected %s Got %s err=%s\n", 483 explicitdefaultresource.getLocale().getName(), defaultresource.getLocale().getName(), u_errorName(err)); 484 } 485 486 487 ResourceBundle copyRes(defaultresource); 488 if(strcmp(copyRes.getName(), defaultresource.getName() ) !=0 || 489 strcmp(test1.getName(), defaultresource.getName() ) ==0 || 490 strcmp(copyRes.getLocale().getName(), defaultresource.getLocale().getName() ) !=0 || 491 strcmp(test1.getLocale().getName(), defaultresource.getLocale().getName() ) ==0 ) 492 { 493 errln("copy construction failed\n"); 494 } 495 496 ResourceBundle defaultSub = defaultresource.get((int32_t)0, err); 497 ResourceBundle defSubCopy(defaultSub); 498 if(strcmp(defSubCopy.getName(), defaultSub.getName() ) !=0 || 499 strcmp(defSubCopy.getLocale().getName(), defaultSub.getLocale().getName() ) !=0 ){ 500 errln("copy construction for subresource failed\n"); 501 } 502 503 ResourceBundle *p; 504 505 p = defaultresource.clone(); 506 if(p == &defaultresource || !equalRB(*p, defaultresource)) { 507 errln("ResourceBundle.clone() failed"); 508 } 509 delete p; 510 511 p = defaultSub.clone(); 512 if(p == &defaultSub || !equalRB(*p, defaultSub)) { 513 errln("2nd ResourceBundle.clone() failed"); 514 } 515 delete p; 516 517 UVersionInfo ver; 518 copyRes.getVersion(ver); 519 520 logln("Version returned: [%d.%d.%d.%d]\n", ver[0], ver[1], ver[2], ver[3]); 521 522 logln("Testing C like UnicodeString APIs\n"); 523 524 UResourceBundle *testCAPI = NULL, *bundle = NULL, *rowbundle = NULL, *temp = NULL; 525 err = U_ZERO_ERROR; 526 const char* data[]={ 527 "string_in_Root_te_te_IN", "1", 528 "array_in_Root_te_te_IN", "5", 529 "array_2d_in_Root_te_te_IN", "4", 530 }; 531 532 533 testCAPI = ures_open(testdatapath, "te_IN", &err); 534 535 if(U_SUCCESS(err)) { 536 // Do the testing 537 // first iteration 538 539 uint32_t i; 540 int32_t count, row=0, col=0; 541 char buf[5]; 542 UnicodeString expected; 543 UnicodeString element("TE_IN"); 544 UnicodeString action; 545 546 547 for(i=0; i<UPRV_LENGTHOF(data); i=i+2){ 548 action = "te_IN"; 549 action +=".get("; 550 action += data[i]; 551 action +=", err)"; 552 err=U_ZERO_ERROR; 553 bundle = ures_getByKey(testCAPI, data[i], bundle, &err); 554 if(!U_FAILURE(err)){ 555 const char* key = NULL; 556 action = "te_IN"; 557 action +=".getKey()"; 558 559 CONFIRM_EQ((UnicodeString)ures_getKey(bundle), (UnicodeString)data[i]); 560 561 count=0; 562 row=0; 563 while(ures_hasNext(bundle)){ 564 action = data[i]; 565 action +=".getNextString(err)"; 566 row=count; 567 UnicodeString got=ures_getNextUnicodeString(bundle, &key, &err); 568 if(U_SUCCESS(err)){ 569 expected=element; 570 if(ures_getSize(bundle) > 1){ 571 CONFIRM_EQ(ures_getType(bundle), URES_ARRAY); 572 expected+=itoa(row, buf); 573 rowbundle=ures_getByIndex(bundle, row, rowbundle, &err); 574 if(!U_FAILURE(err) && ures_getSize(rowbundle)>1){ 575 col=0; 576 while(ures_hasNext(rowbundle)){ 577 expected=element; 578 got=ures_getNextUnicodeString(rowbundle, &key, &err); 579 temp = ures_getByIndex(rowbundle, col, temp, &err); 580 UnicodeString bla = ures_getUnicodeString(temp, &err); 581 UnicodeString bla2 = ures_getUnicodeStringByIndex(rowbundle, col, &err); 582 if(!U_FAILURE(err)){ 583 expected+=itoa(row, buf); 584 expected+=itoa(col, buf); 585 col++; 586 CONFIRM_EQ(got, expected); 587 CONFIRM_EQ(bla, expected); 588 CONFIRM_EQ(bla2, expected); 589 } 590 } 591 CONFIRM_EQ(col, ures_getSize(rowbundle)); 592 } 593 } 594 else{ 595 CONFIRM_EQ(ures_getType(bundle), (int32_t)URES_STRING); 596 } 597 } 598 CONFIRM_EQ(got, expected); 599 count++; 600 } 601 } 602 } 603 604 // Check that ures_getUnicodeString() & variants return a bogus string if failure. 605 // Same relevant code path whether the failure code is passed in 606 // or comes from a lookup error. 607 UErrorCode failure = U_INTERNAL_PROGRAM_ERROR; 608 assertTrue("ures_getUnicodeString(failure).isBogus()", 609 ures_getUnicodeString(testCAPI, &failure).isBogus()); 610 assertTrue("ures_getNextUnicodeString(failure).isBogus()", 611 ures_getNextUnicodeString(testCAPI, NULL, &failure).isBogus()); 612 assertTrue("ures_getUnicodeStringByIndex(failure).isBogus()", 613 ures_getUnicodeStringByIndex(testCAPI, 999, &failure).isBogus()); 614 assertTrue("ures_getUnicodeStringByKey(failure).isBogus()", 615 ures_getUnicodeStringByKey(testCAPI, "bogus key", &failure).isBogus()); 616 617 ures_close(temp); 618 ures_close(rowbundle); 619 ures_close(bundle); 620 ures_close(testCAPI); 621 } else { 622 errln("failed to open a resource bundle\n"); 623 } 624 625 /* Restore the default locale for the other tests. */ 626 Locale::setDefault(originalDefault, err); 627 } 628 629 630 631 632 //*************************************************************************************** 633 634 UBool 635 NewResourceBundleTest::testTag(const char* frag, 636 UBool in_Root, 637 UBool in_te, 638 UBool in_te_IN) 639 { 640 int32_t failOrig = fail; 641 642 // Make array from input params 643 644 UBool is_in[] = { in_Root, in_te, in_te_IN }; 645 646 const char* NAME[] = { "ROOT", "TE", "TE_IN" }; 647 648 // Now try to load the desired items 649 650 char tag[100]; 651 UnicodeString action; 652 653 int32_t i,j,row,col, actual_bundle; 654 int32_t index; 655 const char* testdatapath; 656 657 UErrorCode status = U_ZERO_ERROR; 658 testdatapath=loadTestData(status); 659 if(U_FAILURE(status)) 660 { 661 dataerrln("Could not load testdata.dat %s " + UnicodeString(u_errorName(status))); 662 return FALSE; 663 } 664 665 for (i=0; i<bundles_count; ++i) 666 { 667 action = "Constructor for "; 668 action += param[i].name; 669 670 status = U_ZERO_ERROR; 671 ResourceBundle theBundle( testdatapath, *param[i].locale, status); 672 //ResourceBundle theBundle( "c:\\icu\\icu\\source\\test\\testdata\\testdata", *param[i].locale, status); 673 CONFIRM_UErrorCode(status,param[i].expected_constructor_status); 674 675 if(i == 5) 676 actual_bundle = 0; /* ne -> default */ 677 else if(i == 3) 678 actual_bundle = 1; /* te_NE -> te */ 679 else if(i == 4) 680 actual_bundle = 2; /* te_IN_NE -> te_IN */ 681 else 682 actual_bundle = i; 683 684 685 UErrorCode expected_resource_status = U_MISSING_RESOURCE_ERROR; 686 for (j=e_te_IN; j>=e_Root; --j) 687 { 688 if (is_in[j] && param[i].inherits[j]) 689 { 690 if(j == actual_bundle) /* it's in the same bundle OR it's a nonexistent=default bundle (5) */ 691 expected_resource_status = U_ZERO_ERROR; 692 else if(j == 0) 693 expected_resource_status = U_USING_DEFAULT_WARNING; 694 else 695 expected_resource_status = U_USING_FALLBACK_WARNING; 696 697 break; 698 } 699 } 700 701 UErrorCode expected_status; 702 703 UnicodeString base; 704 for (j=param[i].where; j>=0; --j) 705 { 706 if (is_in[j]) 707 { 708 base = NAME[j]; 709 break; 710 } 711 } 712 713 //-------------------------------------------------------------------------- 714 // string 715 716 uprv_strcpy(tag, "string_"); 717 uprv_strcat(tag, frag); 718 719 action = param[i].name; 720 action += ".getStringEx("; 721 action += tag; 722 action += ")"; 723 724 725 status = U_ZERO_ERROR; 726 UnicodeString string = theBundle.getStringEx(tag, status); 727 if(U_FAILURE(status)) { 728 string.setTo(TRUE, kErrorUChars, kErrorLength); 729 } 730 731 CONFIRM_UErrorCode(status, expected_resource_status); 732 733 UnicodeString expected_string(kErrorUChars); 734 if (U_SUCCESS(status)) { 735 expected_string = base; 736 } 737 738 CONFIRM_EQ(string, expected_string); 739 740 //-------------------------------------------------------------------------- 741 // array ResourceBundle using the key 742 743 uprv_strcpy(tag, "array_"); 744 uprv_strcat(tag, frag); 745 746 action = param[i].name; 747 action += ".get("; 748 action += tag; 749 action += ")"; 750 751 int32_t count = kERROR_COUNT; 752 status = U_ZERO_ERROR; 753 ResourceBundle array = theBundle.get(tag, status); 754 CONFIRM_UErrorCode(status,expected_resource_status); 755 756 757 if (U_SUCCESS(status)) 758 { 759 //confirm the resource type is an array 760 UResType bundleType=array.getType(); 761 CONFIRM_EQ(bundleType, URES_ARRAY); 762 763 count=array.getSize(); 764 CONFIRM_GE(count,1); 765 766 for (j=0; j<count; ++j) 767 { 768 char buf[32]; 769 expected_string = base; 770 expected_string += itoa(j,buf); 771 CONFIRM_EQ(array.getNextString(status),expected_string); 772 } 773 774 } 775 else 776 { 777 CONFIRM_EQ(count,kERROR_COUNT); 778 // CONFIRM_EQ((int32_t)(unsigned long)array,(int32_t)0); 779 count = 0; 780 } 781 782 //-------------------------------------------------------------------------- 783 // arrayItem ResourceBundle using the index 784 785 786 for (j=0; j<100; ++j) 787 { 788 index = count ? (randi(count * 3) - count) : (randi(200) - 100); 789 status = U_ZERO_ERROR; 790 string = kErrorUChars; 791 ResourceBundle array = theBundle.get(tag, status); 792 if(!U_FAILURE(status)){ 793 UnicodeString t = array.getStringEx(index, status); 794 if(!U_FAILURE(status)) { 795 string=t; 796 } 797 } 798 799 expected_status = (index >= 0 && index < count) ? expected_resource_status : U_MISSING_RESOURCE_ERROR; 800 CONFIRM_UErrorCode(status,expected_status); 801 802 if (U_SUCCESS(status)){ 803 char buf[32]; 804 expected_string = base; 805 expected_string += itoa(index,buf); 806 } else { 807 expected_string = kErrorUChars; 808 } 809 CONFIRM_EQ(string,expected_string); 810 811 } 812 813 //-------------------------------------------------------------------------- 814 // 2dArray 815 816 uprv_strcpy(tag, "array_2d_"); 817 uprv_strcat(tag, frag); 818 819 action = param[i].name; 820 action += ".get("; 821 action += tag; 822 action += ")"; 823 824 825 int32_t row_count = kERROR_COUNT, column_count = kERROR_COUNT; 826 status = U_ZERO_ERROR; 827 ResourceBundle array2d=theBundle.get(tag, status); 828 829 //const UnicodeString** array2d = theBundle.get2dArray(tag, row_count, column_count, status); 830 CONFIRM_UErrorCode(status,expected_resource_status); 831 832 if (U_SUCCESS(status)) 833 { 834 //confirm the resource type is an 2darray 835 UResType bundleType=array2d.getType(); 836 CONFIRM_EQ(bundleType, URES_ARRAY); 837 838 row_count=array2d.getSize(); 839 CONFIRM_GE(row_count,1); 840 841 for(row=0; row<row_count; ++row){ 842 ResourceBundle tablerow=array2d.get(row, status); 843 CONFIRM_UErrorCode(status, expected_resource_status); 844 if(U_SUCCESS(status)){ 845 //confirm the resourcetype of each table row is an array 846 UResType rowType=tablerow.getType(); 847 CONFIRM_EQ(rowType, URES_ARRAY); 848 849 column_count=tablerow.getSize(); 850 CONFIRM_GE(column_count,1); 851 852 for (col=0; j<column_count; ++j) { 853 char buf[32]; 854 expected_string = base; 855 expected_string += itoa(row,buf); 856 expected_string += itoa(col,buf); 857 CONFIRM_EQ(tablerow.getNextString(status),expected_string); 858 } 859 } 860 } 861 }else{ 862 CONFIRM_EQ(row_count,kERROR_COUNT); 863 CONFIRM_EQ(column_count,kERROR_COUNT); 864 row_count=column_count=0; 865 } 866 867 868 869 870 //-------------------------------------------------------------------------- 871 // 2dArrayItem 872 for (j=0; j<200; ++j) 873 { 874 row = row_count ? (randi(row_count * 3) - row_count) : (randi(200) - 100); 875 col = column_count ? (randi(column_count * 3) - column_count) : (randi(200) - 100); 876 status = U_ZERO_ERROR; 877 string = kErrorUChars; 878 ResourceBundle array2d=theBundle.get(tag, status); 879 if(U_SUCCESS(status)){ 880 ResourceBundle tablerow=array2d.get(row, status); 881 if(U_SUCCESS(status)) { 882 UnicodeString t=tablerow.getStringEx(col, status); 883 if(U_SUCCESS(status)){ 884 string=t; 885 } 886 } 887 } 888 expected_status = (row >= 0 && row < row_count && col >= 0 && col < column_count) ? 889 expected_resource_status: U_MISSING_RESOURCE_ERROR; 890 CONFIRM_UErrorCode(status,expected_status); 891 892 if (U_SUCCESS(status)){ 893 char buf[32]; 894 expected_string = base; 895 expected_string += itoa(row,buf); 896 expected_string += itoa(col,buf); 897 } else { 898 expected_string = kErrorUChars; 899 } 900 CONFIRM_EQ(string,expected_string); 901 902 } 903 904 //-------------------------------------------------------------------------- 905 // taggedArray 906 907 uprv_strcpy(tag, "tagged_array_"); 908 uprv_strcat(tag, frag); 909 910 action = param[i].name; 911 action += ".get("; 912 action += tag; 913 action += ")"; 914 915 int32_t tag_count; 916 status = U_ZERO_ERROR; 917 918 ResourceBundle tags=theBundle.get(tag, status); 919 CONFIRM_UErrorCode(status, expected_resource_status); 920 921 if (U_SUCCESS(status)) { 922 UResType bundleType=tags.getType(); 923 CONFIRM_EQ(bundleType, URES_TABLE); 924 925 tag_count=tags.getSize(); 926 CONFIRM_GE((int32_t)tag_count, (int32_t)0); 927 928 for(index=0; index <tag_count; index++){ 929 ResourceBundle tagelement=tags.get(index, status); 930 UnicodeString key=tagelement.getKey(); 931 UnicodeString value=tagelement.getNextString(status); 932 logln("tag = " + key + ", value = " + value ); 933 if(key.startsWith("tag") && value.startsWith(base)){ 934 record_pass(); 935 }else{ 936 record_fail(); 937 } 938 939 } 940 941 for(index=0; index <tag_count; index++){ 942 ResourceBundle tagelement=tags.get(index, status); 943 const char *tkey=NULL; 944 UnicodeString value=tagelement.getNextString(&tkey, status); 945 UnicodeString key(tkey); 946 logln("tag = " + key + ", value = " + value ); 947 if(value.startsWith(base)){ 948 record_pass(); 949 }else{ 950 record_fail(); 951 } 952 } 953 954 }else{ 955 tag_count=0; 956 } 957 958 959 960 961 //-------------------------------------------------------------------------- 962 // taggedArrayItem 963 964 action = param[i].name; 965 action += ".get("; 966 action += tag; 967 action += ")"; 968 969 count = 0; 970 for (index=-20; index<20; ++index) 971 { 972 char buf[32]; 973 status = U_ZERO_ERROR; 974 string = kErrorUChars; 975 char item_tag[8]; 976 uprv_strcpy(item_tag, "tag"); 977 uprv_strcat(item_tag, itoa(index,buf)); 978 ResourceBundle tags=theBundle.get(tag, status); 979 if(U_SUCCESS(status)){ 980 ResourceBundle tagelement=tags.get(item_tag, status); 981 if(!U_FAILURE(status)){ 982 UResType elementType=tagelement.getType(); 983 CONFIRM_EQ(elementType, (int32_t)URES_STRING); 984 const char* key=tagelement.getKey(); 985 CONFIRM_EQ((UnicodeString)key, (UnicodeString)item_tag); 986 UnicodeString t=tagelement.getString(status); 987 if(!U_FAILURE(status)){ 988 string=t; 989 } 990 } 991 if (index < 0) { 992 CONFIRM_UErrorCode(status,U_MISSING_RESOURCE_ERROR); 993 } 994 else{ 995 if (status != U_MISSING_RESOURCE_ERROR) { 996 count++; 997 expected_string = base; 998 expected_string += buf; 999 CONFIRM_EQ(string,expected_string); 1000 } 1001 } 1002 } 1003 1004 } 1005 CONFIRM_EQ(count, tag_count); 1006 1007 } 1008 return (UBool)(failOrig == fail); 1009 } 1010 1011 void 1012 NewResourceBundleTest::record_pass() 1013 { 1014 ++pass; 1015 } 1016 void 1017 NewResourceBundleTest::record_fail() 1018 { 1019 err(); 1020 ++fail; 1021 } 1022 1023 1024 void 1025 NewResourceBundleTest::TestNewTypes() { 1026 char action[256]; 1027 const char* testdatapath; 1028 UErrorCode status = U_ZERO_ERROR; 1029 uint8_t *binResult = NULL; 1030 int32_t len = 0; 1031 int32_t i = 0; 1032 int32_t intResult = 0; 1033 uint32_t uintResult = 0; 1034 UChar expected[] = { 'a','b','c','\0','d','e','f' }; 1035 const char* expect ="tab:\t cr:\r ff:\f newline:\n backslash:\\\\ quote=\\\' doubleQuote=\\\" singlequoutes=''"; 1036 UChar uExpect[200]; 1037 1038 testdatapath=loadTestData(status); 1039 1040 if(U_FAILURE(status)) 1041 { 1042 dataerrln("Could not load testdata.dat %s \n",u_errorName(status)); 1043 return; 1044 } 1045 1046 ResourceBundle theBundle(testdatapath, "testtypes", status); 1047 ResourceBundle bundle(testdatapath, Locale("te_IN"),status); 1048 1049 UnicodeString emptyStr = theBundle.getStringEx("emptystring", status); 1050 if(emptyStr.length() != 0) { 1051 logln("Empty string returned invalid value\n"); 1052 } 1053 1054 CONFIRM_UErrorCode(status, U_ZERO_ERROR); 1055 1056 /* This test reads the string "abc\u0000def" from the bundle */ 1057 /* if everything is working correctly, the size of this string */ 1058 /* should be 7. Everything else is a wrong answer, esp. 3 and 6*/ 1059 1060 strcpy(action, "getting and testing of string with embeded zero"); 1061 ResourceBundle res = theBundle.get("zerotest", status); 1062 CONFIRM_UErrorCode(status, U_ZERO_ERROR); 1063 CONFIRM_EQ(res.getType(), URES_STRING); 1064 UnicodeString zeroString=res.getString(status); 1065 len = zeroString.length(); 1066 if(U_SUCCESS(status)){ 1067 CONFIRM_UErrorCode(status, U_ZERO_ERROR); 1068 CONFIRM_EQ(len, 7); 1069 CONFIRM_NE(len, 3); 1070 } 1071 for(i=0;i<len;i++){ 1072 if(zeroString[i]!= expected[i]){ 1073 logln("Output didnot match Expected: \\u%4X Got: \\u%4X", expected[i], zeroString[i]); 1074 } 1075 } 1076 1077 strcpy(action, "getting and testing of binary type"); 1078 res = theBundle.get("binarytest", status); 1079 CONFIRM_UErrorCode(status, U_ZERO_ERROR); 1080 CONFIRM_EQ(res.getType(), URES_BINARY); 1081 binResult=(uint8_t*)res.getBinary(len, status); 1082 if(U_SUCCESS(status)){ 1083 CONFIRM_UErrorCode(status, U_ZERO_ERROR); 1084 CONFIRM_EQ(len, 15); 1085 for(i = 0; i<15; i++) { 1086 CONFIRM_EQ(binResult[i], i); 1087 } 1088 } 1089 1090 strcpy(action, "getting and testing of imported binary type"); 1091 res = theBundle.get("importtest",status); 1092 CONFIRM_UErrorCode(status, U_ZERO_ERROR); 1093 CONFIRM_EQ(res.getType(), URES_BINARY); 1094 binResult=(uint8_t*)res.getBinary(len, status); 1095 if(U_SUCCESS(status)){ 1096 CONFIRM_UErrorCode(status, U_ZERO_ERROR); 1097 CONFIRM_EQ(len, 15); 1098 for(i = 0; i<15; i++) { 1099 CONFIRM_EQ(binResult[i], i); 1100 } 1101 } 1102 1103 strcpy(action, "getting and testing of integer types"); 1104 res = theBundle.get("one", status); 1105 CONFIRM_UErrorCode(status, U_ZERO_ERROR); 1106 CONFIRM_EQ(res.getType(), URES_INT); 1107 intResult=res.getInt(status); 1108 uintResult = res.getUInt(status); 1109 if(U_SUCCESS(status)){ 1110 CONFIRM_UErrorCode(status, U_ZERO_ERROR); 1111 CONFIRM_EQ(uintResult, (uint32_t)intResult); 1112 CONFIRM_EQ(intResult, 1); 1113 } 1114 1115 strcpy(action, "getting minusone"); 1116 res = theBundle.get((const char*)"minusone", status); 1117 CONFIRM_UErrorCode(status, U_ZERO_ERROR); 1118 CONFIRM_EQ(res.getType(), URES_INT); 1119 intResult=res.getInt(status); 1120 uintResult = res.getUInt(status); 1121 if(U_SUCCESS(status)){ 1122 CONFIRM_UErrorCode(status, U_ZERO_ERROR); 1123 CONFIRM_EQ(uintResult, 0x0FFFFFFF); /* a 28 bit integer */ 1124 CONFIRM_EQ(intResult, -1); 1125 CONFIRM_NE(uintResult, (uint32_t)intResult); 1126 } 1127 1128 strcpy(action, "getting plusone"); 1129 res = theBundle.get("plusone",status); 1130 CONFIRM_UErrorCode(status, U_ZERO_ERROR); 1131 CONFIRM_EQ(res.getType(), URES_INT); 1132 intResult=res.getInt(status); 1133 uintResult = res.getUInt(status); 1134 if(U_SUCCESS(status)){ 1135 CONFIRM_UErrorCode(status, U_ZERO_ERROR); 1136 CONFIRM_EQ(uintResult, (uint32_t)intResult); 1137 CONFIRM_EQ(intResult, 1); 1138 } 1139 1140 res = theBundle.get("onehundredtwentythree",status); 1141 CONFIRM_UErrorCode(status, U_ZERO_ERROR); 1142 CONFIRM_EQ(res.getType(), URES_INT); 1143 intResult=res.getInt(status); 1144 if(U_SUCCESS(status)){ 1145 CONFIRM_UErrorCode(status, U_ZERO_ERROR); 1146 CONFIRM_EQ(intResult, 123); 1147 } 1148 1149 /* this tests if escapes are preserved or not */ 1150 { 1151 UnicodeString str = theBundle.getStringEx("testescape",status); 1152 CONFIRM_UErrorCode(status, U_ZERO_ERROR); 1153 if(U_SUCCESS(status)){ 1154 u_charsToUChars(expect,uExpect,(int32_t)uprv_strlen(expect)+1); 1155 if(str.compare(uExpect)!=0){ 1156 errln("Did not get the expected string for testescape expected. Expected : " 1157 +UnicodeString(uExpect )+ " Got: " + str); 1158 } 1159 } 1160 } 1161 /* test for jitterbug#1435 */ 1162 { 1163 UnicodeString str = theBundle.getStringEx("test_underscores",status); 1164 expect ="test message ...."; 1165 CONFIRM_UErrorCode(status, U_ZERO_ERROR); 1166 u_charsToUChars(expect,uExpect,(int32_t)uprv_strlen(expect)+1); 1167 if(str.compare(uExpect)!=0){ 1168 errln("Did not get the expected string for test_underscores.\n"); 1169 } 1170 } 1171 1172 1173 } 1174 1175 void 1176 NewResourceBundleTest::TestGetByFallback() { 1177 UErrorCode status = U_ZERO_ERROR; 1178 1179 ResourceBundle heRes(NULL, "he", status); 1180 1181 heRes.getWithFallback("calendar", status).getWithFallback("islamic-civil", status).getWithFallback("DateTime", status); 1182 if(U_SUCCESS(status)) { 1183 errln("he locale's Islamic-civil DateTime resource exists. How did it get here?\n"); 1184 } 1185 status = U_ZERO_ERROR; 1186 1187 heRes.getWithFallback("calendar", status).getWithFallback("islamic-civil", status).getWithFallback("eras", status); 1188 if(U_FAILURE(status)) { 1189 dataerrln("Didn't get Islamic Eras. I know they are there! - %s", u_errorName(status)); 1190 } 1191 status = U_ZERO_ERROR; 1192 1193 ResourceBundle rootRes(NULL, "root", status); 1194 rootRes.getWithFallback("calendar", status).getWithFallback("islamic-civil", status).getWithFallback("DateTime", status); 1195 if(U_SUCCESS(status)) { 1196 errln("Root's Islamic-civil's DateTime resource exists. How did it get here?\n"); 1197 } 1198 status = U_ZERO_ERROR; 1199 1200 } 1201 //eof 1202 1203