1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /********************************************************************
4 * COPYRIGHT:
5 * Copyright (c) 1997-2016, International Business Machines Corporation and
6 * others. All Rights Reserved.
7 ********************************************************************/
8 /*******************************************************************************
9 *
10 * File CRESTST.C
11 *
12 * Modification History:
13 * Name Description
14 * Madhu Katragadda Ported for C API
15 * 06/14/99 stephen Updated for RB API changes (no suffix).
16 ********************************************************************************
17 */
18
19
20 #include "unicode/utypes.h"
21 #include "cintltst.h"
22 #include "unicode/ustring.h"
23 #include "unicode/utf16.h"
24 #include "cmemory.h"
25 #include "cstring.h"
26 #include "filestrm.h"
27 #include <stdlib.h>
28
29 #define RESTEST_HEAP_CHECK 0
30
31 #include "unicode/ures.h"
32 #include "crestst.h"
33 #include "unicode/ctest.h"
34 #include "uresimp.h"
35
36 static void TestOpenDirect(void);
37 static void TestFallback(void);
38 static void TestTable32(void);
39 static void TestFileStream(void);
40 /*****************************************************************************/
41
42 const UChar kERROR[] = { 0x0045 /*E*/, 0x0052 /*'R'*/, 0x0052 /*'R'*/,
43 0x004F /*'O'*/, 0x0052/*'R'*/, 0x0000 /*'\0'*/};
44
45 /*****************************************************************************/
46
47 enum E_Where
48 {
49 e_Root,
50 e_te,
51 e_te_IN,
52 e_Where_count
53 };
54 typedef enum E_Where E_Where;
55 /*****************************************************************************/
56
57 #define CONFIRM_EQ(actual,expected) UPRV_BLOCK_MACRO_BEGIN { \
58 if (u_strcmp(expected,actual)==0) { \
59 record_pass(); \
60 } else { \
61 record_fail(); \
62 log_err("%s returned %s instead of %s\n", action, austrdup(actual), austrdup(expected)); \
63 } \
64 } UPRV_BLOCK_MACRO_END
65
66 #define CONFIRM_ErrorCode(actual,expected) UPRV_BLOCK_MACRO_BEGIN { \
67 if ((expected)==(actual)) { \
68 record_pass(); \
69 } else { \
70 record_fail(); \
71 log_err("%s returned %s instead of %s\n", action, myErrorName(actual), myErrorName(expected)); \
72 } \
73 } UPRV_BLOCK_MACRO_END
74
75
76 /* Array of our test objects */
77
78 static struct
79 {
80 const char* name;
81 UErrorCode expected_constructor_status;
82 E_Where where;
83 UBool like[e_Where_count];
84 UBool inherits[e_Where_count];
85 } param[] =
86 {
87 /* "te" means test */
88 /* "IN" means inherits */
89 /* "NE" or "ne" means "does not exist" */
90
91 { "root", U_ZERO_ERROR, e_Root, { TRUE, FALSE, FALSE }, { TRUE, FALSE, FALSE } },
92 { "te", U_ZERO_ERROR, e_te, { FALSE, TRUE, FALSE }, { TRUE, TRUE, FALSE } },
93 { "te_IN", U_ZERO_ERROR, e_te_IN, { FALSE, FALSE, TRUE }, { TRUE, TRUE, TRUE } },
94 { "te_NE", U_USING_FALLBACK_WARNING, e_te, { FALSE, TRUE, FALSE }, { TRUE, TRUE, FALSE } },
95 { "te_IN_NE", U_USING_FALLBACK_WARNING, e_te_IN, { FALSE, FALSE, TRUE }, { TRUE, TRUE, TRUE } },
96 { "ne", U_USING_DEFAULT_WARNING, e_Root, { TRUE, FALSE, FALSE }, { TRUE, FALSE, FALSE } }
97 };
98
99 static int32_t bundles_count = UPRV_LENGTHOF(param);
100
101
102
103 /***************************************************************************************/
104
105 /* Array of our test objects */
106
107 void addResourceBundleTest(TestNode** root);
108
addResourceBundleTest(TestNode ** root)109 void addResourceBundleTest(TestNode** root)
110 {
111 #if !UCONFIG_NO_FILE_IO && !UCONFIG_NO_LEGACY_CONVERSION
112 addTest(root, &TestConstruction1, "tsutil/crestst/TestConstruction1");
113 addTest(root, &TestOpenDirect, "tsutil/crestst/TestOpenDirect");
114 addTest(root, &TestResourceBundles, "tsutil/crestst/TestResourceBundles");
115 addTest(root, &TestTable32, "tsutil/crestst/TestTable32");
116 addTest(root, &TestFileStream, "tsutil/crestst/TestFileStream");
117 addTest(root, &TestGetSize, "tsutil/crestst/TestGetSize");
118 addTest(root, &TestGetLocaleByType, "tsutil/crestst/TestGetLocaleByType");
119 #endif
120 addTest(root, &TestFallback, "tsutil/crestst/TestFallback");
121 addTest(root, &TestAliasConflict, "tsutil/crestst/TestAliasConflict");
122
123 }
124
125
126 /***************************************************************************************/
TestAliasConflict(void)127 void TestAliasConflict(void) {
128 UErrorCode status = U_ZERO_ERROR;
129 UResourceBundle *he = NULL;
130 UResourceBundle *iw = NULL;
131 const UChar *result = NULL;
132 int32_t resultLen;
133
134 he = ures_open(NULL, "he", &status);
135 iw = ures_open(NULL, "iw", &status);
136 if(U_FAILURE(status)) {
137 log_err_status(status, "Failed to get resource with %s\n", myErrorName(status));
138 }
139 ures_close(iw);
140 result = ures_getStringByKey(he, "ExemplarCharacters", &resultLen, &status);
141 if(U_FAILURE(status) || result == NULL) {
142 log_err_status(status, "Failed to get resource with %s\n", myErrorName(status));
143 }
144 ures_close(he);
145 }
146
147
TestResourceBundles()148 void TestResourceBundles()
149 {
150 // The test expectation only works if the default locale is not one of the
151 // locale bundle in the testdata which have those info. Therefore, we skip
152 // the test if the default locale is te, sh, mc, or them with subtags.
153 if ( uprv_strncmp(uloc_getDefault(), "te", 2) == 0 ||
154 uprv_strncmp(uloc_getDefault(), "sh", 2) == 0 ||
155 uprv_strncmp(uloc_getDefault(), "mc", 2) == 0) {
156 return;
157 }
158
159 UErrorCode status = U_ZERO_ERROR;
160 loadTestData(&status);
161 if(U_FAILURE(status)) {
162 log_data_err("Could not load testdata.dat, status = %s\n", u_errorName(status));
163 return;
164 }
165
166 testTag("only_in_Root", TRUE, FALSE, FALSE);
167 testTag("in_Root_te", TRUE, TRUE, FALSE);
168 testTag("in_Root_te_te_IN", TRUE, TRUE, TRUE);
169 testTag("in_Root_te_IN", TRUE, FALSE, TRUE);
170 testTag("only_in_te", FALSE, TRUE, FALSE);
171 testTag("only_in_te_IN", FALSE, FALSE, TRUE);
172 testTag("in_te_te_IN", FALSE, TRUE, TRUE);
173 testTag("nonexistent", FALSE, FALSE, FALSE);
174
175 log_verbose("Passed:= %d Failed= %d \n", pass, fail);
176 }
177
TestConstruction1()178 void TestConstruction1()
179 {
180 UResourceBundle *test1 = 0, *test2 = 0;
181 const UChar *result1, *result2;
182 int32_t resultLen;
183 UChar temp[7];
184
185 UErrorCode err = U_ZERO_ERROR;
186 const char* testdatapath ;
187 const char* locale="te_IN";
188
189 log_verbose("Testing ures_open()......\n");
190
191
192 testdatapath=loadTestData(&err);
193 if(U_FAILURE(err))
194 {
195 log_data_err("Could not load testdata.dat %s \n",myErrorName(err));
196 return;
197 }
198
199 test1=ures_open(testdatapath, NULL, &err);
200 if(U_FAILURE(err))
201 {
202 log_err("construction of %s did not succeed : %s \n",NULL, myErrorName(err));
203 return;
204 }
205
206
207 test2=ures_open(testdatapath, locale, &err);
208 if(U_FAILURE(err))
209 {
210 log_err("construction of %s did not succeed : %s \n",locale, myErrorName(err));
211 return;
212 }
213 result1= ures_getStringByKey(test1, "string_in_Root_te_te_IN", &resultLen, &err);
214 result2= ures_getStringByKey(test2, "string_in_Root_te_te_IN", &resultLen, &err);
215
216
217 if (U_FAILURE(err)) {
218 log_err("Something threw an error in TestConstruction(): %s\n", myErrorName(err));
219 return;
220 }
221
222 u_uastrcpy(temp, "TE_IN");
223
224 if(u_strcmp(result2, temp)!=0)
225 {
226 int n;
227
228 log_err("Construction test failed for ures_open();\n");
229 if(!getTestOption(VERBOSITY_OPTION))
230 log_info("(run verbose for more information)\n");
231
232 log_verbose("\nGot->");
233 for(n=0;result2[n];n++)
234 {
235 log_verbose("%04X ",result2[n]);
236 }
237 log_verbose("<\n");
238
239 log_verbose("\nWant>");
240 for(n=0;temp[n];n++)
241 {
242 log_verbose("%04X ",temp[n]);
243 }
244 log_verbose("<\n");
245
246 }
247
248 log_verbose("for string_in_Root_te_te_IN, default.txt had %s\n", austrdup(result1));
249 log_verbose("for string_in_Root_te_te_IN, te_IN.txt had %s\n", austrdup(result2));
250
251 /* Test getVersionNumber*/
252 log_verbose("Testing version number\n");
253 log_verbose("for getVersionNumber : %s\n", ures_getVersionNumber(test1));
254
255 ures_close(test1);
256 ures_close(test2);
257 }
258
259 /*****************************************************************************/
260 /*****************************************************************************/
261
testTag(const char * frag,UBool in_Root,UBool in_te,UBool in_te_IN)262 UBool testTag(const char* frag,
263 UBool in_Root,
264 UBool in_te,
265 UBool in_te_IN)
266 {
267 int32_t passNum=pass;
268
269 /* Make array from input params */
270
271 UBool is_in[3];
272 const char *NAME[] = { "ROOT", "TE", "TE_IN" };
273
274 /* Now try to load the desired items */
275 UResourceBundle* theBundle = NULL;
276 char tag[99];
277 char action[256];
278 UErrorCode status = U_ZERO_ERROR,expected_resource_status = U_ZERO_ERROR;
279 UChar* base = NULL;
280 UChar* expected_string = NULL;
281 const UChar* string = NULL;
282 char item_tag[10];
283 int32_t i,j;
284 int32_t actual_bundle;
285 int32_t resultLen;
286 const char *testdatapath = loadTestData(&status);
287
288 is_in[0] = in_Root;
289 is_in[1] = in_te;
290 is_in[2] = in_te_IN;
291
292 strcpy(item_tag, "tag");
293
294 status = U_ZERO_ERROR;
295 theBundle = ures_open(testdatapath, "root", &status);
296 if(U_FAILURE(status))
297 {
298 ures_close(theBundle);
299 log_err("Couldn't open root bundle in %s", testdatapath);
300 return FALSE;
301 }
302 ures_close(theBundle);
303 theBundle = NULL;
304
305
306 for (i=0; i<bundles_count; ++i)
307 {
308 strcpy(action,"construction for");
309 strcat(action, param[i].name);
310
311
312 status = U_ZERO_ERROR;
313
314 theBundle = ures_open(testdatapath, param[i].name, &status);
315 /*theBundle = ures_open("c:\\icu\\icu\\source\\test\\testdata\\testdata", param[i].name, &status);*/
316
317 CONFIRM_ErrorCode(status,param[i].expected_constructor_status);
318
319
320
321 if(i == 5)
322 actual_bundle = 0; /* ne -> default */
323 else if(i == 3)
324 actual_bundle = 1; /* te_NE -> te */
325 else if(i == 4)
326 actual_bundle = 2; /* te_IN_NE -> te_IN */
327 else
328 actual_bundle = i;
329
330 expected_resource_status = U_MISSING_RESOURCE_ERROR;
331 for (j=e_te_IN; j>=e_Root; --j)
332 {
333 if (is_in[j] && param[i].inherits[j])
334 {
335
336 if(j == actual_bundle) /* it's in the same bundle OR it's a nonexistent=default bundle (5) */
337 expected_resource_status = U_ZERO_ERROR;
338 else if(j == 0)
339 expected_resource_status = U_USING_DEFAULT_WARNING;
340 else
341 expected_resource_status = U_USING_FALLBACK_WARNING;
342
343 log_verbose("%s[%d]::%s: in<%d:%s> inherits<%d:%s>. actual_bundle=%s\n",
344 param[i].name,
345 i,
346 frag,
347 j,
348 is_in[j]?"Yes":"No",
349 j,
350 param[i].inherits[j]?"Yes":"No",
351 param[actual_bundle].name);
352
353 break;
354 }
355 }
356
357 for (j=param[i].where; j>=0; --j)
358 {
359 if (is_in[j])
360 {
361 if(base != NULL) {
362 free(base);
363 base = NULL;
364 }
365
366 base=(UChar*)malloc(sizeof(UChar)*(strlen(NAME[j]) + 1));
367 u_uastrcpy(base,NAME[j]);
368
369 break;
370 }
371 else {
372 if(base != NULL) {
373 free(base);
374 base = NULL;
375 }
376 base = (UChar*) malloc(sizeof(UChar) * 1);
377 *base = 0x0000;
378 }
379 }
380
381 /*-------------------------------------------------------------------- */
382 /* string */
383
384 strcpy(tag,"string_");
385 strcat(tag,frag);
386
387 strcpy(action,param[i].name);
388 strcat(action, ".ures_get(" );
389 strcat(action,tag);
390 strcat(action, ")");
391
392 string= kERROR;
393
394 status = U_ZERO_ERROR;
395
396 ures_getStringByKey(theBundle, tag, &resultLen, &status);
397 if(U_SUCCESS(status))
398 {
399 status = U_ZERO_ERROR;
400 string=ures_getStringByKey(theBundle, tag, &resultLen, &status);
401 }
402
403 log_verbose("%s got %d, expected %d\n", action, status, expected_resource_status);
404
405 CONFIRM_ErrorCode(status, expected_resource_status);
406
407
408 if(U_SUCCESS(status)){
409 expected_string=(UChar*)malloc(sizeof(UChar)*(u_strlen(base) + 3));
410 u_strcpy(expected_string,base);
411
412 }
413 else
414 {
415 expected_string = (UChar*)malloc(sizeof(UChar)*(u_strlen(kERROR) + 1));
416 u_strcpy(expected_string,kERROR);
417
418 }
419
420 CONFIRM_EQ(string, expected_string);
421
422 free(expected_string);
423 ures_close(theBundle);
424 }
425 free(base);
426 return (UBool)(passNum == pass);
427 }
428
record_pass()429 void record_pass()
430 {
431 ++pass;
432 }
433
record_fail()434 void record_fail()
435 {
436 ++fail;
437 }
438
439 /**
440 * Test to make sure that the U_USING_FALLBACK_ERROR and U_USING_DEFAULT_ERROR
441 * are set correctly
442 */
443
TestFallback()444 static void TestFallback()
445 {
446 UErrorCode status = U_ZERO_ERROR;
447 UResourceBundle *fr_FR = NULL;
448 UResourceBundle *subResource = NULL;
449 const UChar *junk; /* ignored */
450 int32_t resultLen;
451
452 log_verbose("Opening fr_FR..");
453 fr_FR = ures_open(NULL, "fr_FR", &status);
454 if(U_FAILURE(status))
455 {
456 log_err_status(status, "Couldn't open fr_FR - %s\n", u_errorName(status));
457 return;
458 }
459
460 status = U_ZERO_ERROR;
461
462
463 /* clear it out.. just do some calls to get the gears turning */
464 junk = ures_getStringByKey(fr_FR, "LocaleID", &resultLen, &status);
465 (void)junk; /* Suppress set but not used warning. */
466 status = U_ZERO_ERROR;
467 junk = ures_getStringByKey(fr_FR, "LocaleString", &resultLen, &status);
468 status = U_ZERO_ERROR;
469 junk = ures_getStringByKey(fr_FR, "LocaleID", &resultLen, &status);
470 status = U_ZERO_ERROR;
471
472 /* OK first one. This should be a Default value. */
473 subResource = ures_getByKey(fr_FR, "layout", NULL, &status);
474 if(status != U_USING_DEFAULT_WARNING)
475 {
476 log_data_err("Expected U_USING_DEFAULT_ERROR when trying to get layout from fr_FR, got %s\n",
477 u_errorName(status));
478 }
479 ures_close(subResource);
480 status = U_ZERO_ERROR;
481
482 /* and this is a Fallback, to fr */
483 junk = ures_getStringByKey(fr_FR, "ExemplarCharacters", &resultLen, &status);
484 if(status != U_USING_FALLBACK_WARNING)
485 {
486 log_data_err("Expected U_USING_FALLBACK_ERROR when trying to get ExemplarCharacters from fr_FR, got %s\n",
487 u_errorName(status));
488 }
489
490 status = U_ZERO_ERROR;
491
492 ures_close(fr_FR);
493 }
494
495 static void
TestOpenDirect(void)496 TestOpenDirect(void) {
497 UResourceBundle *idna_rules, *casing, *te_IN, *ne, *item, *defaultLocale;
498 UErrorCode errorCode;
499
500 /*
501 * test that ures_openDirect() opens a resource bundle
502 * where one can look up its own items but not fallback items
503 * from root or similar
504 */
505 errorCode=U_ZERO_ERROR;
506 idna_rules=ures_openDirect(loadTestData(&errorCode), "idna_rules", &errorCode);
507 if(U_FAILURE(errorCode)) {
508 log_data_err("ures_openDirect(\"idna_rules\") failed: %s\n", u_errorName(errorCode));
509 return;
510 }
511
512 if(0!=uprv_strcmp("idna_rules", ures_getLocale(idna_rules, &errorCode))) {
513 log_err("ures_openDirect(\"idna_rules\").getLocale()!=idna_rules\n");
514 }
515 errorCode=U_ZERO_ERROR;
516
517 /* try an item in idna_rules, must work */
518 item=ures_getByKey(idna_rules, "UnassignedSet", NULL, &errorCode);
519 if(U_FAILURE(errorCode)) {
520 log_err("translit_index.getByKey(local key) failed: %s\n", u_errorName(errorCode));
521 errorCode=U_ZERO_ERROR;
522 } else {
523 ures_close(item);
524 }
525
526 /* try an item in root, must fail */
527 item=ures_getByKey(idna_rules, "ShortLanguage", NULL, &errorCode);
528 if(U_FAILURE(errorCode)) {
529 errorCode=U_ZERO_ERROR;
530 } else {
531 log_err("idna_rules.getByKey(root key) succeeded!\n");
532 ures_close(item);
533 }
534 ures_close(idna_rules);
535
536 /* now make sure that "idna_rules" will not work with ures_open() */
537 errorCode=U_ZERO_ERROR;
538 idna_rules=ures_open("testdata", "idna_rules", &errorCode);
539 if(U_FAILURE(errorCode) || errorCode==U_USING_DEFAULT_WARNING || errorCode==U_USING_FALLBACK_WARNING) {
540 /* falling back to default or root is ok */
541 errorCode=U_ZERO_ERROR;
542 } else if(0!=uprv_strcmp("idna_rules", ures_getLocale(idna_rules, &errorCode))) {
543 /* Opening this file will work in "files mode" on Windows and the Mac,
544 which have case insensitive file systems */
545 log_err("ures_open(\"idna_rules\") succeeded, should fail! Got: %s\n", u_errorName(errorCode));
546 }
547 ures_close(idna_rules);
548
549 /* ures_openDirect("translit_index_WronG") must fail */
550 idna_rules=ures_openDirect(NULL, "idna_rules_WronG", &errorCode);
551 if(U_FAILURE(errorCode)) {
552 errorCode=U_ZERO_ERROR;
553 } else {
554 log_err("ures_openDirect(\"idna_rules_WronG\") succeeded, should fail!\n");
555 }
556 ures_close(idna_rules);
557
558 errorCode = U_USING_FALLBACK_WARNING;
559 idna_rules=ures_openDirect("testdata", "idna_rules", &errorCode);
560 if(U_FAILURE(errorCode)) {
561 log_data_err("ures_openDirect(\"idna_rules\") failed when U_USING_FALLBACK_WARNING was set prior to call: %s\n", u_errorName(errorCode));
562 return;
563 }
564 ures_close(idna_rules);
565
566 /*
567 * ICU 3.6 has new resource bundle syntax and data for bundles that do not
568 * participate in locale fallback. Now,
569 * - ures_open() works like ures_openDirect() on a bundle with a top-level
570 * type of ":table(nofallback)" _if_ the bundle exists
571 * - ures_open() will continue to find a root bundle if the requested one
572 * does not exist, unlike ures_openDirect()
573 *
574 * Test with a different bundle than above to avoid confusion in the cache.
575 */
576
577 /*
578 * verify that ures_open("casing"), which now has a nofallback declaration,
579 * does not enable fallbacks
580 */
581 errorCode=U_ZERO_ERROR;
582 casing=ures_open("testdata", "casing", &errorCode);
583 if(U_FAILURE(errorCode)) {
584 log_data_err("ures_open(\"casing\") failed: %s\n", u_errorName(errorCode));
585 return;
586 }
587
588 errorCode=U_ZERO_ERROR;
589 item=ures_getByKey(casing, "Info", NULL, &errorCode);
590 if(U_FAILURE(errorCode)) {
591 log_err("casing.getByKey(Info) failed - %s\n", u_errorName(errorCode));
592 } else {
593 ures_close(item);
594 }
595
596 errorCode=U_ZERO_ERROR;
597 item=ures_getByKey(casing, "ShortLanguage", NULL, &errorCode);
598 if(U_SUCCESS(errorCode)) {
599 log_err("casing.getByKey(root key) succeeded despite nofallback declaration - %s\n", u_errorName(errorCode));
600 ures_close(item);
601 }
602 ures_close(casing);
603
604 /*
605 * verify that ures_open("ne") finds the root bundle or default locale
606 * bundle but ures_openDirect("ne") does not.
607 */
608 errorCode=U_ZERO_ERROR;
609 ne=ures_open("testdata", "ne", &errorCode);
610 if(U_FAILURE(errorCode)) {
611 log_data_err("ures_open(\"ne\") failed (expected to get root): %s\n", u_errorName(errorCode));
612 }
613 if( errorCode!=U_USING_DEFAULT_WARNING ||
614 (0!=uprv_strcmp("root", ures_getLocale(ne, &errorCode)) &&
615 0!=uprv_strcmp(uloc_getDefault(), ures_getLocale(ne, &errorCode)))) {
616 log_err("ures_open(\"ne\") found something other than \"root\" "
617 "or default locale \"%s\" - %s\n", uloc_getDefault(), u_errorName(errorCode));
618 }
619 ures_close(ne);
620
621 errorCode=U_ZERO_ERROR;
622 ne=ures_openDirect("testdata", "ne", &errorCode);
623 if(U_SUCCESS(errorCode)) {
624 log_data_err("ures_openDirect(\"ne\") succeeded unexpectedly\n");
625 ures_close(ne);
626 }
627
628 /* verify that ures_openDirect("te_IN") does not enable fallbacks */
629 errorCode=U_ZERO_ERROR;
630 te_IN=ures_openDirect("testdata", "te_IN", &errorCode);
631 if(U_FAILURE(errorCode)) {
632 log_data_err("ures_open(\"te_IN\") failed: %s\n", u_errorName(errorCode));
633 return;
634 }
635 errorCode=U_ZERO_ERROR;
636 item=ures_getByKey(te_IN, "ShortLanguage", NULL, &errorCode);
637 if(U_SUCCESS(errorCode)) {
638 log_err("te_IN.getByKey(root key) succeeded despite use of ures_openDirect() - %s\n", u_errorName(errorCode));
639 ures_close(item);
640 }
641 ures_close(te_IN);
642
643 // ICU-21705
644 // Verify that calling ures_openDirect() with a NULL localeID doesn't crash or assert.
645 errorCode = U_ZERO_ERROR;
646 defaultLocale = ures_openDirect(NULL, NULL, &errorCode);
647 ures_close(defaultLocale);
648 }
649
650 static int32_t
parseTable32Key(const char * key)651 parseTable32Key(const char *key) {
652 int32_t number;
653 char c;
654
655 number=0;
656 while((c=*key++)!=0) {
657 number<<=1;
658 if(c=='1') {
659 number|=1;
660 }
661 }
662 return number;
663 }
664
665 static void
TestTable32(void)666 TestTable32(void) {
667 static const struct {
668 const char *key;
669 int32_t number;
670 } testcases[]={
671 { "ooooooooooooooooo", 0 },
672 { "oooooooooooooooo1", 1 },
673 { "ooooooooooooooo1o", 2 },
674 { "oo11ooo1ooo11111o", 25150 },
675 { "oo11ooo1ooo111111", 25151 },
676 { "o1111111111111111", 65535 },
677 { "1oooooooooooooooo", 65536 },
678 { "1ooooooo11o11ooo1", 65969 },
679 { "1ooooooo11o11oo1o", 65970 },
680 { "1ooooooo111oo1111", 65999 }
681 };
682
683 /* ### TODO UResourceBundle staticItem={ 0 }; - need to know the size */
684 UResourceBundle *res, *item;
685 const UChar *s;
686 const char *key;
687 UErrorCode errorCode;
688 int32_t i, j, number, parsedNumber, length, count;
689
690 errorCode=U_ZERO_ERROR;
691 res=ures_open(loadTestData(&errorCode), "testtable32", &errorCode);
692 if(U_FAILURE(errorCode)) {
693 log_data_err("unable to open testdata/testtable32.res - %s\n", u_errorName(errorCode));
694 return;
695 }
696 if(ures_getType(res)!=URES_TABLE) {
697 log_data_err("testdata/testtable32.res has type %d instead of URES_TABLE\n", ures_getType(res));
698 }
699
700 count=ures_getSize(res);
701 if(count!=66000) {
702 log_err("testdata/testtable32.res should have 66000 entries but has %d\n", count);
703 }
704
705 /* get the items by index */
706 item=NULL;
707 for(i=0; i<count; ++i) {
708 item=ures_getByIndex(res, i, item, &errorCode);
709 if(U_FAILURE(errorCode)) {
710 log_err("unable to get item %d of %d in testdata/testtable32.res - %s\n",
711 i, count, u_errorName(errorCode));
712 break;
713 }
714
715 key=ures_getKey(item);
716 parsedNumber=parseTable32Key(key);
717
718 switch(ures_getType(item)) {
719 case URES_STRING:
720 s=ures_getString(item, &length, &errorCode);
721 if(U_FAILURE(errorCode) || s==NULL) {
722 log_err("unable to access the string \"%s\" at %d in testdata/testtable32.res - %s\n",
723 key, i, u_errorName(errorCode));
724 number=-1;
725 } else {
726 j=0;
727 U16_NEXT(s, j, length, number);
728 }
729 break;
730 case URES_INT:
731 number=ures_getInt(item, &errorCode);
732 if(U_FAILURE(errorCode)) {
733 log_err("unable to access the integer \"%s\" at %d in testdata/testtable32.res - %s\n",
734 key, i, u_errorName(errorCode));
735 number=-1;
736 }
737 break;
738 default:
739 log_err("unexpected resource type %d for \"%s\" at %d in testdata/testtable32.res - %s\n",
740 ures_getType(item), key, i, u_errorName(errorCode));
741 number=-1;
742 break;
743 }
744
745 if(number>=0 && number!=parsedNumber) {
746 log_err("\"%s\" at %d in testdata/testtable32.res has a string/int value of %d, expected %d\n",
747 key, i, number, parsedNumber);
748 }
749 }
750
751 /* search for some items by key */
752 for(i=0; i<UPRV_LENGTHOF(testcases); ++i) {
753 item=ures_getByKey(res, testcases[i].key, item, &errorCode);
754 if(U_FAILURE(errorCode)) {
755 log_err("unable to find the key \"%s\" in testdata/testtable32.res - %s\n",
756 testcases[i].key, u_errorName(errorCode));
757 continue;
758 }
759
760 switch(ures_getType(item)) {
761 case URES_STRING:
762 s=ures_getString(item, &length, &errorCode);
763 if(U_FAILURE(errorCode) || s==NULL) {
764 log_err("unable to access the string \"%s\" in testdata/testtable32.res - %s\n",
765 testcases[i].key, u_errorName(errorCode));
766 number=-1;
767 } else {
768 j=0;
769 U16_NEXT(s, j, length, number);
770 }
771 break;
772 case URES_INT:
773 number=ures_getInt(item, &errorCode);
774 if(U_FAILURE(errorCode)) {
775 log_err("unable to access the integer \"%s\" in testdata/testtable32.res - %s\n",
776 testcases[i].key, u_errorName(errorCode));
777 number=-1;
778 }
779 break;
780 default:
781 log_err("unexpected resource type %d for \"%s\" in testdata/testtable32.res - %s\n",
782 ures_getType(item), testcases[i].key, u_errorName(errorCode));
783 number=-1;
784 break;
785 }
786
787 if(number>=0 && number!=testcases[i].number) {
788 log_err("\"%s\" in testdata/testtable32.res has a string/int value of %d, expected %d\n",
789 testcases[i].key, number, testcases[i].number);
790 }
791
792 key=ures_getKey(item);
793 if(0!=uprv_strcmp(key, testcases[i].key)) {
794 log_err("\"%s\" in testdata/testtable32.res claims to have the key \"%s\"\n",
795 testcases[i].key, key);
796 }
797 }
798
799 ures_close(item);
800 ures_close(res);
801 }
802
TestFileStream(void)803 static void TestFileStream(void){
804 int32_t c = 0;
805 int32_t c1=0;
806 UErrorCode status = U_ZERO_ERROR;
807 const char* testdatapath = loadTestData(&status);
808 char* fileName = (char*) malloc(uprv_strlen(testdatapath) +10);
809 FileStream* stream = NULL;
810 /* these should not be closed */
811 FileStream* pStdin = T_FileStream_stdin();
812 FileStream* pStdout = T_FileStream_stdout();
813 FileStream* pStderr = T_FileStream_stderr();
814
815 const char* testline = "This is a test line";
816 int32_t bufLen = (int32_t)strlen(testline)+10;
817 char* buf = (char*) malloc(bufLen);
818 int32_t retLen = 0;
819
820 if(pStdin==NULL){
821 log_err("failed to get T_FileStream_stdin()");
822 }
823 if(pStdout==NULL){
824 log_err("failed to get T_FileStream_stdout()");
825 }
826 if(pStderr==NULL){
827 log_err("failed to get T_FileStream_stderr()");
828 }
829
830 uprv_strcpy(fileName,testdatapath);
831 uprv_strcat(fileName,".dat");
832 stream = T_FileStream_open(fileName, "r");
833 if(stream==NULL){
834 log_data_err("T_FileStream_open failed to open %s\n",fileName);
835 } else {
836 if(!T_FileStream_file_exists(fileName)){
837 log_data_err("T_FileStream_file_exists failed to verify existence of %s \n",fileName);
838 }
839
840 retLen=T_FileStream_read(stream,&c,1);
841 if(retLen==0){
842 log_data_err("T_FileStream_read failed to read from %s \n",fileName);
843 }
844 retLen=0;
845 T_FileStream_rewind(stream);
846 T_FileStream_read(stream,&c1,1);
847 if(c!=c1){
848 log_data_err("T_FileStream_rewind failed to rewind %s \n",fileName);
849 }
850 T_FileStream_rewind(stream);
851 c1 = T_FileStream_peek(stream);
852 if(c!=c1){
853 log_data_err("T_FileStream_peek failed to peekd %s \n",fileName);
854 }
855 c = T_FileStream_getc(stream);
856 T_FileStream_ungetc(c,stream);
857 if(c!= T_FileStream_getc(stream)){
858 log_data_err("T_FileStream_ungetc failed to d %s \n",fileName);
859 }
860
861 if(T_FileStream_size(stream)<=0){
862 log_data_err("T_FileStream_size failed to d %s \n",fileName);
863 }
864 if(T_FileStream_error(stream)){
865 log_data_err("T_FileStream_error shouldn't have an error %s\n",fileName);
866 }
867 if(!T_FileStream_error(NULL)){
868 log_err("T_FileStream_error didn't get an error %s\n",fileName);
869 }
870 T_FileStream_putc(stream, 0x20);
871 if(!T_FileStream_error(stream)){
872 /*
873 Warning
874 writing to a read-only file may not consistently fail on all platforms
875 (e.g. HP-UX, FreeBSD, MacOSX)
876 */
877 log_verbose("T_FileStream_error didn't get an error when writing to a readonly file %s\n",fileName);
878 }
879
880 T_FileStream_close(stream);
881 }
882 /* test writing function */
883 stream=NULL;
884 uprv_strcpy(fileName,testdatapath);
885 uprv_strcat(fileName,".tmp");
886 stream = T_FileStream_open(fileName,"w+");
887
888 if(stream == NULL){
889 log_data_err("Could not open %s for writing\n",fileName);
890 } else {
891 c= '$';
892 T_FileStream_putc(stream,c);
893 T_FileStream_rewind(stream);
894 if(c != T_FileStream_getc(stream)){
895 log_data_err("T_FileStream_putc failed %s\n",fileName);
896 }
897
898 T_FileStream_rewind(stream);
899 T_FileStream_writeLine(stream,testline);
900 T_FileStream_rewind(stream);
901 T_FileStream_readLine(stream,buf,bufLen);
902 if(uprv_strncmp(testline, buf,uprv_strlen(buf))!=0){
903 log_data_err("T_FileStream_writeLine failed %s\n",fileName);
904 }
905
906 T_FileStream_rewind(stream);
907 T_FileStream_write(stream,testline,(int32_t)strlen(testline));
908 T_FileStream_rewind(stream);
909 retLen = T_FileStream_read(stream, buf, bufLen);
910 if(uprv_strncmp(testline, buf,retLen)!=0){
911 log_data_err("T_FileStream_write failed %s\n",fileName);
912 }
913
914 T_FileStream_close(stream);
915 }
916 if(!T_FileStream_remove(fileName)){
917 log_data_err("T_FileStream_remove failed to delete %s\n",fileName);
918 }
919
920
921 free(fileName);
922 free(buf);
923
924 }
925
TestGetSize(void)926 static void TestGetSize(void) {
927 const struct {
928 const char* key;
929 int32_t size;
930 } test[] = {
931 { "zerotest", 1},
932 { "one", 1},
933 { "importtest", 1},
934 { "integerarray", 1},
935 { "emptyarray", 0},
936 { "emptytable", 0},
937 { "emptystring", 1}, /* empty string is still a string */
938 { "emptyint", 1},
939 { "emptybin", 1},
940 { "testinclude", 1},
941 { "collations", 1}, /* not 2 - there is hidden %%CollationBin */
942 };
943
944 UErrorCode status = U_ZERO_ERROR;
945
946 UResourceBundle *rb = NULL;
947 UResourceBundle *res = NULL;
948 UResourceBundle *helper = NULL;
949 const char* testdatapath = loadTestData(&status);
950 int32_t i = 0, j = 0;
951 int32_t size = 0;
952
953 if(U_FAILURE(status))
954 {
955 log_data_err("Could not load testdata.dat %s\n", u_errorName(status));
956 return;
957 }
958
959 rb = ures_open(testdatapath, "testtypes", &status);
960 if(U_FAILURE(status))
961 {
962 log_err("Could not testtypes resource bundle %s\n", u_errorName(status));
963 return;
964 }
965
966 for(i = 0; i < UPRV_LENGTHOF(test); i++) {
967 res = ures_getByKey(rb, test[i].key, res, &status);
968 if(U_FAILURE(status))
969 {
970 log_err("Couldn't find the key %s. Error: %s\n", test[i].key, u_errorName(status));
971 ures_close(rb);
972 return;
973 }
974 size = ures_getSize(res);
975 if(size != test[i].size) {
976 log_err("Expected size %i, got size %i for key %s\n", test[i].size, size, test[i].key);
977 for(j = 0; j < size; j++) {
978 helper = ures_getByIndex(res, j, helper, &status);
979 log_err("%s\n", ures_getKey(helper));
980 }
981 }
982 }
983 ures_close(helper);
984 ures_close(res);
985 ures_close(rb);
986 }
987
TestGetLocaleByType(void)988 static void TestGetLocaleByType(void) {
989 static const struct {
990 const char *requestedLocale;
991 const char *resourceKey;
992 const char *validLocale;
993 const char *actualLocale;
994 } test[] = {
995 { "te_IN_BLAH", "string_only_in_te_IN", "te_IN", "te_IN" },
996 { "te_IN_BLAH", "string_only_in_te", "te_IN", "te" },
997 { "te_IN_BLAH", "string_only_in_Root", "te_IN", "root" },
998 { "te_IN_BLAH_01234567890_01234567890_01234567890_01234567890_01234567890_01234567890", "array_2d_only_in_Root", "te_IN", "root" },
999 { "te_IN_BLAH@currency=euro", "array_2d_only_in_te_IN", "te_IN", "te_IN" },
1000 { "te_IN_BLAH@collation=phonebook;calendar=thai", "array_2d_only_in_te", "te_IN", "te" }
1001 };
1002
1003 UErrorCode status = U_ZERO_ERROR;
1004
1005 UResourceBundle *rb = NULL;
1006 UResourceBundle *res = NULL;
1007 const char* testdatapath = loadTestData(&status);
1008 int32_t i = 0;
1009 const char *locale = NULL;
1010
1011 if(U_FAILURE(status))
1012 {
1013 log_data_err("Could not load testdata.dat %s\n", u_errorName(status));
1014 return;
1015 }
1016
1017 for(i = 0; i < UPRV_LENGTHOF(test); i++) {
1018 rb = ures_open(testdatapath, test[i].requestedLocale, &status);
1019 if(U_FAILURE(status))
1020 {
1021 log_err("Could not open resource bundle %s (error %s)\n", test[i].requestedLocale, u_errorName(status));
1022 status = U_ZERO_ERROR;
1023 continue;
1024 }
1025
1026 res = ures_getByKey(rb, test[i].resourceKey, res, &status);
1027 if(U_FAILURE(status))
1028 {
1029 log_err("Couldn't find the key %s. Error: %s\n", test[i].resourceKey, u_errorName(status));
1030 ures_close(rb);
1031 status = U_ZERO_ERROR;
1032 continue;
1033 }
1034
1035 locale = ures_getLocaleByType(res, ULOC_REQUESTED_LOCALE, &status);
1036 if(U_SUCCESS(status) && locale != NULL) {
1037 log_err("Requested locale should return NULL\n");
1038 }
1039 status = U_ZERO_ERROR;
1040 locale = ures_getLocaleByType(res, ULOC_VALID_LOCALE, &status);
1041 if(!locale || strcmp(locale, test[i].validLocale) != 0) {
1042 log_err("Expected valid locale to be %s. Got %s\n", test[i].requestedLocale, locale);
1043 }
1044 locale = ures_getLocaleByType(res, ULOC_ACTUAL_LOCALE, &status);
1045 if(!locale || strcmp(locale, test[i].actualLocale) != 0) {
1046 log_err("Expected actual locale to be %s. Got %s\n", test[i].requestedLocale, locale);
1047 }
1048 ures_close(rb);
1049 }
1050 ures_close(res);
1051 }
1052