• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /********************************************************************
2  * COPYRIGHT:
3  * Copyright (c) 1997-2012, International Business Machines Corporation and
4  * others. All Rights Reserved.
5  ********************************************************************
6  *
7  * File CMSGTST.C
8  *
9  * Modification History:
10  *        Name                     Description
11  *     Madhu Katragadda              Creation
12  ********************************************************************/
13 /* C API TEST FOR MESSAGE FORMAT */
14 
15 #include "unicode/utypes.h"
16 
17 #if !UCONFIG_NO_FORMATTING
18 
19 #include <stdlib.h>
20 #include <string.h>
21 #include <stdarg.h>
22 #include "unicode/uloc.h"
23 #include "unicode/umsg.h"
24 #include "unicode/udat.h"
25 #include "unicode/umsg.h"
26 #include "unicode/ustring.h"
27 #include "cintltst.h"
28 #include "cmsgtst.h"
29 #include "cformtst.h"
30 
31 #define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
32 
33 static const char* const txt_testCasePatterns[] = {
34    "Quotes '', '{', a {0,number,integer} '{'0}",
35    "Quotes '', '{', a {0,number,integer} '{'0}",
36    "You deposited {0,number,integer} times an amount of {1,number,currency} on {2,date,short}",
37     "'{'2,time,full}, for {1, number }, {0,number,integer} is {2,time,full} and full date is {2,date,full}",
38    "'{'1,number,percent} for {0,number,integer} is {1,number,percent}",
39 };
40 
41 static const char* const txt_testResultStrings[] = {
42     "Quotes ', {, a 1 {0}",
43     "Quotes ', {, a 1 {0}",
44     "You deposited 1 times an amount of $3,456.00 on 1/12/70",
45     "{2,time,full}, for 3,456, 1 is 5:46:40 AM Pacific Standard Time and full date is Monday, January 12, 1970",
46     "{1,number,percent} for 1 is 345,600%"
47 };
48 
49 const int32_t cnt_testCases = 5;
50 static UChar* testCasePatterns[5];
51 
52 static UChar* testResultStrings[5];
53 
54 static UBool strings_initialized = FALSE;
55 
56 /* function used to create the test patterns for testing Message formatting */
InitStrings(void)57 static void InitStrings( void )
58 {
59     int32_t i;
60     if (strings_initialized)
61         return;
62 
63     for (i=0; i < cnt_testCases; i++ ) {
64         uint32_t strSize = (uint32_t)strlen(txt_testCasePatterns[i]) + 1;
65         testCasePatterns[i]=(UChar*)malloc(sizeof(UChar) * strSize);
66         u_uastrncpy(testCasePatterns[i], txt_testCasePatterns[i], strSize);
67     }
68     for (i=0; i < cnt_testCases; i++ ) {
69         uint32_t strSize = (uint32_t)strlen(txt_testResultStrings[i]) + 1;
70         testResultStrings[i] = (UChar*)malloc(sizeof(UChar) * strSize);
71         u_uastrncpy(testResultStrings[i], txt_testResultStrings[i], strSize);
72     }
73 
74     strings_initialized = TRUE;
75 }
76 
FreeStrings(void)77 static void FreeStrings( void )
78 {
79     int32_t i;
80     if (!strings_initialized)
81         return;
82 
83     for (i=0; i < cnt_testCases; i++ ) {
84         free(testCasePatterns[i]);
85     }
86     for (i=0; i < cnt_testCases; i++ ) {
87         free(testResultStrings[i]);
88     }
89     strings_initialized = FALSE;
90 }
91 
92 /* Platform dependent test to detect if this type will return NULL when interpreted as a pointer. */
returnsNullForType(int firstParam,...)93 static UBool returnsNullForType(int firstParam, ...) {
94     UBool isNULL;
95     va_list marker;
96     va_start(marker, firstParam);
97     isNULL = (UBool)(va_arg(marker, void*) == NULL);
98     va_end(marker);
99     return isNULL;
100 }
101 
102 /* Test u_formatMessage() with various test patterns() */
MessageFormatTest(void)103 static void MessageFormatTest( void )
104 {
105     UChar *str;
106     UChar* result;
107     int32_t resultLengthOut,resultlength,i, patternlength;
108     UErrorCode status = U_ZERO_ERROR;
109     UDate d1=1000000000.0;
110 
111     ctest_setTimeZone(NULL, &status);
112 
113     str=(UChar*)malloc(sizeof(UChar) * 7);
114     u_uastrncpy(str, "MyDisk", 7);
115     resultlength=1;
116     result=(UChar*)malloc(sizeof(UChar) * 1);
117     log_verbose("Testing u_formatMessage()\n");
118     InitStrings();
119     for (i = 0; i < cnt_testCases; i++) {
120         status=U_ZERO_ERROR;
121         patternlength=u_strlen(testCasePatterns[i]);
122         resultLengthOut=u_formatMessage( "en_US",testCasePatterns[i], patternlength, result, resultlength,
123             &status, 1, 3456.00, d1);
124         if(status== U_BUFFER_OVERFLOW_ERROR)
125         {
126             status=U_ZERO_ERROR;
127             resultlength=resultLengthOut+1;
128             result=(UChar*)realloc(result,sizeof(UChar) * resultlength);
129             u_formatMessage( "en_US",testCasePatterns[i], patternlength, result, resultlength,
130                 &status, 1, 3456.00, d1);
131         }
132         if(U_FAILURE(status)){
133             log_data_err("ERROR: failure in message format on testcase %d:  %s (Are you missing data?)\n", i, myErrorName(status) );
134             continue;
135         }
136         if(u_strcmp(result, testResultStrings[i])==0){
137             log_verbose("PASS: MessagFormat successful on testcase : %d\n", i);
138         }
139         else{
140             log_err("FAIL: Error in MessageFormat on testcase : %d\n GOT %s EXPECTED %s\n", i,
141                 austrdup(result), austrdup(testResultStrings[i]) );
142         }
143     }
144     free(result);
145     result = NULL;
146     free(str);
147     {
148 
149          for (i = 0; i < cnt_testCases; i++) {
150             UParseError parseError;
151             status=U_ZERO_ERROR;
152             patternlength=u_strlen(testCasePatterns[i]);
153             resultlength=0;
154             resultLengthOut=u_formatMessageWithError( "en_US",testCasePatterns[i], patternlength, result, resultlength,
155                 &parseError,&status, 1, 3456.00, d1);
156             if(status== U_BUFFER_OVERFLOW_ERROR)
157             {
158                 status=U_ZERO_ERROR;
159                 resultlength=resultLengthOut+1;
160                 result=(UChar*)malloc(sizeof(UChar) * resultlength);
161                 u_formatMessage( "en_US",testCasePatterns[i], patternlength, result, resultlength,
162                     &status, 1, 3456.00, d1);
163             }
164             if(U_FAILURE(status)){
165                 log_data_err("ERROR: failure in message format on testcase %d:  %s (Are you missing data?)\n", i, myErrorName(status) );
166                 continue;
167             }
168             if(u_strcmp(result, testResultStrings[i])==0){
169                 log_verbose("PASS: MessagFormat successful on testcase : %d\n", i);
170             }
171             else{
172                 log_err("FAIL: Error in MessageFormat on testcase : %d\n GOT %s EXPECTED %s\n", i,
173                     austrdup(result), austrdup(testResultStrings[i]) );
174             }
175             free(result);
176             result=NULL;
177         }
178     }
179     {
180         UErrorCode ec = U_ZERO_ERROR;
181         int32_t patternLength = u_strlen(testCasePatterns[0]);
182 
183         UMessageFormat formatter = umsg_open(testCasePatterns[0],patternLength,"en_US",NULL,&ec);
184 
185         if(U_FAILURE(ec)){
186             log_data_err("umsg_open() failed for testCasePattens[%d]. -> %s (Are you missing data?)\n",i, u_errorName(ec));
187             return;
188         }
189         for(i = 0;i<cnt_testCases; i++){
190             UParseError parseError;
191             int32_t resultLength =0,count=0;
192             int32_t one=0;
193             int32_t two=0;
194             UDate d2=0;
195 
196             result=NULL;
197             patternLength = u_strlen(testCasePatterns[i]);
198 
199             umsg_applyPattern(formatter,testCasePatterns[i],patternLength,&parseError,&ec);
200             if(U_FAILURE(ec)){
201                 log_err("umsg_applyPattern() failed for testCasePattens[%d].\n",i);
202                 return;
203             }
204             /* pre-flight */
205             resultLength = umsg_format(formatter,result,resultLength,&ec,1,3456.00,d1);
206             if(ec==U_BUFFER_OVERFLOW_ERROR){
207                 ec=U_ZERO_ERROR;
208                 result = (UChar*) malloc(U_SIZEOF_UCHAR*resultLength+2);
209                 resultLength =  umsg_format(formatter,result,resultLength+2,&ec,1,3456.00,d1);
210                 if(U_FAILURE(ec)){
211                       log_err("ERROR: failure in message format on testcase %d:  %s\n", i, u_errorName(status) );
212                       free(result);
213                       return;
214                 }
215 
216                 if(u_strcmp(result, testResultStrings[i])==0){
217                     log_verbose("PASS: MessagFormat successful on testcase : %d\n", i);
218                 }
219                 else{
220                     log_err("FAIL: Error in MessageFormat on testcase : %d\n GOT %s EXPECTED %s\n", i,
221                         austrdup(result), austrdup(testResultStrings[i]) );
222                 }
223 
224 #if (U_PLATFORM == U_PF_LINUX) /* add platforms here .. */
225                 log_verbose("Skipping potentially crashing test for mismatched varargs.\n");
226 #else
227                 log_verbose("Note: the next is a platform dependent test. If it crashes, add an exclusion for your platform near %s:%d\n", __FILE__, __LINE__);
228 
229                 if (returnsNullForType(1, (double)2.0)) {
230                     /* HP/UX and possibly other platforms don't properly check for this case.
231                     We pass in a UDate, but the function expects a UDate *.  When va_arg is used,
232                     most compilers will return NULL, but HP-UX won't do that and will return 2
233                     in this case.  This is a platform dependent test.  It crashes on some systems.
234 
235                     If you get a crash here, see the definition of returnsNullForType.
236 
237                     This relies upon "undefined" behavior, as indicated by C99 7.15.1.1 paragraph 2
238                     */
239                     umsg_parse(formatter,result,resultLength,&count,&ec,one,two,d2);
240                     if(ec!=U_ILLEGAL_ARGUMENT_ERROR){
241                         log_err("FAIL: Did not get expected error for umsg_parse(). Expected: U_ILLEGAL_ARGUMENT_ERROR Got: %s \n",u_errorName(ec));
242                     }else{
243                         ec = U_ZERO_ERROR;
244                     }
245                 }
246                 else {
247                     log_verbose("Warning: Returning NULL for a mismatched va_arg type isn't supported on this platform.\n", i);
248                 }
249 #endif
250 
251                 umsg_parse(formatter,result,resultLength,&count,&ec,&one,&two,&d2);
252                 if(U_FAILURE(ec)){
253                     log_err("umsg_parse could not parse the pattern. Error: %s.\n",u_errorName(ec));
254                 }
255                 free(result);
256             }else{
257                 log_err("FAIL: Expected U_BUFFER_OVERFLOW error while preflighting got: %s for testCasePatterns[%d]",u_errorName(ec),i);
258             }
259         }
260         umsg_close(formatter);
261     }
262     FreeStrings();
263 
264     ctest_resetTimeZone();
265 }
266 
267 
268 /*test u_formatMessage() with sample patterns */
TestSampleMessageFormat(void)269 static void TestSampleMessageFormat(void)
270 {
271     UChar *str;
272     UChar *result;
273     UChar pattern[100], expected[100];
274     int32_t resultLengthOut, resultlength;
275     UDate d = 837039928046.0;
276     UErrorCode status = U_ZERO_ERROR;
277 
278     ctest_setTimeZone(NULL, &status);
279 
280     str=(UChar*)malloc(sizeof(UChar) * 15);
281     u_uastrcpy(str, "abc");
282 
283     u_uastrcpy(pattern, "There are {0} files on {1,date}");
284     u_uastrcpy(expected, "There are abc files on Jul 10, 1996");
285     result=(UChar*)malloc(sizeof(UChar) * 1);
286     log_verbose("\nTesting a sample for Message format test#1\n");
287     resultlength=1;
288     resultLengthOut=u_formatMessage( "en_US", pattern, u_strlen(pattern), result, resultlength, &status, str, d);
289     if(status==U_BUFFER_OVERFLOW_ERROR)
290     {
291         status=U_ZERO_ERROR;
292         resultlength=resultLengthOut+1;
293         result=(UChar*)realloc(result, sizeof(UChar) * resultlength);
294         u_formatMessage( "en_US", pattern, u_strlen(pattern), result, resultlength, &status, str, d);
295     }
296     if(U_FAILURE(status)){
297         log_data_err("Error: failure in message format on test#1: %s (Are you missing data?)\n", myErrorName(status));
298     }
299     else if(u_strcmp(result, expected)==0)
300         log_verbose("PASS: MessagFormat successful on test#1\n");
301     else{
302         log_err("FAIL: Error in MessageFormat on test#1 \n GOT: %s EXPECTED: %s\n",
303             austrdup(result), austrdup(expected) );
304     }
305 
306 
307     log_verbose("\nTesting message format with another pattern test#2\n");
308     u_uastrcpy(pattern, "The disk \"{0}\" contains {1,number,integer} file(s)");
309     u_uastrcpy(expected, "The disk \"MyDisk\" contains 23 file(s)");
310     u_uastrcpy(str, "MyDisk");
311 
312     resultLengthOut=u_formatMessage( "en_US",
313         pattern,
314         u_strlen(pattern),
315         result,
316         resultlength,
317         &status,
318         str,
319         235);
320     if(status==U_BUFFER_OVERFLOW_ERROR)
321     {
322         status=U_ZERO_ERROR;
323         resultlength=resultLengthOut+1;
324         result=(UChar*)realloc(result, sizeof(UChar) * (resultlength+1));
325         u_formatMessage( "en_US", pattern, u_strlen(pattern), result, resultlength, &status, str, 23);
326     }
327     if(U_FAILURE(status)){
328         log_data_err("Error: failure in message format on test#2 : %s (Are you missing data?)\n", myErrorName(status));
329     }
330     else if(u_strcmp(result, expected)==0)
331         log_verbose("PASS: MessagFormat successful on test#2\n");
332     else{
333         log_err("FAIL: Error in MessageFormat on test#2\n GOT: %s EXPECTED: %s\n",
334             austrdup(result), austrdup(expected) );
335     }
336 
337 
338 
339     log_verbose("\nTesting message format with another pattern test#3\n");
340     u_uastrcpy(pattern, "You made a {0} of {1,number,currency}");
341     u_uastrcpy(expected, "You made a deposit of $500.00");
342     u_uastrcpy(str, "deposit");
343     resultlength=0;
344     resultLengthOut=u_formatMessage( "en_US", pattern, u_strlen(pattern), NULL, resultlength, &status, str, 500.00);
345     if(status==U_BUFFER_OVERFLOW_ERROR)
346     {
347         status=U_ZERO_ERROR;
348         resultlength=resultLengthOut+1;
349         result=(UChar*)realloc(result, sizeof(UChar) * resultlength);
350         u_formatMessage( "en_US", pattern, u_strlen(pattern), result, resultlength, &status, str, 500.00);
351     }
352     if(U_FAILURE(status)){
353         log_data_err("Error: failure in message format on test#3 : %s (Are you missing data?)\n", myErrorName(status));
354     }
355     else if(u_strcmp(result, expected)==0)
356         log_verbose("PASS: MessagFormat successful on test#3\n");
357     else{
358         log_err("FAIL: Error in MessageFormat on test#3\n GOT: %s EXPECTED %s\n", austrdup(result),
359             austrdup(expected) );
360     }
361 
362     free(result);
363     free(str);
364 
365     ctest_resetTimeZone();
366 }
367 
368 /* Test umsg_format() and umsg_parse() , format and parse sequence and round trip */
TestNewFormatAndParseAPI(void)369 static void TestNewFormatAndParseAPI(void)
370 {
371 
372     UChar *result, tzID[4], str[25];
373     UChar pattern[100];
374     UChar expected[100];
375     int32_t resultLengthOut, resultlength;
376     UCalendar *cal;
377     UDate d1,d;
378     UDateFormat *def1;
379     UErrorCode status = U_ZERO_ERROR;
380     int32_t value = 0;
381     UChar ret[30];
382     UParseError parseError;
383     UMessageFormat* fmt = NULL;
384     int32_t count=0;
385 
386     ctest_setTimeZone(NULL, &status);
387 
388     log_verbose("Testing format and parse with parse error\n");
389 
390     u_uastrcpy(str, "disturbance in force");
391     u_uastrcpy(tzID, "PST");
392     cal=ucal_open(tzID, u_strlen(tzID), "en_US", UCAL_TRADITIONAL, &status);
393     if(U_FAILURE(status)){
394         log_data_err("error in ucal_open caldef : %s - (Are you missing data?)\n", myErrorName(status) );
395         return;
396     }
397     ucal_setDateTime(cal, 1999, UCAL_MARCH, 18, 0, 0, 0, &status);
398     d1=ucal_getMillis(cal, &status);
399     if(U_FAILURE(status)){
400             log_err("Error: failure in get millis: %s\n", myErrorName(status) );
401             return;
402     }
403 
404     log_verbose("\nTesting with pattern test#4");
405     u_uastrcpy(pattern, "On {0, date, long}, there was a {1} on planet {2,number,integer}");
406     u_uastrcpy(expected, "On March 18, 1999, there was a disturbance in force on planet 7");
407     resultlength=1;
408     fmt = umsg_open(pattern,u_strlen(pattern),"en_US",&parseError,&status);
409     if(U_FAILURE(status)){
410         log_data_err("error in umsg_open  : %s (Are you missing data?)\n", u_errorName(status) );
411         return;
412     }
413     result=(UChar*)malloc(sizeof(UChar) * resultlength);
414 
415     resultLengthOut=umsg_format(fmt ,result, resultlength,&status, d1, str, 7);
416     if(status==U_BUFFER_OVERFLOW_ERROR)
417     {
418         status=U_ZERO_ERROR;
419         resultlength=resultLengthOut+1;
420         result=(UChar*)realloc(result, sizeof(UChar) * resultlength);
421         u_formatMessageWithError( "en_US", pattern, u_strlen(pattern), result, resultlength,&parseError, &status, d1, str, 7);
422 
423     }
424     if(U_FAILURE(status)){
425         log_err("ERROR: failure in message format test#4: %s\n", myErrorName(status));
426     }
427     if(u_strcmp(result, expected)==0)
428         log_verbose("PASS: MessagFormat successful on test#4\n");
429     else{
430         log_err("FAIL: Error in MessageFormat on test#4\n GOT: %s EXPECTED: %s\n", austrdup(result),
431             austrdup(expected) );
432     }
433 
434 
435     /*try to parse this and check*/
436     log_verbose("\nTesting the parse Message test#5\n");
437 
438     umsg_parse(fmt, result, u_strlen(result),&count,&status, &d, ret, &value);
439     if(U_FAILURE(status)){
440         log_err("ERROR: error in parsing: test#5: %s\n", myErrorName(status));
441     }
442     if(value!=7 && u_strcmp(str,ret)!=0)
443         log_err("FAIL: Error in parseMessage on test#5 \n");
444     else
445         log_verbose("PASS: parseMessage successful on test#5\n");
446 
447     def1 = udat_open(UDAT_DEFAULT,UDAT_DEFAULT ,NULL, NULL, 0, NULL,0,&status);
448     if(U_FAILURE(status))
449     {
450         log_err("error in creating the dateformat using short date and time style:\n %s\n", myErrorName(status));
451     }else{
452 
453         if(u_strcmp(myDateFormat(def1, d), myDateFormat(def1, d1))==0)
454             log_verbose("PASS: parseMessage successful test#5\n");
455         else{
456             log_err("FAIL: parseMessage didn't parse the date successfully\n GOT: %s EXPECTED %s\n",
457                 austrdup(myDateFormat(def1,d)), austrdup(myDateFormat(def1,d1)) );
458         }
459     }
460     umsg_close(fmt);
461     udat_close(def1);
462     ucal_close(cal);
463 
464     free(result);
465 
466     ctest_resetTimeZone();
467 }
468 
469 /* Test u_formatMessageWithError() and u_parseMessageWithError() , format and parse sequence and round trip */
TestSampleFormatAndParseWithError(void)470 static void TestSampleFormatAndParseWithError(void)
471 {
472 
473     UChar *result, *tzID, *str;
474     UChar pattern[100];
475 
476     UChar expected[100];
477     int32_t resultLengthOut, resultlength;
478     UCalendar *cal;
479     UDate d1,d;
480     UDateFormat *def1;
481     UErrorCode status = U_ZERO_ERROR;
482     int32_t value = 0;
483     UChar ret[30];
484     UParseError parseError;
485 
486     ctest_setTimeZone(NULL, &status);
487 
488     log_verbose("Testing format and parse with parse error\n");
489 
490     str=(UChar*)malloc(sizeof(UChar) * 25);
491     u_uastrcpy(str, "disturbance in force");
492     tzID=(UChar*)malloc(sizeof(UChar) * 4);
493     u_uastrcpy(tzID, "PST");
494     cal=ucal_open(tzID, u_strlen(tzID), "en_US", UCAL_TRADITIONAL, &status);
495     if(U_FAILURE(status)){
496         log_data_err("error in ucal_open caldef : %s - (Are you missing data?)\n", myErrorName(status) );
497     }
498     ucal_setDateTime(cal, 1999, UCAL_MARCH, 18, 0, 0, 0, &status);
499     d1=ucal_getMillis(cal, &status);
500     if(U_FAILURE(status)){
501             log_data_err("Error: failure in get millis: %s - (Are you missing data?)\n", myErrorName(status) );
502     }
503 
504     log_verbose("\nTesting with pattern test#4");
505     u_uastrcpy(pattern, "On {0, date, long}, there was a {1} on planet {2,number,integer}");
506     u_uastrcpy(expected, "On March 18, 1999, there was a disturbance in force on planet 7");
507     resultlength=1;
508     result=(UChar*)malloc(sizeof(UChar) * resultlength);
509     resultLengthOut=u_formatMessageWithError( "en_US", pattern, u_strlen(pattern), result, resultlength,&parseError, &status, d1, str, 7);
510     if(status==U_BUFFER_OVERFLOW_ERROR)
511     {
512         status=U_ZERO_ERROR;
513         resultlength=resultLengthOut+1;
514         result=(UChar*)realloc(result, sizeof(UChar) * resultlength);
515         u_formatMessageWithError( "en_US", pattern, u_strlen(pattern), result, resultlength,&parseError, &status, d1, str, 7);
516 
517     }
518     if(U_FAILURE(status)){
519         log_data_err("ERROR: failure in message format test#4: %s (Are you missing data?)\n", myErrorName(status));
520     }
521     else if(u_strcmp(result, expected)==0)
522         log_verbose("PASS: MessagFormat successful on test#4\n");
523     else{
524         log_err("FAIL: Error in MessageFormat on test#4\n GOT: %s EXPECTED: %s\n", austrdup(result),
525             austrdup(expected) );
526     }
527 
528 
529     /*try to parse this and check*/
530     log_verbose("\nTesting the parse Message test#5\n");
531 
532     u_parseMessageWithError("en_US", pattern, u_strlen(pattern), result, u_strlen(result), &parseError,&status, &d, ret, &value);
533     if(U_FAILURE(status)){
534         log_data_err("ERROR: error in parsing: test#5: %s (Are you missing data?)\n", myErrorName(status));
535     }
536     else if(value!=7 && u_strcmp(str,ret)!=0)
537         log_err("FAIL: Error in parseMessage on test#5 \n");
538     else
539         log_verbose("PASS: parseMessage successful on test#5\n");
540 
541     def1 = udat_open(UDAT_DEFAULT,UDAT_DEFAULT ,NULL, NULL, 0, NULL,0,&status);
542     if(U_FAILURE(status))
543     {
544         log_data_err("error in creating the dateformat using short date and time style: %s (Are you missing data?)\n", myErrorName(status));
545     }else{
546 
547         if(u_strcmp(myDateFormat(def1, d), myDateFormat(def1, d1))==0)
548             log_verbose("PASS: parseMessage successful test#5\n");
549         else{
550             log_err("FAIL: parseMessage didn't parse the date successfully\n GOT: %s EXPECTED %s\n",
551                 austrdup(myDateFormat(def1,d)), austrdup(myDateFormat(def1,d1)) );
552         }
553     }
554     udat_close(def1);
555     ucal_close(cal);
556 
557     free(result);
558     free(str);
559     free(tzID);
560 
561     ctest_resetTimeZone();
562 }
563 
564 /* Test u_formatMessage() and u_parseMessage() , format and parse sequence and round trip */
TestSampleFormatAndParse(void)565 static void TestSampleFormatAndParse(void)
566 {
567 
568     UChar *result, *tzID, *str;
569     UChar pattern[100];
570     UChar expected[100];
571     int32_t resultLengthOut, resultlength;
572     UCalendar *cal;
573     UDate d1,d;
574     UDateFormat *def1;
575     UErrorCode status = U_ZERO_ERROR;
576     int32_t value = 0;
577     UChar ret[30];
578 
579     ctest_setTimeZone(NULL, &status);
580 
581     log_verbose("Testing format and parse\n");
582 
583     str=(UChar*)malloc(sizeof(UChar) * 25);
584     u_uastrcpy(str, "disturbance in force");
585     tzID=(UChar*)malloc(sizeof(UChar) * 4);
586     u_uastrcpy(tzID, "PST");
587     cal=ucal_open(tzID, u_strlen(tzID), "en_US", UCAL_TRADITIONAL, &status);
588     if(U_FAILURE(status)){
589         log_data_err("error in ucal_open caldef : %s - (Are you missing data?)\n", myErrorName(status) );
590     }
591     ucal_setDateTime(cal, 1999, UCAL_MARCH, 18, 0, 0, 0, &status);
592     d1=ucal_getMillis(cal, &status);
593     if(U_FAILURE(status)){
594             log_data_err("Error: failure in get millis: %s - (Are you missing data?)\n", myErrorName(status) );
595     }
596 
597     log_verbose("\nTesting with pattern test#4");
598     u_uastrcpy(pattern, "On {0, date, long}, there was a {1} on planet {2,number,integer}");
599     u_uastrcpy(expected, "On March 18, 1999, there was a disturbance in force on planet 7");
600     resultlength=1;
601     result=(UChar*)malloc(sizeof(UChar) * resultlength);
602     resultLengthOut=u_formatMessage( "en_US", pattern, u_strlen(pattern), result, resultlength, &status, d1, str, 7);
603     if(status==U_BUFFER_OVERFLOW_ERROR)
604     {
605         status=U_ZERO_ERROR;
606         resultlength=resultLengthOut+1;
607         result=(UChar*)realloc(result, sizeof(UChar) * resultlength);
608         u_formatMessage( "en_US", pattern, u_strlen(pattern), result, resultlength, &status, d1, str, 7);
609 
610     }
611     if(U_FAILURE(status)){
612         log_data_err("ERROR: failure in message format test#4: %s (Are you missing data?)\n", myErrorName(status));
613     }
614     else if(u_strcmp(result, expected)==0)
615         log_verbose("PASS: MessagFormat successful on test#4\n");
616     else{
617         log_err("FAIL: Error in MessageFormat on test#4\n GOT: %s EXPECTED: %s\n", austrdup(result),
618             austrdup(expected) );
619     }
620 
621 
622     /*try to parse this and check*/
623     log_verbose("\nTesting the parse Message test#5\n");
624 
625     u_parseMessage("en_US", pattern, u_strlen(pattern), result, u_strlen(result), &status, &d, ret, &value);
626     if(U_FAILURE(status)){
627         log_data_err("ERROR: error in parsing: test#5: %s (Are you missing data?)\n", myErrorName(status));
628     }
629     else if(value!=7 && u_strcmp(str,ret)!=0)
630         log_err("FAIL: Error in parseMessage on test#5 \n");
631     else
632         log_verbose("PASS: parseMessage successful on test#5\n");
633 
634     def1 = udat_open(UDAT_DEFAULT,UDAT_DEFAULT ,NULL, NULL, 0, NULL,0,&status);
635     if(U_FAILURE(status))
636     {
637         log_data_err("error in creating the dateformat using short date and time style: %s (Are you missing data?)\n", myErrorName(status));
638     }else{
639 
640         if(u_strcmp(myDateFormat(def1, d), myDateFormat(def1, d1))==0)
641             log_verbose("PASS: parseMessage successful test#5\n");
642         else{
643             log_err("FAIL: parseMessage didn't parse the date successfully\n GOT: %s EXPECTED %s\n",
644                 austrdup(myDateFormat(def1,d)), austrdup(myDateFormat(def1,d1)) );
645         }
646     }
647     udat_close(def1);
648     ucal_close(cal);
649 
650     free(result);
651     free(str);
652     free(tzID);
653 
654     ctest_resetTimeZone();
655 }
656 
657 /* Test message format with a Select option */
TestMsgFormatSelect(void)658 static void TestMsgFormatSelect(void)
659 {
660     UChar* str;
661     UChar* str1;
662     UErrorCode status = U_ZERO_ERROR;
663     UChar *result;
664     UChar pattern[100];
665     UChar expected[100];
666     int32_t resultlength,resultLengthOut;
667 
668     str=(UChar*)malloc(sizeof(UChar) * 25);
669     u_uastrcpy(str, "Kirti");
670     str1=(UChar*)malloc(sizeof(UChar) * 25);
671     u_uastrcpy(str1, "female");
672     log_verbose("Testing message format with Select test #1\n:");
673     u_uastrcpy(pattern, "{0} est {1, select, female {all\\u00E9e} other {all\\u00E9}} \\u00E0 Paris.");
674     u_uastrcpy(expected, "Kirti est all\\u00E9e \\u00E0 Paris.");
675     resultlength=0;
676     resultLengthOut=u_formatMessage( "fr", pattern, u_strlen(pattern), NULL, resultlength, &status, str , str1);
677     if(status==U_BUFFER_OVERFLOW_ERROR)
678     {
679         status=U_ZERO_ERROR;
680         resultlength=resultLengthOut+1;
681         result=(UChar*)malloc(sizeof(UChar) * resultlength);
682         u_formatMessage( "fr", pattern, u_strlen(pattern), result, resultlength, &status, str , str1);
683         if(u_strcmp(result, expected)==0)
684             log_verbose("PASS: MessagFormat successful on Select test#1\n");
685         else{
686             log_err("FAIL: Error in MessageFormat on Select test#1\n GOT %s EXPECTED %s\n", austrdup(result),
687                 austrdup(expected) );
688         }
689         free(result);
690     }
691     if(U_FAILURE(status)){
692         log_data_err("ERROR: failure in message format on Select test#1 : %s \n", myErrorName(status));
693     }
694     free(str);
695     free(str1);
696 
697     /*Test a nested pattern*/
698     str=(UChar*)malloc(sizeof(UChar) * 25);
699     u_uastrcpy(str, "Noname");
700     str1=(UChar*)malloc(sizeof(UChar) * 25);
701     u_uastrcpy(str1, "other");
702     log_verbose("Testing message format with Select test #2\n:");
703     u_uastrcpy(pattern, "{0} est {1, select, female {{2,number,integer} all\\u00E9e} other {all\\u00E9}} \\u00E0 Paris.");
704     u_uastrcpy(expected, "Noname est all\\u00E9 \\u00E0 Paris.");
705     resultlength=0;
706     resultLengthOut=u_formatMessage( "fr", pattern, u_strlen(pattern), NULL, resultlength, &status, str , str1,6);
707     if(status==U_BUFFER_OVERFLOW_ERROR)
708     {
709         status=U_ZERO_ERROR;
710         resultlength=resultLengthOut+1;
711         result=(UChar*)malloc(sizeof(UChar) * resultlength);
712         u_formatMessage( "fr", pattern, u_strlen(pattern), result, resultlength, &status, str , str1);
713         if(u_strcmp(result, expected)==0)
714             log_verbose("PASS: MessagFormat successful on Select test#2\n");
715         else{
716             log_err("FAIL: Error in MessageFormat on Select test#2\n GOT %s EXPECTED %s\n", austrdup(result),
717                 austrdup(expected) );
718         }
719         free(result);
720     }
721     if(U_FAILURE(status)){
722         log_data_err("ERROR: failure in message format on Select test#2 : %s \n", myErrorName(status));
723     }
724     free(str);
725     free(str1);
726 }
727 
728 /* test message format with a choice option */
TestMsgFormatChoice(void)729 static void TestMsgFormatChoice(void)
730 {
731     UChar* str;
732     UErrorCode status = U_ZERO_ERROR;
733     UChar *result;
734     UChar pattern[100];
735     UChar expected[100];
736     int32_t resultlength,resultLengthOut;
737 
738     str=(UChar*)malloc(sizeof(UChar) * 25);
739     u_uastrcpy(str, "MyDisk");
740     log_verbose("Testing message format with choice test #6\n:");
741     /*
742      * Before ICU 4.8, umsg_xxx() did not detect conflicting argument types,
743      * and this pattern had {0,number,integer} as the inner argument.
744      * The choice argument has kDouble type while {0,number,integer} has kLong (int32_t).
745      * ICU 4.8 and above detects this as an error.
746      * We changed this pattern to work as intended.
747      */
748     u_uastrcpy(pattern, "The disk {1} contains {0,choice,0#no files|1#one file|1<{0,number} files}");
749     u_uastrcpy(expected, "The disk MyDisk contains 100 files");
750     resultlength=0;
751     resultLengthOut=u_formatMessage( "en_US", pattern, u_strlen(pattern), NULL, resultlength, &status, 100., str);
752     if(status==U_BUFFER_OVERFLOW_ERROR)
753     {
754         status=U_ZERO_ERROR;
755         resultlength=resultLengthOut+1;
756         result=(UChar*)malloc(sizeof(UChar) * resultlength);
757         u_formatMessage( "en_US", pattern, u_strlen(pattern), result, resultlength, &status, 100., str);
758         if(u_strcmp(result, expected)==0)
759             log_verbose("PASS: MessagFormat successful on test#6\n");
760         else{
761             log_err("FAIL: Error in MessageFormat on test#6\n GOT %s EXPECTED %s\n", austrdup(result),
762                 austrdup(expected) );
763         }
764         free(result);
765     }
766     if(U_FAILURE(status)){
767         log_data_err("ERROR: failure in message format on test#6 : %s (Are you missing data?)\n", myErrorName(status));
768     }
769 
770     log_verbose("Testing message format with choice test #7\n:");
771     u_uastrcpy(expected, "The disk MyDisk contains no files");
772     resultlength=0;
773     resultLengthOut=u_formatMessage( "en_US", pattern, u_strlen(pattern), NULL, resultlength, &status, 0., str);
774     if(status==U_BUFFER_OVERFLOW_ERROR)
775     {
776         status=U_ZERO_ERROR;
777         resultlength=resultLengthOut+1;
778         result=(UChar*)malloc(sizeof(UChar) * resultlength);
779         u_formatMessage( "en_US", pattern, u_strlen(pattern), result, resultlength, &status, 0., str);
780 
781         if(u_strcmp(result, expected)==0)
782             log_verbose("PASS: MessagFormat successful on test#7\n");
783         else{
784             log_err("FAIL: Error in MessageFormat on test#7\n GOT: %s EXPECTED %s\n", austrdup(result),
785                 austrdup(expected) );
786         }
787         free(result);
788     }
789     if(U_FAILURE(status)){
790         log_data_err("ERROR: failure in message format on test#7 : %s (Are you missing data?)\n", myErrorName(status));
791     }
792 
793     log_verbose("Testing message format with choice test #8\n:");
794     u_uastrcpy(expected, "The disk MyDisk contains one file");
795     resultlength=0;
796     resultLengthOut=u_formatMessage( "en_US", pattern, u_strlen(pattern), NULL, resultlength, &status, 1., str);
797     if(status==U_BUFFER_OVERFLOW_ERROR)
798     {
799         status=U_ZERO_ERROR;
800         resultlength=resultLengthOut+1;
801         result=(UChar*)malloc(sizeof(UChar) * resultlength);
802         u_formatMessage( "en_US", pattern, u_strlen(pattern), result, resultlength, &status, 1., str);
803 
804         if(u_strcmp(result, expected)==0)
805             log_verbose("PASS: MessagFormat successful on test#8\n");
806         else{
807             log_err("FAIL: Error in MessageFormat on test#8\n GOT %s EXPECTED: %s\n", austrdup(result),
808                 austrdup(expected) );
809         }
810 
811         free(result);
812     }
813     if(U_FAILURE(status)){
814         log_data_err("ERROR: failure in message format on test#8 : %s (Are you missing data?)\n", myErrorName(status));
815     }
816 
817     free(str);
818 
819 }
820 
821 /*test u_parseMessage() with various test patterns */
TestParseMessage(void)822 static void TestParseMessage(void)
823 {
824     UChar pattern[100];
825     UChar source[100];
826     UErrorCode status = U_ZERO_ERROR;
827     int32_t value;
828     UChar str[10];
829     UChar res[10];
830 
831     log_verbose("\nTesting a sample for parse Message test#9\n");
832 
833     u_uastrcpy(source, "You deposited an amount of $500.00");
834     u_uastrcpy(pattern, "You {0} an amount of {1,number,currency}");
835     u_uastrcpy(res,"deposited");
836 
837     u_parseMessage( "en_US", pattern, u_strlen(pattern), source, u_strlen(source), &status, str, &value);
838     if(U_FAILURE(status)){
839         log_data_err("ERROR: failure in parse Message on test#9: %s (Are you missing data?)\n", myErrorName(status));
840     }
841     else if(value==500.00  && u_strcmp(str,res)==0)
842         log_verbose("PASS: parseMessage successful on test#9\n");
843     else
844         log_err("FAIL: Error in parseMessage on test#9 \n");
845 
846 
847 
848     log_verbose("\nTesting a sample for parse Message test#10\n");
849 
850     u_uastrcpy(source, "There are 123 files on MyDisk created");
851     u_uastrcpy(pattern, "There are {0,number,integer} files on {1} created");
852     u_uastrcpy(res,"MyDisk");
853 
854     u_parseMessage( "en_US", pattern, u_strlen(pattern), source, u_strlen(source), &status, &value, str);
855     if(U_FAILURE(status)){
856         log_data_err("ERROR: failure in parse Message on test#10: %s (Are you missing data?)\n", myErrorName(status));
857     }
858     else if(value==123.00 && u_strcmp(str,res)==0)
859         log_verbose("PASS: parseMessage successful on test#10\n");
860     else
861         log_err("FAIL: Error in parseMessage on test#10 \n");
862 }
863 
CallFormatMessage(const char * locale,UChar * testCasePattern,int32_t patternLength,UChar * result,int32_t resultLength,UErrorCode * status,...)864 static int32_t CallFormatMessage(const char* locale, UChar* testCasePattern, int32_t patternLength,
865                        UChar* result, int32_t resultLength, UErrorCode *status, ...)
866 {
867     int32_t len = 0;
868     va_list ap;
869     va_start(ap, status);
870     len = u_vformatMessage(locale, testCasePattern, patternLength, result, resultLength, ap, status);
871     va_end(ap);
872     return len;
873 }
874 
875 /* Test u_vformatMessage() with various test patterns. */
TestMessageFormatWithValist(void)876 static void TestMessageFormatWithValist( void )
877 {
878 
879     UChar *str;
880     UChar* result;
881     int32_t resultLengthOut,resultlength,i, patternlength;
882     UErrorCode status = U_ZERO_ERROR;
883     UDate d1=1000000000.0;
884 
885     ctest_setTimeZone(NULL, &status);
886 
887     str=(UChar*)malloc(sizeof(UChar) * 7);
888     u_uastrcpy(str, "MyDisk");
889     resultlength=1;
890     result=(UChar*)malloc(sizeof(UChar) * 1);
891     log_verbose("Testing u_formatMessage90\n");
892     InitStrings();
893     for (i = 0; i < cnt_testCases; i++) {
894         status=U_ZERO_ERROR;
895         patternlength=u_strlen(testCasePatterns[i]);
896         resultLengthOut=CallFormatMessage( "en_US",testCasePatterns[i], patternlength, result, resultlength,
897             &status, 1, 3456.00, d1);
898         if(status== U_BUFFER_OVERFLOW_ERROR)
899         {
900             status=U_ZERO_ERROR;
901             resultlength=resultLengthOut+1;
902             result=(UChar*)realloc(result,sizeof(UChar) * resultlength);
903             CallFormatMessage( "en_US",testCasePatterns[i], patternlength, result, resultlength,
904                 &status, 1, 3456.00, d1);
905         }
906         if(U_FAILURE(status)){
907             log_data_err("ERROR: failure in message format on testcase %d:  %s (Are you missing data?)\n", i, myErrorName(status) );
908         }
909         else if(u_strcmp(result, testResultStrings[i])==0){
910             log_verbose("PASS: MessagFormat successful on testcase : %d\n", i);
911         }
912         else{
913             log_err("FAIL: Error in MessageFormat on testcase : %d\n GOT %s EXPECTED %s\n", i,
914                 austrdup(result), austrdup(testResultStrings[i]) );
915         }
916     }
917     free(result);
918     free(str);
919     FreeStrings();
920 
921     ctest_resetTimeZone();
922 }
923 
CallParseMessage(const char * locale,UChar * pattern,int32_t patternLength,UChar * source,int32_t sourceLength,UErrorCode * status,...)924 static void CallParseMessage(const char* locale, UChar* pattern, int32_t patternLength,
925                        UChar* source, int32_t sourceLength, UErrorCode *status, ...)
926 {
927     va_list ap;
928     va_start(ap, status);
929     u_vparseMessage(locale, pattern, patternLength, source, sourceLength, ap, status);
930     va_end(ap);
931 }
932 
933 /*test u_vparseMessage() with various test patterns */
TestParseMessageWithValist(void)934 static void TestParseMessageWithValist(void)
935 {
936     UChar pattern[100];
937     UChar source[100];
938     UErrorCode status = U_ZERO_ERROR;
939     int32_t value;
940     UChar str[10];
941     UChar res[10];
942 
943     log_verbose("\nTesting a sample for parse Message test#9\n");
944 
945     u_uastrcpy(source, "You deposited an amount of $500.00");
946     u_uastrcpy(pattern, "You {0} an amount of {1,number,currency}");
947     u_uastrcpy(res,"deposited");
948 
949     CallParseMessage( "en_US", pattern, u_strlen(pattern), source, u_strlen(source), &status, str, &value);
950     if(U_FAILURE(status)){
951         log_data_err("ERROR: failure in parse Message on test#9: %s (Are you missing data?)\n", myErrorName(status));
952     }
953     else if(value==500.00  && u_strcmp(str,res)==0)
954         log_verbose("PASS: parseMessage successful on test#9\n");
955     else
956         log_err("FAIL: Error in parseMessage on test#9\n");
957 
958 
959     log_verbose("\nTesting a sample for parse Message test#10\n");
960 
961     u_uastrcpy(source, "There are 123 files on MyDisk created");
962     u_uastrcpy(pattern, "There are {0,number,integer} files on {1} created");
963     u_uastrcpy(res,"MyDisk");
964 
965     CallParseMessage( "en_US", pattern, u_strlen(pattern), source, u_strlen(source), &status, &value, str);
966     if(U_FAILURE(status)){
967         log_data_err("ERROR: failure in parse Message on test#10: %s (Are you missing data?)\n", myErrorName(status));
968     }
969     else if(value==123.00 && u_strcmp(str,res)==0)
970         log_verbose("PASS: parseMessage successful on test#10\n");
971     else
972         log_err("FAIL: Error in parseMessage on test#10 \n");
973 }
974 
975 /**
976  * Regression test for ICU4C Jitterbug 904
977  */
TestJ904(void)978 static void TestJ904(void) {
979     UChar pattern[256];
980     UChar result[256];
981     UChar string[16];
982     char cresult[256];
983     int32_t length;
984     UErrorCode status = U_ZERO_ERROR;
985     const char* PAT = "Number {1,number,#0.000}, String {0}, Date {2,date,12:mm:ss.SSS}";
986     const char* EXP = "Number 0,143, String foo, Date 12:34:56.789";
987 
988     ctest_setTimeZone(NULL, &status);
989 
990     u_uastrcpy(string, "foo");
991     /* Slight hack here -- instead of date pattern HH:mm:ss.SSS, use
992      * 12:mm:ss.SSS.  Why?  So this test generates the same output --
993      * "12:34:56.789" -- regardless of time zone (as long as we aren't
994      * in one of the 30 minute offset zones!). */
995     u_uastrcpy(pattern, PAT);
996     length = u_formatMessage("nl", pattern, u_strlen(pattern),
997                              result, 256, &status,
998                              string, 1/7.0,
999                              789.0+1000*(56+60*(34+60*12)));
1000 
1001     u_austrncpy(cresult, result, sizeof(cresult));
1002 
1003     /* This test passes if it DOESN'T CRASH.  However, we test the
1004      * output anyway.  If the string doesn't match in the date part,
1005      * check to see that the machine doesn't have an unusual time zone
1006      * offset, that is, one with a non-zero minutes/seconds offset
1007      * from GMT -- see above. */
1008     if (strcmp(cresult, EXP) == 0) {
1009         log_verbose("Ok: \"%s\"\n", cresult);
1010     } else {
1011         log_data_err("FAIL: got \"%s\", expected \"%s\" -> %s (Are you missing data?)\n", cresult, EXP, u_errorName(status));
1012     }
1013 
1014     ctest_resetTimeZone();
1015 }
1016 
OpenMessageFormatTest(void)1017 static void OpenMessageFormatTest(void)
1018 {
1019     UMessageFormat *f1, *f2, *f3;
1020     UChar pattern[256];
1021     UChar result[256];
1022     char cresult[256];
1023     UParseError parseError;
1024     const char* locale = "hi_IN";
1025     char* retLoc;
1026     const char* PAT = "Number {1,number,#0.000}, String {0}, Date {2,date,12:mm:ss.SSS}";
1027     int32_t length=0;
1028     UErrorCode status = U_ZERO_ERROR;
1029 
1030     u_uastrncpy(pattern, PAT, sizeof(pattern)/sizeof(pattern[0]));
1031 
1032     /* Test umsg_open                   */
1033     f1 = umsg_open(pattern,length,NULL,NULL,&status);
1034 
1035     if(U_FAILURE(status))
1036     {
1037         log_err("umsg_open failed with pattern %s. Error: \n", PAT, u_errorName(status));
1038         return;
1039     }
1040 
1041     /* Test umsg_open with parse error  */
1042     status = U_ZERO_ERROR;
1043     f2 = umsg_open(pattern,length,NULL,&parseError,&status);
1044 
1045     if(U_FAILURE(status))
1046     {
1047         log_err("umsg_open with parseError failed with pattern %s. Error: %s\n", PAT, u_errorName(status));
1048         return;
1049     }
1050 
1051     /* Test umsg_clone                  */
1052     status = U_ZERO_ERROR;
1053     f3 = umsg_clone(f1,&status);
1054     if(U_FAILURE(status))
1055     {
1056         log_err("umsg_clone failed. Error %s \n", u_errorName(status));
1057     }
1058 
1059     /* Test umsg_setLocale              */
1060     umsg_setLocale(f1,locale);
1061     /* Test umsg_getLocale              */
1062     retLoc = (char*)umsg_getLocale(f1);
1063     if(strcmp(retLoc,locale)!=0)
1064     {
1065         log_err("umsg_setLocale and umsg_getLocale methods failed. Expected:%s Got: %s \n", locale, retLoc);
1066     }
1067 
1068     /* Test umsg_applyPattern           */
1069     status = U_ZERO_ERROR;
1070     umsg_applyPattern(f1,pattern,(int32_t)strlen(PAT),NULL,&status);
1071     if(U_FAILURE(status))
1072     {
1073         log_data_err("umsg_applyPattern failed. Error %s (Are you missing data?)\n",u_errorName(status));
1074     }
1075 
1076     /* Test umsg_toPattern              */
1077     umsg_toPattern(f1,result,256,&status);
1078     if(U_FAILURE(status) ){
1079         log_data_err("umsg_toPattern method failed. Error: %s (Are you missing data?)\n",u_errorName(status));
1080     } else {
1081         if(u_strcmp(result,pattern)!=0){
1082             u_UCharsToChars(result,cresult,256);
1083             log_err("umsg_toPattern method failed. Expected: %s Got: %s \n",PAT,cresult);
1084         }
1085     }
1086     /* umsg_format umsg_parse */
1087 
1088     umsg_close(f1);
1089     umsg_close(f2);
1090     umsg_close(f3);
1091 }
1092 
MessageLength(void)1093 static void MessageLength(void)
1094 {
1095     UErrorCode status = U_ZERO_ERROR;
1096     const char patChars[] = {"123{0}456{0}"};
1097     const char expectedChars[] = {"123abc"};
1098     UChar pattern[sizeof(patChars)];
1099     UChar arg[] = {0x61,0x62,0x63,0};
1100     UChar result[128] = {0};
1101     UChar expected[sizeof(expectedChars)];
1102 
1103     u_uastrncpy(pattern, patChars, sizeof(pattern)/sizeof(pattern[0]));
1104     u_uastrncpy(expected, expectedChars, sizeof(expected)/sizeof(expected[0]));
1105 
1106     u_formatMessage("en_US", pattern, 6, result, sizeof(result)/sizeof(result[0]), &status, arg);
1107     if (U_FAILURE(status)) {
1108         log_err("u_formatMessage method failed. Error: %s \n",u_errorName(status));
1109     }
1110     if (u_strcmp(result, expected) != 0) {
1111         log_err("u_formatMessage didn't return expected result\n");
1112     }
1113 }
1114 
TestMessageWithUnusedArgNumber()1115 static void TestMessageWithUnusedArgNumber() {
1116     UErrorCode errorCode = U_ZERO_ERROR;
1117     U_STRING_DECL(pattern, "abc {1} def", 11);
1118     UChar x[2] = { 0x78, 0 };  // "x"
1119     UChar y[2] = { 0x79, 0 };  // "y"
1120     U_STRING_DECL(expected, "abc y def", 9);
1121     UChar result[20];
1122     int32_t length;
1123 
1124     U_STRING_INIT(pattern, "abc {1} def", 11);
1125     U_STRING_INIT(expected, "abc y def", 9);
1126     length = u_formatMessage("en", pattern, -1, result, LENGTHOF(result), &errorCode, x, y);
1127     if (U_FAILURE(errorCode) || length != u_strlen(expected) || u_strcmp(result, expected) != 0) {
1128         log_err("u_formatMessage(pattern with only {1}, 2 args) failed: result length %d, UErrorCode %s \n",
1129                 (int)length, u_errorName(errorCode));
1130     }
1131 }
1132 
TestErrorChaining(void)1133 static void TestErrorChaining(void) {
1134     UErrorCode status = U_USELESS_COLLATOR_ERROR;
1135 
1136     umsg_open(NULL, 0, NULL, NULL, &status);
1137     umsg_applyPattern(NULL, NULL, 0, NULL, &status);
1138     umsg_toPattern(NULL, NULL, 0, &status);
1139     umsg_clone(NULL, &status);
1140     umsg_format(NULL, NULL, 0, &status);
1141     umsg_parse(NULL, NULL, 0, NULL, &status);
1142     umsg_close(NULL);
1143 
1144     /* All of this code should have done nothing. */
1145     if (status != U_USELESS_COLLATOR_ERROR) {
1146         log_err("Status got changed to %s\n", u_errorName(status));
1147     }
1148 
1149     status = U_ZERO_ERROR;
1150     umsg_open(NULL, 0, NULL, NULL, &status);
1151     if (status != U_ILLEGAL_ARGUMENT_ERROR) {
1152         log_err("Status should be U_ILLEGAL_ARGUMENT_ERROR instead of %s\n", u_errorName(status));
1153     }
1154     status = U_ZERO_ERROR;
1155     umsg_applyPattern(NULL, NULL, 0, NULL, &status);
1156     if (status != U_ILLEGAL_ARGUMENT_ERROR) {
1157         log_err("Status should be U_ILLEGAL_ARGUMENT_ERROR instead of %s\n", u_errorName(status));
1158     }
1159     status = U_ZERO_ERROR;
1160     umsg_toPattern(NULL, NULL, 0, &status);
1161     if (status != U_ILLEGAL_ARGUMENT_ERROR) {
1162         log_err("Status should be U_ILLEGAL_ARGUMENT_ERROR instead of %s\n", u_errorName(status));
1163     }
1164     status = U_ZERO_ERROR;
1165     umsg_clone(NULL, &status);
1166     if (status != U_ILLEGAL_ARGUMENT_ERROR) {
1167         log_err("Status should be U_ILLEGAL_ARGUMENT_ERROR instead of %s\n", u_errorName(status));
1168     }
1169 }
1170 
1171 void addMsgForTest(TestNode** root);
1172 
addMsgForTest(TestNode ** root)1173 void addMsgForTest(TestNode** root)
1174 {
1175     addTest(root, &OpenMessageFormatTest, "tsformat/cmsgtst/OpenMessageFormatTest");
1176     addTest(root, &MessageFormatTest, "tsformat/cmsgtst/MessageFormatTest");
1177     addTest(root, &TestSampleMessageFormat, "tsformat/cmsgtst/TestSampleMessageFormat");
1178     addTest(root, &TestSampleFormatAndParse, "tsformat/cmsgtst/TestSampleFormatAndParse");
1179     addTest(root, &TestSampleFormatAndParseWithError, "tsformat/cmsgtst/TestSampleFormatAndParseWithError");
1180     addTest(root, &TestNewFormatAndParseAPI, "tsformat/cmsgtst/TestNewFormatAndParseAPI");
1181     addTest(root, &TestMsgFormatChoice, "tsformat/cmsgtst/TestMsgFormatChoice");
1182     addTest(root, &TestParseMessage, "tsformat/cmsgtst/TestParseMessage");
1183     addTest(root, &TestMessageFormatWithValist, "tsformat/cmsgtst/TestMessageFormatWithValist");
1184     addTest(root, &TestParseMessageWithValist, "tsformat/cmsgtst/TestParseMessageWithValist");
1185     addTest(root, &TestJ904, "tsformat/cmsgtst/TestJ904");
1186     addTest(root, &MessageLength, "tsformat/cmsgtst/MessageLength");
1187     addTest(root, &TestMessageWithUnusedArgNumber, "tsformat/cmsgtst/TestMessageWithUnusedArgNumber");
1188     addTest(root, &TestErrorChaining, "tsformat/cmsgtst/TestErrorChaining");
1189     addTest(root, &TestMsgFormatSelect, "tsformat/cmsgtst/TestMsgFormatSelect");
1190 }
1191 
1192 #endif /* #if !UCONFIG_NO_FORMATTING */
1193