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*
itoa(int32_t i,char * buf)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
randul()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
randd()140 randd()
141 {
142 return (double)(randul() / ULONG_MAX);
143 }
144
145 /**
146 * Return a random integer i where 0 <= i < n.
147 */
randi(int32_t n)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 */
NewResourceBundleTest()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
~NewResourceBundleTest()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
runIndexedTest(int32_t index,UBool exec,const char * & name,char *)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
TestResourceBundles()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
TestConstruction()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
TestIteration()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
equalRB(ResourceBundle & a,ResourceBundle & b)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
TestOtherAPI()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
testTag(const char * frag,UBool in_Root,UBool in_te,UBool in_te_IN)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
record_pass()1012 NewResourceBundleTest::record_pass()
1013 {
1014 ++pass;
1015 }
1016 void
record_fail()1017 NewResourceBundleTest::record_fail()
1018 {
1019 err();
1020 ++fail;
1021 }
1022
1023
1024 void
TestNewTypes()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
TestGetByFallback()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