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