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