1/********************************************************************
2 * COPYRIGHT:
3 * Copyright (c) 1997-2009, International Business Machines Corporation and
4 * others. All Rights Reserved.
5 ********************************************************************/
6/********************************************************************************
7*
8* File CMSGTST.C
9*
10* Modification History:
11*        Name                     Description
12*     Madhu Katragadda              Creation
13*********************************************************************************
14*/
15/* C API TEST FOR MESSAGE FORMAT */
16
17#include "unicode/utypes.h"
18
19#if !UCONFIG_NO_FORMATTING
20
21#include <stdlib.h>
22#include <string.h>
23#include <stdarg.h>
24#include "unicode/uloc.h"
25#include "unicode/umsg.h"
26#include "unicode/udat.h"
27#include "unicode/umsg.h"
28#include "unicode/ustring.h"
29#include "cintltst.h"
30#include "cmsgtst.h"
31#include "cformtst.h"
32
33static 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
41static 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
49const int32_t cnt_testCases = 5;
50static UChar* testCasePatterns[5];
51
52static UChar* testResultStrings[5];
53
54static UBool strings_initialized = FALSE;
55
56/* function used to create the test patterns for testing Message formatting */
57static 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
77static 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. */
93static 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() */
103static 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 (returnsNullForType(1, (double)2.0)) {
225                    /* HP/UX and possibly other platforms don't properly check for this case.
226                    We pass in a UDate, but the function expects a UDate *.  When va_arg is used,
227                    most compilers will return NULL, but HP-UX won't do that and will return 2
228                    in this case.  This is a platform dependent test.
229
230                    This relies upon "undefined" behavior, as indicated by C99 7.15.1.1 paragraph 2
231                    */
232                    umsg_parse(formatter,result,resultLength,&count,&ec,one,two,d2);
233                    if(ec!=U_ILLEGAL_ARGUMENT_ERROR){
234                        log_err("FAIL: Did not get expected error for umsg_parse(). Expected: U_ILLEGAL_ARGUMENT_ERROR Got: %s \n",u_errorName(ec));
235                    }else{
236                        ec = U_ZERO_ERROR;
237                    }
238                }
239                else {
240                    log_verbose("Warning: Returning NULL for a mismatched va_arg type isn't supported on this platform.\n", i);
241                }
242
243                umsg_parse(formatter,result,resultLength,&count,&ec,&one,&two,&d2);
244                if(U_FAILURE(ec)){
245                    log_err("umsg_parse could not parse the pattern. Error: %s.\n",u_errorName(ec));
246                }
247                free(result);
248            }else{
249                log_err("FAIL: Expected U_BUFFER_OVERFLOW error while preflighting got: %s for testCasePatterns[%d]",u_errorName(ec),i);
250            }
251        }
252        umsg_close(formatter);
253    }
254    FreeStrings();
255
256    ctest_resetTimeZone();
257}
258
259
260/*test u_formatMessage() with sample patterns */
261static void TestSampleMessageFormat(void)
262{
263    UChar *str;
264    UChar *result;
265    UChar pattern[100], expected[100];
266    int32_t resultLengthOut, resultlength;
267    UDate d = 837039928046.0;
268    UErrorCode status = U_ZERO_ERROR;
269
270    ctest_setTimeZone(NULL, &status);
271
272    str=(UChar*)malloc(sizeof(UChar) * 15);
273    u_uastrcpy(str, "abc");
274
275    u_uastrcpy(pattern, "There are {0} files on {1,date}");
276    u_uastrcpy(expected, "There are abc files on Jul 10, 1996");
277    result=(UChar*)malloc(sizeof(UChar) * 1);
278    log_verbose("\nTesting a sample for Message format test#1\n");
279    resultlength=1;
280    resultLengthOut=u_formatMessage( "en_US", pattern, u_strlen(pattern), result, resultlength, &status, str, d);
281    if(status==U_BUFFER_OVERFLOW_ERROR)
282    {
283        status=U_ZERO_ERROR;
284        resultlength=resultLengthOut+1;
285        result=(UChar*)realloc(result, sizeof(UChar) * resultlength);
286        u_formatMessage( "en_US", pattern, u_strlen(pattern), result, resultlength, &status, str, d);
287    }
288    if(U_FAILURE(status)){
289        log_data_err("Error: failure in message format on test#1: %s (Are you missing data?)\n", myErrorName(status));
290    }
291    else if(u_strcmp(result, expected)==0)
292        log_verbose("PASS: MessagFormat successful on test#1\n");
293    else{
294        log_err("FAIL: Error in MessageFormat on test#1 \n GOT: %s EXPECTED: %s\n",
295            austrdup(result), austrdup(expected) );
296    }
297
298
299    log_verbose("\nTesting message format with another pattern test#2\n");
300    u_uastrcpy(pattern, "The disk \"{0}\" contains {1,number,integer} file(s)");
301    u_uastrcpy(expected, "The disk \"MyDisk\" contains 23 file(s)");
302    u_uastrcpy(str, "MyDisk");
303
304    resultLengthOut=u_formatMessage( "en_US",
305        pattern,
306        u_strlen(pattern),
307        result,
308        resultlength,
309        &status,
310        str,
311        235);
312    if(status==U_BUFFER_OVERFLOW_ERROR)
313    {
314        status=U_ZERO_ERROR;
315        resultlength=resultLengthOut+1;
316        result=(UChar*)realloc(result, sizeof(UChar) * (resultlength+1));
317        u_formatMessage( "en_US", pattern, u_strlen(pattern), result, resultlength, &status, str, 23);
318    }
319    if(U_FAILURE(status)){
320        log_data_err("Error: failure in message format on test#2 : %s (Are you missing data?)\n", myErrorName(status));
321    }
322    else if(u_strcmp(result, expected)==0)
323        log_verbose("PASS: MessagFormat successful on test#2\n");
324    else{
325        log_err("FAIL: Error in MessageFormat on test#2\n GOT: %s EXPECTED: %s\n",
326            austrdup(result), austrdup(expected) );
327    }
328
329
330
331    log_verbose("\nTesting message format with another pattern test#3\n");
332    u_uastrcpy(pattern, "You made a {0} of {1,number,currency}");
333    u_uastrcpy(expected, "You made a deposit of $500.00");
334    u_uastrcpy(str, "deposit");
335    resultlength=0;
336    resultLengthOut=u_formatMessage( "en_US", pattern, u_strlen(pattern), NULL, resultlength, &status, str, 500.00);
337    if(status==U_BUFFER_OVERFLOW_ERROR)
338    {
339        status=U_ZERO_ERROR;
340        resultlength=resultLengthOut+1;
341        result=(UChar*)realloc(result, sizeof(UChar) * resultlength);
342        u_formatMessage( "en_US", pattern, u_strlen(pattern), result, resultlength, &status, str, 500.00);
343    }
344    if(U_FAILURE(status)){
345        log_data_err("Error: failure in message format on test#3 : %s (Are you missing data?)\n", myErrorName(status));
346    }
347    else if(u_strcmp(result, expected)==0)
348        log_verbose("PASS: MessagFormat successful on test#3\n");
349    else{
350        log_err("FAIL: Error in MessageFormat on test#3\n GOT: %s EXPECTED %s\n", austrdup(result),
351            austrdup(expected) );
352    }
353
354    free(result);
355    free(str);
356
357    ctest_resetTimeZone();
358}
359
360/* Test umsg_format() and umsg_parse() , format and parse sequence and round trip */
361static void TestNewFormatAndParseAPI(void)
362{
363
364    UChar *result, tzID[4], str[25];
365    UChar pattern[100];
366    UChar expected[100];
367    int32_t resultLengthOut, resultlength;
368    UCalendar *cal;
369    UDate d1,d;
370    UDateFormat *def1;
371    UErrorCode status = U_ZERO_ERROR;
372    int32_t value = 0;
373    UChar ret[30];
374    UParseError parseError;
375    UMessageFormat* fmt = NULL;
376    int32_t count=0;
377
378    ctest_setTimeZone(NULL, &status);
379
380    log_verbose("Testing format and parse with parse error\n");
381
382    u_uastrcpy(str, "disturbance in force");
383    u_uastrcpy(tzID, "PST");
384    cal=ucal_open(tzID, u_strlen(tzID), "en_US", UCAL_TRADITIONAL, &status);
385    if(U_FAILURE(status)){
386        log_err("error in ucal_open caldef : %s\n", myErrorName(status) );
387        return;
388    }
389    ucal_setDateTime(cal, 1999, UCAL_MARCH, 18, 0, 0, 0, &status);
390    d1=ucal_getMillis(cal, &status);
391    if(U_FAILURE(status)){
392            log_err("Error: failure in get millis: %s\n", myErrorName(status) );
393            return;
394    }
395
396    log_verbose("\nTesting with pattern test#4");
397    u_uastrcpy(pattern, "On {0, date, long}, there was a {1} on planet {2,number,integer}");
398    u_uastrcpy(expected, "On March 18, 1999, there was a disturbance in force on planet 7");
399    resultlength=1;
400    fmt = umsg_open(pattern,u_strlen(pattern),"en_US",&parseError,&status);
401    if(U_FAILURE(status)){
402        log_data_err("error in umsg_open  : %s (Are you missing data?)\n", u_errorName(status) );
403        return;
404    }
405    result=(UChar*)malloc(sizeof(UChar) * resultlength);
406
407    resultLengthOut=umsg_format(fmt ,result, resultlength,&status, d1, str, 7);
408    if(status==U_BUFFER_OVERFLOW_ERROR)
409    {
410        status=U_ZERO_ERROR;
411        resultlength=resultLengthOut+1;
412        result=(UChar*)realloc(result, sizeof(UChar) * resultlength);
413        u_formatMessageWithError( "en_US", pattern, u_strlen(pattern), result, resultlength,&parseError, &status, d1, str, 7);
414
415    }
416    if(U_FAILURE(status)){
417        log_err("ERROR: failure in message format test#4: %s\n", myErrorName(status));
418    }
419    if(u_strcmp(result, expected)==0)
420        log_verbose("PASS: MessagFormat successful on test#4\n");
421    else{
422        log_err("FAIL: Error in MessageFormat on test#4\n GOT: %s EXPECTED: %s\n", austrdup(result),
423            austrdup(expected) );
424    }
425
426
427    /*try to parse this and check*/
428    log_verbose("\nTesting the parse Message test#5\n");
429
430    umsg_parse(fmt, result, u_strlen(result),&count,&status, &d, ret, &value);
431    if(U_FAILURE(status)){
432        log_err("ERROR: error in parsing: test#5: %s\n", myErrorName(status));
433    }
434    if(value!=7 && u_strcmp(str,ret)!=0)
435        log_err("FAIL: Error in parseMessage on test#5 \n");
436    else
437        log_verbose("PASS: parseMessage successful on test#5\n");
438
439    def1 = udat_open(UDAT_DEFAULT,UDAT_DEFAULT ,NULL, NULL, 0, NULL,0,&status);
440    if(U_FAILURE(status))
441    {
442        log_err("error in creating the dateformat using short date and time style:\n %s\n", myErrorName(status));
443    }else{
444
445        if(u_strcmp(myDateFormat(def1, d), myDateFormat(def1, d1))==0)
446            log_verbose("PASS: parseMessage successful test#5\n");
447        else{
448            log_err("FAIL: parseMessage didn't parse the date successfully\n GOT: %s EXPECTED %s\n",
449                austrdup(myDateFormat(def1,d)), austrdup(myDateFormat(def1,d1)) );
450        }
451    }
452    umsg_close(fmt);
453    udat_close(def1);
454    ucal_close(cal);
455
456    free(result);
457
458    ctest_resetTimeZone();
459}
460
461/* Test u_formatMessageWithError() and u_parseMessageWithError() , format and parse sequence and round trip */
462static void TestSampleFormatAndParseWithError(void)
463{
464
465    UChar *result, *tzID, *str;
466    UChar pattern[100];
467
468    UChar expected[100];
469    int32_t resultLengthOut, resultlength;
470    UCalendar *cal;
471    UDate d1,d;
472    UDateFormat *def1;
473    UErrorCode status = U_ZERO_ERROR;
474    int32_t value = 0;
475    UChar ret[30];
476    UParseError parseError;
477
478    ctest_setTimeZone(NULL, &status);
479
480    log_verbose("Testing format and parse with parse error\n");
481
482    str=(UChar*)malloc(sizeof(UChar) * 25);
483    u_uastrcpy(str, "disturbance in force");
484    tzID=(UChar*)malloc(sizeof(UChar) * 4);
485    u_uastrcpy(tzID, "PST");
486    cal=ucal_open(tzID, u_strlen(tzID), "en_US", UCAL_TRADITIONAL, &status);
487    if(U_FAILURE(status)){
488        log_err("error in ucal_open caldef : %s\n", myErrorName(status) );
489    }
490    ucal_setDateTime(cal, 1999, UCAL_MARCH, 18, 0, 0, 0, &status);
491    d1=ucal_getMillis(cal, &status);
492    if(U_FAILURE(status)){
493            log_err("Error: failure in get millis: %s\n", myErrorName(status) );
494    }
495
496    log_verbose("\nTesting with pattern test#4");
497    u_uastrcpy(pattern, "On {0, date, long}, there was a {1} on planet {2,number,integer}");
498    u_uastrcpy(expected, "On March 18, 1999, there was a disturbance in force on planet 7");
499    resultlength=1;
500    result=(UChar*)malloc(sizeof(UChar) * resultlength);
501    resultLengthOut=u_formatMessageWithError( "en_US", pattern, u_strlen(pattern), result, resultlength,&parseError, &status, d1, str, 7);
502    if(status==U_BUFFER_OVERFLOW_ERROR)
503    {
504        status=U_ZERO_ERROR;
505        resultlength=resultLengthOut+1;
506        result=(UChar*)realloc(result, sizeof(UChar) * resultlength);
507        u_formatMessageWithError( "en_US", pattern, u_strlen(pattern), result, resultlength,&parseError, &status, d1, str, 7);
508
509    }
510    if(U_FAILURE(status)){
511        log_data_err("ERROR: failure in message format test#4: %s (Are you missing data?)\n", myErrorName(status));
512    }
513    else if(u_strcmp(result, expected)==0)
514        log_verbose("PASS: MessagFormat successful on test#4\n");
515    else{
516        log_err("FAIL: Error in MessageFormat on test#4\n GOT: %s EXPECTED: %s\n", austrdup(result),
517            austrdup(expected) );
518    }
519
520
521    /*try to parse this and check*/
522    log_verbose("\nTesting the parse Message test#5\n");
523
524    u_parseMessageWithError("en_US", pattern, u_strlen(pattern), result, u_strlen(result), &parseError,&status, &d, ret, &value);
525    if(U_FAILURE(status)){
526        log_data_err("ERROR: error in parsing: test#5: %s (Are you missing data?)\n", myErrorName(status));
527    }
528    else if(value!=7 && u_strcmp(str,ret)!=0)
529        log_err("FAIL: Error in parseMessage on test#5 \n");
530    else
531        log_verbose("PASS: parseMessage successful on test#5\n");
532
533    def1 = udat_open(UDAT_DEFAULT,UDAT_DEFAULT ,NULL, NULL, 0, NULL,0,&status);
534    if(U_FAILURE(status))
535    {
536        log_data_err("error in creating the dateformat using short date and time style: %s (Are you missing data?)\n", myErrorName(status));
537    }else{
538
539        if(u_strcmp(myDateFormat(def1, d), myDateFormat(def1, d1))==0)
540            log_verbose("PASS: parseMessage successful test#5\n");
541        else{
542            log_err("FAIL: parseMessage didn't parse the date successfully\n GOT: %s EXPECTED %s\n",
543                austrdup(myDateFormat(def1,d)), austrdup(myDateFormat(def1,d1)) );
544        }
545    }
546    udat_close(def1);
547    ucal_close(cal);
548
549    free(result);
550    free(str);
551    free(tzID);
552
553    ctest_resetTimeZone();
554}
555
556/* Test u_formatMessage() and u_parseMessage() , format and parse sequence and round trip */
557static void TestSampleFormatAndParse(void)
558{
559
560    UChar *result, *tzID, *str;
561    UChar pattern[100];
562    UChar expected[100];
563    int32_t resultLengthOut, resultlength;
564    UCalendar *cal;
565    UDate d1,d;
566    UDateFormat *def1;
567    UErrorCode status = U_ZERO_ERROR;
568    int32_t value = 0;
569    UChar ret[30];
570
571    ctest_setTimeZone(NULL, &status);
572
573    log_verbose("Testing format and parse\n");
574
575    str=(UChar*)malloc(sizeof(UChar) * 25);
576    u_uastrcpy(str, "disturbance in force");
577    tzID=(UChar*)malloc(sizeof(UChar) * 4);
578    u_uastrcpy(tzID, "PST");
579    cal=ucal_open(tzID, u_strlen(tzID), "en_US", UCAL_TRADITIONAL, &status);
580    if(U_FAILURE(status)){
581        log_err("error in ucal_open caldef : %s\n", myErrorName(status) );
582    }
583    ucal_setDateTime(cal, 1999, UCAL_MARCH, 18, 0, 0, 0, &status);
584    d1=ucal_getMillis(cal, &status);
585    if(U_FAILURE(status)){
586            log_err("Error: failure in get millis: %s\n", myErrorName(status) );
587    }
588
589    log_verbose("\nTesting with pattern test#4");
590    u_uastrcpy(pattern, "On {0, date, long}, there was a {1} on planet {2,number,integer}");
591    u_uastrcpy(expected, "On March 18, 1999, there was a disturbance in force on planet 7");
592    resultlength=1;
593    result=(UChar*)malloc(sizeof(UChar) * resultlength);
594    resultLengthOut=u_formatMessage( "en_US", pattern, u_strlen(pattern), result, resultlength, &status, d1, str, 7);
595    if(status==U_BUFFER_OVERFLOW_ERROR)
596    {
597        status=U_ZERO_ERROR;
598        resultlength=resultLengthOut+1;
599        result=(UChar*)realloc(result, sizeof(UChar) * resultlength);
600        u_formatMessage( "en_US", pattern, u_strlen(pattern), result, resultlength, &status, d1, str, 7);
601
602    }
603    if(U_FAILURE(status)){
604        log_data_err("ERROR: failure in message format test#4: %s (Are you missing data?)\n", myErrorName(status));
605    }
606    else if(u_strcmp(result, expected)==0)
607        log_verbose("PASS: MessagFormat successful on test#4\n");
608    else{
609        log_err("FAIL: Error in MessageFormat on test#4\n GOT: %s EXPECTED: %s\n", austrdup(result),
610            austrdup(expected) );
611    }
612
613
614    /*try to parse this and check*/
615    log_verbose("\nTesting the parse Message test#5\n");
616
617    u_parseMessage("en_US", pattern, u_strlen(pattern), result, u_strlen(result), &status, &d, ret, &value);
618    if(U_FAILURE(status)){
619        log_data_err("ERROR: error in parsing: test#5: %s (Are you missing data?)\n", myErrorName(status));
620    }
621    else if(value!=7 && u_strcmp(str,ret)!=0)
622        log_err("FAIL: Error in parseMessage on test#5 \n");
623    else
624        log_verbose("PASS: parseMessage successful on test#5\n");
625
626    def1 = udat_open(UDAT_DEFAULT,UDAT_DEFAULT ,NULL, NULL, 0, NULL,0,&status);
627    if(U_FAILURE(status))
628    {
629        log_data_err("error in creating the dateformat using short date and time style: %s (Are you missing data?)\n", myErrorName(status));
630    }else{
631
632        if(u_strcmp(myDateFormat(def1, d), myDateFormat(def1, d1))==0)
633            log_verbose("PASS: parseMessage successful test#5\n");
634        else{
635            log_err("FAIL: parseMessage didn't parse the date successfully\n GOT: %s EXPECTED %s\n",
636                austrdup(myDateFormat(def1,d)), austrdup(myDateFormat(def1,d1)) );
637        }
638    }
639    udat_close(def1);
640    ucal_close(cal);
641
642    free(result);
643    free(str);
644    free(tzID);
645
646    ctest_resetTimeZone();
647}
648
649/* test message format with a choice option */
650static void TestMsgFormatChoice(void)
651{
652    UChar* str;
653    UErrorCode status = U_ZERO_ERROR;
654    UChar *result;
655    UChar pattern[100];
656    UChar expected[100];
657    int32_t resultlength,resultLengthOut;
658
659    str=(UChar*)malloc(sizeof(UChar) * 25);
660    u_uastrcpy(str, "MyDisk");
661    log_verbose("Testing message format with choice test #6\n:");
662    /*There {0,choice,0#are no files|1#is one file|1<are {0,number,integer} files}.*/
663    u_uastrcpy(pattern, "The disk {1} contains {0,choice,0#no files|1#one file|1<{0,number,integer} files}");
664    u_uastrcpy(expected, "The disk MyDisk contains 100 files");
665    resultlength=0;
666    resultLengthOut=u_formatMessage( "en_US", pattern, u_strlen(pattern), NULL, resultlength, &status, 100., str);
667    if(status==U_BUFFER_OVERFLOW_ERROR)
668    {
669        status=U_ZERO_ERROR;
670        resultlength=resultLengthOut+1;
671        result=(UChar*)malloc(sizeof(UChar) * resultlength);
672        u_formatMessage( "en_US", pattern, u_strlen(pattern), result, resultlength, &status, 100., str);
673        if(u_strcmp(result, expected)==0)
674            log_verbose("PASS: MessagFormat successful on test#6\n");
675        else{
676            log_err("FAIL: Error in MessageFormat on test#6\n GOT %s EXPECTED %s\n", austrdup(result),
677                austrdup(expected) );
678        }
679        free(result);
680    }
681    if(U_FAILURE(status)){
682        log_data_err("ERROR: failure in message format on test#6 : %s (Are you missing data?)\n", myErrorName(status));
683    }
684
685    log_verbose("Testing message format with choice test #7\n:");
686    u_uastrcpy(expected, "The disk MyDisk contains no files");
687    resultlength=0;
688    resultLengthOut=u_formatMessage( "en_US", pattern, u_strlen(pattern), NULL, resultlength, &status, 0., str);
689    if(status==U_BUFFER_OVERFLOW_ERROR)
690    {
691        status=U_ZERO_ERROR;
692        resultlength=resultLengthOut+1;
693        result=(UChar*)malloc(sizeof(UChar) * resultlength);
694        u_formatMessage( "en_US", pattern, u_strlen(pattern), result, resultlength, &status, 0., str);
695
696        if(u_strcmp(result, expected)==0)
697            log_verbose("PASS: MessagFormat successful on test#7\n");
698        else{
699            log_err("FAIL: Error in MessageFormat on test#7\n GOT: %s EXPECTED %s\n", austrdup(result),
700                austrdup(expected) );
701        }
702        free(result);
703    }
704    if(U_FAILURE(status)){
705        log_data_err("ERROR: failure in message format on test#7 : %s (Are you missing data?)\n", myErrorName(status));
706    }
707
708    log_verbose("Testing message format with choice test #8\n:");
709    u_uastrcpy(expected, "The disk MyDisk contains one file");
710    resultlength=0;
711    resultLengthOut=u_formatMessage( "en_US", pattern, u_strlen(pattern), NULL, resultlength, &status, 1., str);
712    if(status==U_BUFFER_OVERFLOW_ERROR)
713    {
714        status=U_ZERO_ERROR;
715        resultlength=resultLengthOut+1;
716        result=(UChar*)malloc(sizeof(UChar) * resultlength);
717        u_formatMessage( "en_US", pattern, u_strlen(pattern), result, resultlength, &status, 1., str);
718
719        if(u_strcmp(result, expected)==0)
720            log_verbose("PASS: MessagFormat successful on test#8\n");
721        else{
722            log_err("FAIL: Error in MessageFormat on test#8\n GOT %s EXPECTED: %s\n", austrdup(result),
723                austrdup(expected) );
724        }
725
726        free(result);
727    }
728    if(U_FAILURE(status)){
729        log_data_err("ERROR: failure in message format on test#8 : %s (Are you missing data?)\n", myErrorName(status));
730    }
731
732    free(str);
733
734}
735
736/*test u_parseMessage() with various test patterns */
737static void TestParseMessage(void)
738{
739    UChar pattern[100];
740    UChar source[100];
741    UErrorCode status = U_ZERO_ERROR;
742    int32_t value;
743    UChar str[10];
744    UChar res[10];
745
746    log_verbose("\nTesting a sample for parse Message test#9\n");
747
748    u_uastrcpy(source, "You deposited an amount of $500.00");
749    u_uastrcpy(pattern, "You {0} an amount of {1,number,currency}");
750    u_uastrcpy(res,"deposited");
751
752    u_parseMessage( "en_US", pattern, u_strlen(pattern), source, u_strlen(source), &status, str, &value);
753    if(U_FAILURE(status)){
754        log_data_err("ERROR: failure in parse Message on test#9: %s (Are you missing data?)\n", myErrorName(status));
755    }
756    else if(value==500.00  && u_strcmp(str,res)==0)
757        log_verbose("PASS: parseMessage successful on test#9\n");
758    else
759        log_err("FAIL: Error in parseMessage on test#9 \n");
760
761
762
763    log_verbose("\nTesting a sample for parse Message test#10\n");
764
765    u_uastrcpy(source, "There are 123 files on MyDisk created");
766    u_uastrcpy(pattern, "There are {0,number,integer} files on {1} created");
767    u_uastrcpy(res,"MyDisk");
768
769    u_parseMessage( "en_US", pattern, u_strlen(pattern), source, u_strlen(source), &status, &value, str);
770    if(U_FAILURE(status)){
771        log_data_err("ERROR: failure in parse Message on test#10: %s (Are you missing data?)\n", myErrorName(status));
772    }
773    else if(value==123.00 && u_strcmp(str,res)==0)
774        log_verbose("PASS: parseMessage successful on test#10\n");
775    else
776        log_err("FAIL: Error in parseMessage on test#10 \n");
777}
778
779static int32_t CallFormatMessage(const char* locale, UChar* testCasePattern, int32_t patternLength,
780                       UChar* result, int32_t resultLength, UErrorCode *status, ...)
781{
782    int32_t len = 0;
783    va_list ap;
784    va_start(ap, status);
785    len = u_vformatMessage(locale, testCasePattern, patternLength, result, resultLength, ap, status);
786    va_end(ap);
787    return len;
788}
789
790/* Test u_vformatMessage() with various test patterns. */
791static void TestMessageFormatWithValist( void )
792{
793
794    UChar *str;
795    UChar* result;
796    int32_t resultLengthOut,resultlength,i, patternlength;
797    UErrorCode status = U_ZERO_ERROR;
798    UDate d1=1000000000.0;
799
800    ctest_setTimeZone(NULL, &status);
801
802    str=(UChar*)malloc(sizeof(UChar) * 7);
803    u_uastrcpy(str, "MyDisk");
804    resultlength=1;
805    result=(UChar*)malloc(sizeof(UChar) * 1);
806    log_verbose("Testing u_formatMessage90\n");
807    InitStrings();
808    for (i = 0; i < cnt_testCases; i++) {
809        status=U_ZERO_ERROR;
810        patternlength=u_strlen(testCasePatterns[i]);
811        resultLengthOut=CallFormatMessage( "en_US",testCasePatterns[i], patternlength, result, resultlength,
812            &status, 1, 3456.00, d1);
813        if(status== U_BUFFER_OVERFLOW_ERROR)
814        {
815            status=U_ZERO_ERROR;
816            resultlength=resultLengthOut+1;
817            result=(UChar*)realloc(result,sizeof(UChar) * resultlength);
818            CallFormatMessage( "en_US",testCasePatterns[i], patternlength, result, resultlength,
819                &status, 1, 3456.00, d1);
820        }
821        if(U_FAILURE(status)){
822            log_data_err("ERROR: failure in message format on testcase %d:  %s (Are you missing data?)\n", i, myErrorName(status) );
823        }
824        else if(u_strcmp(result, testResultStrings[i])==0){
825            log_verbose("PASS: MessagFormat successful on testcase : %d\n", i);
826        }
827        else{
828            log_err("FAIL: Error in MessageFormat on testcase : %d\n GOT %s EXPECTED %s\n", i,
829                austrdup(result), austrdup(testResultStrings[i]) );
830        }
831    }
832    free(result);
833    free(str);
834    FreeStrings();
835
836    ctest_resetTimeZone();
837}
838
839static void CallParseMessage(const char* locale, UChar* pattern, int32_t patternLength,
840                       UChar* source, int32_t sourceLength, UErrorCode *status, ...)
841{
842    va_list ap;
843    va_start(ap, status);
844    u_vparseMessage(locale, pattern, patternLength, source, sourceLength, ap, status);
845    va_end(ap);
846}
847
848/*test u_vparseMessage() with various test patterns */
849static void TestParseMessageWithValist(void)
850{
851    UChar pattern[100];
852    UChar source[100];
853    UErrorCode status = U_ZERO_ERROR;
854    int32_t value;
855    UChar str[10];
856    UChar res[10];
857
858    log_verbose("\nTesting a sample for parse Message test#9\n");
859
860    u_uastrcpy(source, "You deposited an amount of $500.00");
861    u_uastrcpy(pattern, "You {0} an amount of {1,number,currency}");
862    u_uastrcpy(res,"deposited");
863
864    CallParseMessage( "en_US", pattern, u_strlen(pattern), source, u_strlen(source), &status, str, &value);
865    if(U_FAILURE(status)){
866        log_data_err("ERROR: failure in parse Message on test#9: %s (Are you missing data?)\n", myErrorName(status));
867    }
868    else if(value==500.00  && u_strcmp(str,res)==0)
869        log_verbose("PASS: parseMessage successful on test#9\n");
870    else
871        log_err("FAIL: Error in parseMessage on test#9\n");
872
873
874    log_verbose("\nTesting a sample for parse Message test#10\n");
875
876    u_uastrcpy(source, "There are 123 files on MyDisk created");
877    u_uastrcpy(pattern, "There are {0,number,integer} files on {1} created");
878    u_uastrcpy(res,"MyDisk");
879
880    CallParseMessage( "en_US", pattern, u_strlen(pattern), source, u_strlen(source), &status, &value, str);
881    if(U_FAILURE(status)){
882        log_data_err("ERROR: failure in parse Message on test#10: %s (Are you missing data?)\n", myErrorName(status));
883    }
884    else if(value==123.00 && u_strcmp(str,res)==0)
885        log_verbose("PASS: parseMessage successful on test#10\n");
886    else
887        log_err("FAIL: Error in parseMessage on test#10 \n");
888}
889
890/**
891 * Regression test for ICU4C Jitterbug 904
892 */
893static void TestJ904(void) {
894    UChar pattern[256];
895    UChar result[256];
896    UChar string[16];
897    char cresult[256];
898    int32_t length;
899    UErrorCode status = U_ZERO_ERROR;
900    const char* PAT = "Number {1,number,#0.000}, String {0}, Date {2,date,12:mm:ss.SSS}";
901    const char* EXP = "Number 0,143, String foo, Date 12:34:56.789";
902
903    ctest_setTimeZone(NULL, &status);
904
905    u_uastrcpy(string, "foo");
906    /* Slight hack here -- instead of date pattern HH:mm:ss.SSS, use
907     * 12:mm:ss.SSS.  Why?  So this test generates the same output --
908     * "12:34:56.789" -- regardless of time zone (as long as we aren't
909     * in one of the 30 minute offset zones!). */
910    u_uastrcpy(pattern, PAT);
911    length = u_formatMessage("nl", pattern, u_strlen(pattern),
912                             result, 256, &status,
913                             string, 1/7.0,
914                             789.0+1000*(56+60*(34+60*12)));
915
916    u_austrncpy(cresult, result, sizeof(cresult));
917
918    /* This test passes if it DOESN'T CRASH.  However, we test the
919     * output anyway.  If the string doesn't match in the date part,
920     * check to see that the machine doesn't have an unusual time zone
921     * offset, that is, one with a non-zero minutes/seconds offset
922     * from GMT -- see above. */
923    if (strcmp(cresult, EXP) == 0) {
924        log_verbose("Ok: \"%s\"\n", cresult);
925    } else {
926        log_data_err("FAIL: got \"%s\", expected \"%s\" -> %s (Are you missing data?)\n", cresult, EXP, u_errorName(status));
927    }
928
929    ctest_resetTimeZone();
930}
931
932static void OpenMessageFormatTest(void)
933{
934    UMessageFormat *f1, *f2, *f3;
935    UChar pattern[256];
936    UChar result[256];
937    char cresult[256];
938    UParseError parseError;
939    const char* locale = "hi_IN";
940    char* retLoc;
941    const char* PAT = "Number {1,number,#0.000}, String {0}, Date {2,date,12:mm:ss.SSS}";
942    int32_t length=0;
943    UErrorCode status = U_ZERO_ERROR;
944
945    u_uastrncpy(pattern, PAT, sizeof(pattern)/sizeof(pattern[0]));
946
947    /* Test umsg_open                   */
948    f1 = umsg_open(pattern,length,NULL,NULL,&status);
949
950    if(U_FAILURE(status))
951    {
952        log_err("umsg_open failed with pattern %s. Error: \n", PAT, u_errorName(status));
953        return;
954    }
955
956    /* Test umsg_open with parse error  */
957    status = U_ZERO_ERROR;
958    f2 = umsg_open(pattern,length,NULL,&parseError,&status);
959
960    if(U_FAILURE(status))
961    {
962        log_err("umsg_open with parseError failed with pattern %s. Error: %s\n", PAT, u_errorName(status));
963        return;
964    }
965
966    /* Test umsg_clone                  */
967    status = U_ZERO_ERROR;
968    f3 = umsg_clone(f1,&status);
969    if(U_FAILURE(status))
970    {
971        log_err("umsg_clone failed. Error %s \n", u_errorName(status));
972    }
973
974    /* Test umsg_setLocale              */
975    umsg_setLocale(f1,locale);
976    /* Test umsg_getLocale              */
977    retLoc = (char*)umsg_getLocale(f1);
978    if(strcmp(retLoc,locale)!=0)
979    {
980        log_err("umsg_setLocale and umsg_getLocale methods failed. Expected:%s Got: %s \n", locale, retLoc);
981    }
982
983    /* Test umsg_applyPattern           */
984    status = U_ZERO_ERROR;
985    umsg_applyPattern(f1,pattern,(int32_t)strlen(PAT),NULL,&status);
986    if(U_FAILURE(status))
987    {
988        log_data_err("umsg_applyPattern failed. Error %s (Are you missing data?)\n",u_errorName(status));
989    }
990
991    /* Test umsg_toPattern              */
992    umsg_toPattern(f1,result,256,&status);
993    if(U_FAILURE(status) ){
994        log_data_err("umsg_toPattern method failed. Error: %s (Are you missing data?)\n",u_errorName(status));
995    } else {
996        if(u_strcmp(result,pattern)!=0){
997            u_UCharsToChars(result,cresult,256);
998            log_err("umsg_toPattern method failed. Expected: %s Got: %s \n",PAT,cresult);
999        }
1000    }
1001    /* umsg_format umsg_parse */
1002
1003    umsg_close(f1);
1004    umsg_close(f2);
1005    umsg_close(f3);
1006}
1007
1008static void MessageLength(void)
1009{
1010    UErrorCode status = U_ZERO_ERROR;
1011    const char patChars[] = {"123{0}456{0}"};
1012    const char expectedChars[] = {"123abc"};
1013    UChar pattern[sizeof(patChars)];
1014    UChar arg[] = {0x61,0x62,0x63,0};
1015    UChar result[128] = {0};
1016    UChar expected[sizeof(expectedChars)];
1017
1018    u_uastrncpy(pattern, patChars, sizeof(pattern)/sizeof(pattern[0]));
1019    u_uastrncpy(expected, expectedChars, sizeof(expected)/sizeof(expected[0]));
1020
1021    u_formatMessage("en_US", pattern, 6, result, sizeof(result)/sizeof(result[0]), &status, arg);
1022    if (U_FAILURE(status)) {
1023        log_err("u_formatMessage method failed. Error: %s \n",u_errorName(status));
1024    }
1025    if (u_strcmp(result, expected) != 0) {
1026        log_err("u_formatMessage didn't return expected result\n");
1027    }
1028}
1029
1030static void TestErrorChaining(void) {
1031    UErrorCode status = U_USELESS_COLLATOR_ERROR;
1032
1033    umsg_open(NULL, 0, NULL, NULL, &status);
1034    umsg_applyPattern(NULL, NULL, 0, NULL, &status);
1035    umsg_toPattern(NULL, NULL, 0, &status);
1036    umsg_clone(NULL, &status);
1037    umsg_format(NULL, NULL, 0, &status);
1038    umsg_parse(NULL, NULL, 0, NULL, &status);
1039    umsg_close(NULL);
1040
1041    /* All of this code should have done nothing. */
1042    if (status != U_USELESS_COLLATOR_ERROR) {
1043        log_err("Status got changed to %s\n", u_errorName(status));
1044    }
1045
1046    status = U_ZERO_ERROR;
1047    umsg_open(NULL, 0, NULL, NULL, &status);
1048    if (status != U_ILLEGAL_ARGUMENT_ERROR) {
1049        log_err("Status should be U_ILLEGAL_ARGUMENT_ERROR instead of %s\n", u_errorName(status));
1050    }
1051    status = U_ZERO_ERROR;
1052    umsg_applyPattern(NULL, NULL, 0, NULL, &status);
1053    if (status != U_ILLEGAL_ARGUMENT_ERROR) {
1054        log_err("Status should be U_ILLEGAL_ARGUMENT_ERROR instead of %s\n", u_errorName(status));
1055    }
1056    status = U_ZERO_ERROR;
1057    umsg_toPattern(NULL, NULL, 0, &status);
1058    if (status != U_ILLEGAL_ARGUMENT_ERROR) {
1059        log_err("Status should be U_ILLEGAL_ARGUMENT_ERROR instead of %s\n", u_errorName(status));
1060    }
1061    status = U_ZERO_ERROR;
1062    umsg_clone(NULL, &status);
1063    if (status != U_ILLEGAL_ARGUMENT_ERROR) {
1064        log_err("Status should be U_ILLEGAL_ARGUMENT_ERROR instead of %s\n", u_errorName(status));
1065    }
1066}
1067
1068void addMsgForTest(TestNode** root);
1069
1070void addMsgForTest(TestNode** root)
1071{
1072    addTest(root, &OpenMessageFormatTest, "tsformat/cmsgtst/OpenMessageFormatTest");
1073    addTest(root, &MessageFormatTest, "tsformat/cmsgtst/MessageFormatTest");
1074    addTest(root, &TestSampleMessageFormat, "tsformat/cmsgtst/TestSampleMessageFormat");
1075    addTest(root, &TestSampleFormatAndParse, "tsformat/cmsgtst/TestSampleFormatAndParse");
1076    addTest(root, &TestSampleFormatAndParseWithError, "tsformat/cmsgtst/TestSampleFormatAndParseWithError");
1077    addTest(root, &TestNewFormatAndParseAPI, "tsformat/cmsgtst/TestNewFormatAndParseAPI");
1078    addTest(root, &TestMsgFormatChoice, "tsformat/cmsgtst/TestMsgFormatChoice");
1079    addTest(root, &TestParseMessage, "tsformat/cmsgtst/TestParseMessage");
1080    addTest(root, &TestMessageFormatWithValist, "tsformat/cmsgtst/TestMessageFormatWithValist");
1081    addTest(root, &TestParseMessageWithValist, "tsformat/cmsgtst/TestParseMessageWithValist");
1082    addTest(root, &TestJ904, "tsformat/cmsgtst/TestJ904");
1083    addTest(root, &MessageLength, "tsformat/cmsgtst/MessageLength");
1084    addTest(root, &TestErrorChaining, "tsformat/cmsgtst/TestErrorChaining");
1085}
1086
1087#endif /* #if !UCONFIG_NO_FORMATTING */
1088