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