1 /********************************************************************
3 * Copyright (c) 1997-2012, International Business Machines Corporation and
4 * others. All Rights Reserved.
5 ********************************************************************
9 * Modification History:
11 * Madhu Katragadda Creation
12 ********************************************************************/
13 /* C API TEST FOR MESSAGE FORMAT */
15 #include "unicode/utypes.h"
17 #if !UCONFIG_NO_FORMATTING
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"
31 #define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
33 static const char* const txt_testCasePatterns
[] = {
34 "Quotes '', '{', a {0,number,integer} '{'0}",
35 "Quotes '', '{', a {0,number,integer} '{'0}",
36 "You deposited {0,number,integer} times an amount of {1,number,currency} on {2,date,short}",
37 "'{'2,time,full}, for {1, number }, {0,number,integer} is {2,time,full} and full date is {2,date,full}",
38 "'{'1,number,percent} for {0,number,integer} is {1,number,percent}",
41 static const char* const txt_testResultStrings
[] = {
42 "Quotes ', {, a 1 {0}",
43 "Quotes ', {, a 1 {0}",
44 "You deposited 1 times an amount of $3,456.00 on 1/12/70",
45 "{2,time,full}, for 3,456, 1 is 5:46:40 AM Pacific Standard Time and full date is Monday, January 12, 1970",
46 "{1,number,percent} for 1 is 345,600%"
49 const int32_t cnt_testCases
= 5;
50 static UChar
* testCasePatterns
[5];
52 static UChar
* testResultStrings
[5];
54 static UBool strings_initialized
= FALSE
;
56 /* function used to create the test patterns for testing Message formatting */
57 static void InitStrings( void )
60 if (strings_initialized
)
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
);
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
);
74 strings_initialized
= TRUE
;
77 static void FreeStrings( void )
80 if (!strings_initialized
)
83 for (i
=0; i
< cnt_testCases
; i
++ ) {
84 free(testCasePatterns
[i
]);
86 for (i
=0; i
< cnt_testCases
; i
++ ) {
87 free(testResultStrings
[i
]);
89 strings_initialized
= FALSE
;
92 #if (U_PLATFORM == U_PF_LINUX) /* add platforms here .. */
93 /* Keep the #if above in sync with the one below that has the same "add platforms here .." comment. */
95 /* Platform dependent test to detect if this type will return NULL when interpreted as a pointer. */
96 static UBool
returnsNullForType(int firstParam
, ...) {
99 va_start(marker
, firstParam
);
100 isNULL
= (UBool
)(va_arg(marker
, void*) == NULL
);
106 /* Test u_formatMessage() with various test patterns() */
107 static void MessageFormatTest( void )
111 int32_t resultLengthOut
,resultlength
,i
, patternlength
;
112 UErrorCode status
= U_ZERO_ERROR
;
113 UDate d1
=1000000000.0;
115 ctest_setTimeZone(NULL
, &status
);
117 str
=(UChar
*)malloc(sizeof(UChar
) * 7);
118 u_uastrncpy(str
, "MyDisk", 7);
120 result
=(UChar
*)malloc(sizeof(UChar
) * 1);
121 log_verbose("Testing u_formatMessage()\n");
123 for (i
= 0; i
< cnt_testCases
; i
++) {
125 patternlength
=u_strlen(testCasePatterns
[i
]);
126 resultLengthOut
=u_formatMessage( "en_US",testCasePatterns
[i
], patternlength
, result
, resultlength
,
127 &status
, 1, 3456.00, d1
);
128 if(status
== U_BUFFER_OVERFLOW_ERROR
)
131 resultlength
=resultLengthOut
+1;
132 result
=(UChar
*)realloc(result
,sizeof(UChar
) * resultlength
);
133 u_formatMessage( "en_US",testCasePatterns
[i
], patternlength
, result
, resultlength
,
134 &status
, 1, 3456.00, d1
);
136 if(U_FAILURE(status
)){
137 log_data_err("ERROR: failure in message format on testcase %d: %s (Are you missing data?)\n", i
, myErrorName(status
) );
140 if(u_strcmp(result
, testResultStrings
[i
])==0){
141 log_verbose("PASS: MessagFormat successful on testcase : %d\n", i
);
144 log_err("FAIL: Error in MessageFormat on testcase : %d\n GOT %s EXPECTED %s\n", i
,
145 austrdup(result
), austrdup(testResultStrings
[i
]) );
153 for (i
= 0; i
< cnt_testCases
; i
++) {
154 UParseError parseError
;
156 patternlength
=u_strlen(testCasePatterns
[i
]);
158 resultLengthOut
=u_formatMessageWithError( "en_US",testCasePatterns
[i
], patternlength
, result
, resultlength
,
159 &parseError
,&status
, 1, 3456.00, d1
);
160 if(status
== U_BUFFER_OVERFLOW_ERROR
)
163 resultlength
=resultLengthOut
+1;
164 result
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
165 u_formatMessage( "en_US",testCasePatterns
[i
], patternlength
, result
, resultlength
,
166 &status
, 1, 3456.00, d1
);
168 if(U_FAILURE(status
)){
169 log_data_err("ERROR: failure in message format on testcase %d: %s (Are you missing data?)\n", i
, myErrorName(status
) );
172 if(u_strcmp(result
, testResultStrings
[i
])==0){
173 log_verbose("PASS: MessagFormat successful on testcase : %d\n", i
);
176 log_err("FAIL: Error in MessageFormat on testcase : %d\n GOT %s EXPECTED %s\n", i
,
177 austrdup(result
), austrdup(testResultStrings
[i
]) );
184 UErrorCode ec
= U_ZERO_ERROR
;
185 int32_t patternLength
= u_strlen(testCasePatterns
[0]);
187 UMessageFormat formatter
= umsg_open(testCasePatterns
[0],patternLength
,"en_US",NULL
,&ec
);
190 log_data_err("umsg_open() failed for testCasePattens[%d]. -> %s (Are you missing data?)\n",i
, u_errorName(ec
));
193 for(i
= 0;i
<cnt_testCases
; i
++){
194 UParseError parseError
;
195 int32_t resultLength
=0,count
=0;
201 patternLength
= u_strlen(testCasePatterns
[i
]);
203 umsg_applyPattern(formatter
,testCasePatterns
[i
],patternLength
,&parseError
,&ec
);
205 log_err("umsg_applyPattern() failed for testCasePattens[%d].\n",i
);
209 resultLength
= umsg_format(formatter
,result
,resultLength
,&ec
,1,3456.00,d1
);
210 if(ec
==U_BUFFER_OVERFLOW_ERROR
){
212 result
= (UChar
*) malloc(U_SIZEOF_UCHAR
*resultLength
+2);
213 resultLength
= umsg_format(formatter
,result
,resultLength
+2,&ec
,1,3456.00,d1
);
215 log_err("ERROR: failure in message format on testcase %d: %s\n", i
, u_errorName(status
) );
220 if(u_strcmp(result
, testResultStrings
[i
])==0){
221 log_verbose("PASS: MessagFormat successful on testcase : %d\n", i
);
224 log_err("FAIL: Error in MessageFormat on testcase : %d\n GOT %s EXPECTED %s\n", i
,
225 austrdup(result
), austrdup(testResultStrings
[i
]) );
228 #if (U_PLATFORM == U_PF_LINUX) /* add platforms here .. */
229 log_verbose("Skipping potentially crashing test for mismatched varargs.\n");
231 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__
);
233 if (returnsNullForType(1, (double)2.0)) {
234 /* HP/UX and possibly other platforms don't properly check for this case.
235 We pass in a UDate, but the function expects a UDate *. When va_arg is used,
236 most compilers will return NULL, but HP-UX won't do that and will return 2
237 in this case. This is a platform dependent test. It crashes on some systems.
239 If you get a crash here, see the definition of returnsNullForType.
241 This relies upon "undefined" behavior, as indicated by C99 7.15.1.1 paragraph 2
243 umsg_parse(formatter
,result
,resultLength
,&count
,&ec
,one
,two
,d2
);
244 if(ec
!=U_ILLEGAL_ARGUMENT_ERROR
){
245 log_err("FAIL: Did not get expected error for umsg_parse(). Expected: U_ILLEGAL_ARGUMENT_ERROR Got: %s \n",u_errorName(ec
));
251 log_verbose("Warning: Returning NULL for a mismatched va_arg type isn't supported on this platform.\n", i
);
255 umsg_parse(formatter
,result
,resultLength
,&count
,&ec
,&one
,&two
,&d2
);
257 log_err("umsg_parse could not parse the pattern. Error: %s.\n",u_errorName(ec
));
261 log_err("FAIL: Expected U_BUFFER_OVERFLOW error while preflighting got: %s for testCasePatterns[%d]",u_errorName(ec
),i
);
264 umsg_close(formatter
);
268 ctest_resetTimeZone();
272 /*test u_formatMessage() with sample patterns */
273 static void TestSampleMessageFormat(void)
277 UChar pattern
[100], expected
[100];
278 int32_t resultLengthOut
, resultlength
;
279 UDate d
= 837039928046.0;
280 UErrorCode status
= U_ZERO_ERROR
;
282 ctest_setTimeZone(NULL
, &status
);
284 str
=(UChar
*)malloc(sizeof(UChar
) * 15);
285 u_uastrcpy(str
, "abc");
287 u_uastrcpy(pattern
, "There are {0} files on {1,date}");
288 u_uastrcpy(expected
, "There are abc files on Jul 10, 1996");
289 result
=(UChar
*)malloc(sizeof(UChar
) * 1);
290 log_verbose("\nTesting a sample for Message format test#1\n");
292 resultLengthOut
=u_formatMessage( "en_US", pattern
, u_strlen(pattern
), result
, resultlength
, &status
, str
, d
);
293 if(status
==U_BUFFER_OVERFLOW_ERROR
)
296 resultlength
=resultLengthOut
+1;
297 result
=(UChar
*)realloc(result
, sizeof(UChar
) * resultlength
);
298 u_formatMessage( "en_US", pattern
, u_strlen(pattern
), result
, resultlength
, &status
, str
, d
);
300 if(U_FAILURE(status
)){
301 log_data_err("Error: failure in message format on test#1: %s (Are you missing data?)\n", myErrorName(status
));
303 else if(u_strcmp(result
, expected
)==0)
304 log_verbose("PASS: MessagFormat successful on test#1\n");
306 log_err("FAIL: Error in MessageFormat on test#1 \n GOT: %s EXPECTED: %s\n",
307 austrdup(result
), austrdup(expected
) );
311 log_verbose("\nTesting message format with another pattern test#2\n");
312 u_uastrcpy(pattern
, "The disk \"{0}\" contains {1,number,integer} file(s)");
313 u_uastrcpy(expected
, "The disk \"MyDisk\" contains 23 file(s)");
314 u_uastrcpy(str
, "MyDisk");
316 resultLengthOut
=u_formatMessage( "en_US",
324 if(status
==U_BUFFER_OVERFLOW_ERROR
)
327 resultlength
=resultLengthOut
+1;
328 result
=(UChar
*)realloc(result
, sizeof(UChar
) * (resultlength
+1));
329 u_formatMessage( "en_US", pattern
, u_strlen(pattern
), result
, resultlength
, &status
, str
, 23);
331 if(U_FAILURE(status
)){
332 log_data_err("Error: failure in message format on test#2 : %s (Are you missing data?)\n", myErrorName(status
));
334 else if(u_strcmp(result
, expected
)==0)
335 log_verbose("PASS: MessagFormat successful on test#2\n");
337 log_err("FAIL: Error in MessageFormat on test#2\n GOT: %s EXPECTED: %s\n",
338 austrdup(result
), austrdup(expected
) );
343 log_verbose("\nTesting message format with another pattern test#3\n");
344 u_uastrcpy(pattern
, "You made a {0} of {1,number,currency}");
345 u_uastrcpy(expected
, "You made a deposit of $500.00");
346 u_uastrcpy(str
, "deposit");
348 resultLengthOut
=u_formatMessage( "en_US", pattern
, u_strlen(pattern
), NULL
, resultlength
, &status
, str
, 500.00);
349 if(status
==U_BUFFER_OVERFLOW_ERROR
)
352 resultlength
=resultLengthOut
+1;
353 result
=(UChar
*)realloc(result
, sizeof(UChar
) * resultlength
);
354 u_formatMessage( "en_US", pattern
, u_strlen(pattern
), result
, resultlength
, &status
, str
, 500.00);
356 if(U_FAILURE(status
)){
357 log_data_err("Error: failure in message format on test#3 : %s (Are you missing data?)\n", myErrorName(status
));
359 else if(u_strcmp(result
, expected
)==0)
360 log_verbose("PASS: MessagFormat successful on test#3\n");
362 log_err("FAIL: Error in MessageFormat on test#3\n GOT: %s EXPECTED %s\n", austrdup(result
),
363 austrdup(expected
) );
369 ctest_resetTimeZone();
372 /* Test umsg_format() and umsg_parse() , format and parse sequence and round trip */
373 static void TestNewFormatAndParseAPI(void)
376 UChar
*result
, tzID
[4], str
[25];
379 int32_t resultLengthOut
, resultlength
;
383 UErrorCode status
= U_ZERO_ERROR
;
386 UParseError parseError
;
387 UMessageFormat
* fmt
= NULL
;
390 ctest_setTimeZone(NULL
, &status
);
392 log_verbose("Testing format and parse with parse error\n");
394 u_uastrcpy(str
, "disturbance in force");
395 u_uastrcpy(tzID
, "PST");
396 cal
=ucal_open(tzID
, u_strlen(tzID
), "en_US", UCAL_TRADITIONAL
, &status
);
397 if(U_FAILURE(status
)){
398 log_data_err("error in ucal_open caldef : %s - (Are you missing data?)\n", myErrorName(status
) );
401 ucal_setDateTime(cal
, 1999, UCAL_MARCH
, 18, 0, 0, 0, &status
);
402 d1
=ucal_getMillis(cal
, &status
);
403 if(U_FAILURE(status
)){
404 log_err("Error: failure in get millis: %s\n", myErrorName(status
) );
408 log_verbose("\nTesting with pattern test#4");
409 u_uastrcpy(pattern
, "On {0, date, long}, there was a {1} on planet {2,number,integer}");
410 u_uastrcpy(expected
, "On March 18, 1999, there was a disturbance in force on planet 7");
412 fmt
= umsg_open(pattern
,u_strlen(pattern
),"en_US",&parseError
,&status
);
413 if(U_FAILURE(status
)){
414 log_data_err("error in umsg_open : %s (Are you missing data?)\n", u_errorName(status
) );
417 result
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
419 resultLengthOut
=umsg_format(fmt
,result
, resultlength
,&status
, d1
, str
, 7);
420 if(status
==U_BUFFER_OVERFLOW_ERROR
)
423 resultlength
=resultLengthOut
+1;
424 result
=(UChar
*)realloc(result
, sizeof(UChar
) * resultlength
);
425 u_formatMessageWithError( "en_US", pattern
, u_strlen(pattern
), result
, resultlength
,&parseError
, &status
, d1
, str
, 7);
428 if(U_FAILURE(status
)){
429 log_err("ERROR: failure in message format test#4: %s\n", myErrorName(status
));
431 if(u_strcmp(result
, expected
)==0)
432 log_verbose("PASS: MessagFormat successful on test#4\n");
434 log_err("FAIL: Error in MessageFormat on test#4\n GOT: %s EXPECTED: %s\n", austrdup(result
),
435 austrdup(expected
) );
439 /*try to parse this and check*/
440 log_verbose("\nTesting the parse Message test#5\n");
442 umsg_parse(fmt
, result
, u_strlen(result
),&count
,&status
, &d
, ret
, &value
);
443 if(U_FAILURE(status
)){
444 log_err("ERROR: error in parsing: test#5: %s\n", myErrorName(status
));
446 if(value
!=7 && u_strcmp(str
,ret
)!=0)
447 log_err("FAIL: Error in parseMessage on test#5 \n");
449 log_verbose("PASS: parseMessage successful on test#5\n");
451 def1
= udat_open(UDAT_DEFAULT
,UDAT_DEFAULT
,NULL
, NULL
, 0, NULL
,0,&status
);
452 if(U_FAILURE(status
))
454 log_err("error in creating the dateformat using short date and time style:\n %s\n", myErrorName(status
));
457 if(u_strcmp(myDateFormat(def1
, d
), myDateFormat(def1
, d1
))==0)
458 log_verbose("PASS: parseMessage successful test#5\n");
460 log_err("FAIL: parseMessage didn't parse the date successfully\n GOT: %s EXPECTED %s\n",
461 austrdup(myDateFormat(def1
,d
)), austrdup(myDateFormat(def1
,d1
)) );
470 ctest_resetTimeZone();
473 /* Test u_formatMessageWithError() and u_parseMessageWithError() , format and parse sequence and round trip */
474 static void TestSampleFormatAndParseWithError(void)
477 UChar
*result
, *tzID
, *str
;
481 int32_t resultLengthOut
, resultlength
;
485 UErrorCode status
= U_ZERO_ERROR
;
488 UParseError parseError
;
490 ctest_setTimeZone(NULL
, &status
);
492 log_verbose("Testing format and parse with parse error\n");
494 str
=(UChar
*)malloc(sizeof(UChar
) * 25);
495 u_uastrcpy(str
, "disturbance in force");
496 tzID
=(UChar
*)malloc(sizeof(UChar
) * 4);
497 u_uastrcpy(tzID
, "PST");
498 cal
=ucal_open(tzID
, u_strlen(tzID
), "en_US", UCAL_TRADITIONAL
, &status
);
499 if(U_FAILURE(status
)){
500 log_data_err("error in ucal_open caldef : %s - (Are you missing data?)\n", myErrorName(status
) );
502 ucal_setDateTime(cal
, 1999, UCAL_MARCH
, 18, 0, 0, 0, &status
);
503 d1
=ucal_getMillis(cal
, &status
);
504 if(U_FAILURE(status
)){
505 log_data_err("Error: failure in get millis: %s - (Are you missing data?)\n", myErrorName(status
) );
508 log_verbose("\nTesting with pattern test#4");
509 u_uastrcpy(pattern
, "On {0, date, long}, there was a {1} on planet {2,number,integer}");
510 u_uastrcpy(expected
, "On March 18, 1999, there was a disturbance in force on planet 7");
512 result
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
513 resultLengthOut
=u_formatMessageWithError( "en_US", pattern
, u_strlen(pattern
), result
, resultlength
,&parseError
, &status
, d1
, str
, 7);
514 if(status
==U_BUFFER_OVERFLOW_ERROR
)
517 resultlength
=resultLengthOut
+1;
518 result
=(UChar
*)realloc(result
, sizeof(UChar
) * resultlength
);
519 u_formatMessageWithError( "en_US", pattern
, u_strlen(pattern
), result
, resultlength
,&parseError
, &status
, d1
, str
, 7);
522 if(U_FAILURE(status
)){
523 log_data_err("ERROR: failure in message format test#4: %s (Are you missing data?)\n", myErrorName(status
));
525 else if(u_strcmp(result
, expected
)==0)
526 log_verbose("PASS: MessagFormat successful on test#4\n");
528 log_err("FAIL: Error in MessageFormat on test#4\n GOT: %s EXPECTED: %s\n", austrdup(result
),
529 austrdup(expected
) );
533 /*try to parse this and check*/
534 log_verbose("\nTesting the parse Message test#5\n");
536 u_parseMessageWithError("en_US", pattern
, u_strlen(pattern
), result
, u_strlen(result
), &parseError
,&status
, &d
, ret
, &value
);
537 if(U_FAILURE(status
)){
538 log_data_err("ERROR: error in parsing: test#5: %s (Are you missing data?)\n", myErrorName(status
));
540 else if(value
!=7 && u_strcmp(str
,ret
)!=0)
541 log_err("FAIL: Error in parseMessage on test#5 \n");
543 log_verbose("PASS: parseMessage successful on test#5\n");
545 def1
= udat_open(UDAT_DEFAULT
,UDAT_DEFAULT
,NULL
, NULL
, 0, NULL
,0,&status
);
546 if(U_FAILURE(status
))
548 log_data_err("error in creating the dateformat using short date and time style: %s (Are you missing data?)\n", myErrorName(status
));
551 if(u_strcmp(myDateFormat(def1
, d
), myDateFormat(def1
, d1
))==0)
552 log_verbose("PASS: parseMessage successful test#5\n");
554 log_err("FAIL: parseMessage didn't parse the date successfully\n GOT: %s EXPECTED %s\n",
555 austrdup(myDateFormat(def1
,d
)), austrdup(myDateFormat(def1
,d1
)) );
565 ctest_resetTimeZone();
568 /* Test u_formatMessage() and u_parseMessage() , format and parse sequence and round trip */
569 static void TestSampleFormatAndParse(void)
572 UChar
*result
, *tzID
, *str
;
575 int32_t resultLengthOut
, resultlength
;
579 UErrorCode status
= U_ZERO_ERROR
;
583 ctest_setTimeZone(NULL
, &status
);
585 log_verbose("Testing format and parse\n");
587 str
=(UChar
*)malloc(sizeof(UChar
) * 25);
588 u_uastrcpy(str
, "disturbance in force");
589 tzID
=(UChar
*)malloc(sizeof(UChar
) * 4);
590 u_uastrcpy(tzID
, "PST");
591 cal
=ucal_open(tzID
, u_strlen(tzID
), "en_US", UCAL_TRADITIONAL
, &status
);
592 if(U_FAILURE(status
)){
593 log_data_err("error in ucal_open caldef : %s - (Are you missing data?)\n", myErrorName(status
) );
595 ucal_setDateTime(cal
, 1999, UCAL_MARCH
, 18, 0, 0, 0, &status
);
596 d1
=ucal_getMillis(cal
, &status
);
597 if(U_FAILURE(status
)){
598 log_data_err("Error: failure in get millis: %s - (Are you missing data?)\n", myErrorName(status
) );
601 log_verbose("\nTesting with pattern test#4");
602 u_uastrcpy(pattern
, "On {0, date, long}, there was a {1} on planet {2,number,integer}");
603 u_uastrcpy(expected
, "On March 18, 1999, there was a disturbance in force on planet 7");
605 result
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
606 resultLengthOut
=u_formatMessage( "en_US", pattern
, u_strlen(pattern
), result
, resultlength
, &status
, d1
, str
, 7);
607 if(status
==U_BUFFER_OVERFLOW_ERROR
)
610 resultlength
=resultLengthOut
+1;
611 result
=(UChar
*)realloc(result
, sizeof(UChar
) * resultlength
);
612 u_formatMessage( "en_US", pattern
, u_strlen(pattern
), result
, resultlength
, &status
, d1
, str
, 7);
615 if(U_FAILURE(status
)){
616 log_data_err("ERROR: failure in message format test#4: %s (Are you missing data?)\n", myErrorName(status
));
618 else if(u_strcmp(result
, expected
)==0)
619 log_verbose("PASS: MessagFormat successful on test#4\n");
621 log_err("FAIL: Error in MessageFormat on test#4\n GOT: %s EXPECTED: %s\n", austrdup(result
),
622 austrdup(expected
) );
626 /*try to parse this and check*/
627 log_verbose("\nTesting the parse Message test#5\n");
629 u_parseMessage("en_US", pattern
, u_strlen(pattern
), result
, u_strlen(result
), &status
, &d
, ret
, &value
);
630 if(U_FAILURE(status
)){
631 log_data_err("ERROR: error in parsing: test#5: %s (Are you missing data?)\n", myErrorName(status
));
633 else if(value
!=7 && u_strcmp(str
,ret
)!=0)
634 log_err("FAIL: Error in parseMessage on test#5 \n");
636 log_verbose("PASS: parseMessage successful on test#5\n");
638 def1
= udat_open(UDAT_DEFAULT
,UDAT_DEFAULT
,NULL
, NULL
, 0, NULL
,0,&status
);
639 if(U_FAILURE(status
))
641 log_data_err("error in creating the dateformat using short date and time style: %s (Are you missing data?)\n", myErrorName(status
));
644 if(u_strcmp(myDateFormat(def1
, d
), myDateFormat(def1
, d1
))==0)
645 log_verbose("PASS: parseMessage successful test#5\n");
647 log_err("FAIL: parseMessage didn't parse the date successfully\n GOT: %s EXPECTED %s\n",
648 austrdup(myDateFormat(def1
,d
)), austrdup(myDateFormat(def1
,d1
)) );
658 ctest_resetTimeZone();
661 /* Test message format with a Select option */
662 static void TestMsgFormatSelect(void)
666 UErrorCode status
= U_ZERO_ERROR
;
670 int32_t resultlength
,resultLengthOut
;
672 str
=(UChar
*)malloc(sizeof(UChar
) * 25);
673 u_uastrcpy(str
, "Kirti");
674 str1
=(UChar
*)malloc(sizeof(UChar
) * 25);
675 u_uastrcpy(str1
, "female");
676 log_verbose("Testing message format with Select test #1\n:");
677 u_uastrcpy(pattern
, "{0} est {1, select, female {all\\u00E9e} other {all\\u00E9}} \\u00E0 Paris.");
678 u_uastrcpy(expected
, "Kirti est all\\u00E9e \\u00E0 Paris.");
680 resultLengthOut
=u_formatMessage( "fr", pattern
, u_strlen(pattern
), NULL
, resultlength
, &status
, str
, str1
);
681 if(status
==U_BUFFER_OVERFLOW_ERROR
)
684 resultlength
=resultLengthOut
+1;
685 result
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
686 u_formatMessage( "fr", pattern
, u_strlen(pattern
), result
, resultlength
, &status
, str
, str1
);
687 if(u_strcmp(result
, expected
)==0)
688 log_verbose("PASS: MessagFormat successful on Select test#1\n");
690 log_err("FAIL: Error in MessageFormat on Select test#1\n GOT %s EXPECTED %s\n", austrdup(result
),
691 austrdup(expected
) );
695 if(U_FAILURE(status
)){
696 log_data_err("ERROR: failure in message format on Select test#1 : %s \n", myErrorName(status
));
701 /*Test a nested pattern*/
702 str
=(UChar
*)malloc(sizeof(UChar
) * 25);
703 u_uastrcpy(str
, "Noname");
704 str1
=(UChar
*)malloc(sizeof(UChar
) * 25);
705 u_uastrcpy(str1
, "other");
706 log_verbose("Testing message format with Select test #2\n:");
707 u_uastrcpy(pattern
, "{0} est {1, select, female {{2,number,integer} all\\u00E9e} other {all\\u00E9}} \\u00E0 Paris.");
708 u_uastrcpy(expected
, "Noname est all\\u00E9 \\u00E0 Paris.");
710 resultLengthOut
=u_formatMessage( "fr", pattern
, u_strlen(pattern
), NULL
, resultlength
, &status
, str
, str1
,6);
711 if(status
==U_BUFFER_OVERFLOW_ERROR
)
714 resultlength
=resultLengthOut
+1;
715 result
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
716 u_formatMessage( "fr", pattern
, u_strlen(pattern
), result
, resultlength
, &status
, str
, str1
);
717 if(u_strcmp(result
, expected
)==0)
718 log_verbose("PASS: MessagFormat successful on Select test#2\n");
720 log_err("FAIL: Error in MessageFormat on Select test#2\n GOT %s EXPECTED %s\n", austrdup(result
),
721 austrdup(expected
) );
725 if(U_FAILURE(status
)){
726 log_data_err("ERROR: failure in message format on Select test#2 : %s \n", myErrorName(status
));
732 /* test message format with a choice option */
733 static void TestMsgFormatChoice(void)
736 UErrorCode status
= U_ZERO_ERROR
;
740 int32_t resultlength
,resultLengthOut
;
742 str
=(UChar
*)malloc(sizeof(UChar
) * 25);
743 u_uastrcpy(str
, "MyDisk");
744 log_verbose("Testing message format with choice test #6\n:");
746 * Before ICU 4.8, umsg_xxx() did not detect conflicting argument types,
747 * and this pattern had {0,number,integer} as the inner argument.
748 * The choice argument has kDouble type while {0,number,integer} has kLong (int32_t).
749 * ICU 4.8 and above detects this as an error.
750 * We changed this pattern to work as intended.
752 u_uastrcpy(pattern
, "The disk {1} contains {0,choice,0#no files|1#one file|1<{0,number} files}");
753 u_uastrcpy(expected
, "The disk MyDisk contains 100 files");
755 resultLengthOut
=u_formatMessage( "en_US", pattern
, u_strlen(pattern
), NULL
, resultlength
, &status
, 100., str
);
756 if(status
==U_BUFFER_OVERFLOW_ERROR
)
759 resultlength
=resultLengthOut
+1;
760 result
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
761 u_formatMessage( "en_US", pattern
, u_strlen(pattern
), result
, resultlength
, &status
, 100., str
);
762 if(u_strcmp(result
, expected
)==0)
763 log_verbose("PASS: MessagFormat successful on test#6\n");
765 log_err("FAIL: Error in MessageFormat on test#6\n GOT %s EXPECTED %s\n", austrdup(result
),
766 austrdup(expected
) );
770 if(U_FAILURE(status
)){
771 log_data_err("ERROR: failure in message format on test#6 : %s (Are you missing data?)\n", myErrorName(status
));
774 log_verbose("Testing message format with choice test #7\n:");
775 u_uastrcpy(expected
, "The disk MyDisk contains no files");
777 resultLengthOut
=u_formatMessage( "en_US", pattern
, u_strlen(pattern
), NULL
, resultlength
, &status
, 0., str
);
778 if(status
==U_BUFFER_OVERFLOW_ERROR
)
781 resultlength
=resultLengthOut
+1;
782 result
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
783 u_formatMessage( "en_US", pattern
, u_strlen(pattern
), result
, resultlength
, &status
, 0., str
);
785 if(u_strcmp(result
, expected
)==0)
786 log_verbose("PASS: MessagFormat successful on test#7\n");
788 log_err("FAIL: Error in MessageFormat on test#7\n GOT: %s EXPECTED %s\n", austrdup(result
),
789 austrdup(expected
) );
793 if(U_FAILURE(status
)){
794 log_data_err("ERROR: failure in message format on test#7 : %s (Are you missing data?)\n", myErrorName(status
));
797 log_verbose("Testing message format with choice test #8\n:");
798 u_uastrcpy(expected
, "The disk MyDisk contains one file");
800 resultLengthOut
=u_formatMessage( "en_US", pattern
, u_strlen(pattern
), NULL
, resultlength
, &status
, 1., str
);
801 if(status
==U_BUFFER_OVERFLOW_ERROR
)
804 resultlength
=resultLengthOut
+1;
805 result
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
806 u_formatMessage( "en_US", pattern
, u_strlen(pattern
), result
, resultlength
, &status
, 1., str
);
808 if(u_strcmp(result
, expected
)==0)
809 log_verbose("PASS: MessagFormat successful on test#8\n");
811 log_err("FAIL: Error in MessageFormat on test#8\n GOT %s EXPECTED: %s\n", austrdup(result
),
812 austrdup(expected
) );
817 if(U_FAILURE(status
)){
818 log_data_err("ERROR: failure in message format on test#8 : %s (Are you missing data?)\n", myErrorName(status
));
825 /*test u_parseMessage() with various test patterns */
826 static void TestParseMessage(void)
830 UErrorCode status
= U_ZERO_ERROR
;
835 log_verbose("\nTesting a sample for parse Message test#9\n");
837 u_uastrcpy(source
, "You deposited an amount of $500.00");
838 u_uastrcpy(pattern
, "You {0} an amount of {1,number,currency}");
839 u_uastrcpy(res
,"deposited");
841 u_parseMessage( "en_US", pattern
, u_strlen(pattern
), source
, u_strlen(source
), &status
, str
, &value
);
842 if(U_FAILURE(status
)){
843 log_data_err("ERROR: failure in parse Message on test#9: %s (Are you missing data?)\n", myErrorName(status
));
845 else if(value
==500.00 && u_strcmp(str
,res
)==0)
846 log_verbose("PASS: parseMessage successful on test#9\n");
848 log_err("FAIL: Error in parseMessage on test#9 \n");
852 log_verbose("\nTesting a sample for parse Message test#10\n");
854 u_uastrcpy(source
, "There are 123 files on MyDisk created");
855 u_uastrcpy(pattern
, "There are {0,number,integer} files on {1} created");
856 u_uastrcpy(res
,"MyDisk");
858 u_parseMessage( "en_US", pattern
, u_strlen(pattern
), source
, u_strlen(source
), &status
, &value
, str
);
859 if(U_FAILURE(status
)){
860 log_data_err("ERROR: failure in parse Message on test#10: %s (Are you missing data?)\n", myErrorName(status
));
862 else if(value
==123.00 && u_strcmp(str
,res
)==0)
863 log_verbose("PASS: parseMessage successful on test#10\n");
865 log_err("FAIL: Error in parseMessage on test#10 \n");
868 static int32_t CallFormatMessage(const char* locale
, UChar
* testCasePattern
, int32_t patternLength
,
869 UChar
* result
, int32_t resultLength
, UErrorCode
*status
, ...)
873 va_start(ap
, status
);
874 len
= u_vformatMessage(locale
, testCasePattern
, patternLength
, result
, resultLength
, ap
, status
);
879 /* Test u_vformatMessage() with various test patterns. */
880 static void TestMessageFormatWithValist( void )
885 int32_t resultLengthOut
,resultlength
,i
, patternlength
;
886 UErrorCode status
= U_ZERO_ERROR
;
887 UDate d1
=1000000000.0;
889 ctest_setTimeZone(NULL
, &status
);
891 str
=(UChar
*)malloc(sizeof(UChar
) * 7);
892 u_uastrcpy(str
, "MyDisk");
894 result
=(UChar
*)malloc(sizeof(UChar
) * 1);
895 log_verbose("Testing u_formatMessage90\n");
897 for (i
= 0; i
< cnt_testCases
; i
++) {
899 patternlength
=u_strlen(testCasePatterns
[i
]);
900 resultLengthOut
=CallFormatMessage( "en_US",testCasePatterns
[i
], patternlength
, result
, resultlength
,
901 &status
, 1, 3456.00, d1
);
902 if(status
== U_BUFFER_OVERFLOW_ERROR
)
905 resultlength
=resultLengthOut
+1;
906 result
=(UChar
*)realloc(result
,sizeof(UChar
) * resultlength
);
907 CallFormatMessage( "en_US",testCasePatterns
[i
], patternlength
, result
, resultlength
,
908 &status
, 1, 3456.00, d1
);
910 if(U_FAILURE(status
)){
911 log_data_err("ERROR: failure in message format on testcase %d: %s (Are you missing data?)\n", i
, myErrorName(status
) );
913 else if(u_strcmp(result
, testResultStrings
[i
])==0){
914 log_verbose("PASS: MessagFormat successful on testcase : %d\n", i
);
917 log_err("FAIL: Error in MessageFormat on testcase : %d\n GOT %s EXPECTED %s\n", i
,
918 austrdup(result
), austrdup(testResultStrings
[i
]) );
925 ctest_resetTimeZone();
928 static void CallParseMessage(const char* locale
, UChar
* pattern
, int32_t patternLength
,
929 UChar
* source
, int32_t sourceLength
, UErrorCode
*status
, ...)
932 va_start(ap
, status
);
933 u_vparseMessage(locale
, pattern
, patternLength
, source
, sourceLength
, ap
, status
);
937 /*test u_vparseMessage() with various test patterns */
938 static void TestParseMessageWithValist(void)
942 UErrorCode status
= U_ZERO_ERROR
;
947 log_verbose("\nTesting a sample for parse Message test#9\n");
949 u_uastrcpy(source
, "You deposited an amount of $500.00");
950 u_uastrcpy(pattern
, "You {0} an amount of {1,number,currency}");
951 u_uastrcpy(res
,"deposited");
953 CallParseMessage( "en_US", pattern
, u_strlen(pattern
), source
, u_strlen(source
), &status
, str
, &value
);
954 if(U_FAILURE(status
)){
955 log_data_err("ERROR: failure in parse Message on test#9: %s (Are you missing data?)\n", myErrorName(status
));
957 else if(value
==500.00 && u_strcmp(str
,res
)==0)
958 log_verbose("PASS: parseMessage successful on test#9\n");
960 log_err("FAIL: Error in parseMessage on test#9\n");
963 log_verbose("\nTesting a sample for parse Message test#10\n");
965 u_uastrcpy(source
, "There are 123 files on MyDisk created");
966 u_uastrcpy(pattern
, "There are {0,number,integer} files on {1} created");
967 u_uastrcpy(res
,"MyDisk");
969 CallParseMessage( "en_US", pattern
, u_strlen(pattern
), source
, u_strlen(source
), &status
, &value
, str
);
970 if(U_FAILURE(status
)){
971 log_data_err("ERROR: failure in parse Message on test#10: %s (Are you missing data?)\n", myErrorName(status
));
973 else if(value
==123.00 && u_strcmp(str
,res
)==0)
974 log_verbose("PASS: parseMessage successful on test#10\n");
976 log_err("FAIL: Error in parseMessage on test#10 \n");
980 * Regression test for ICU4C Jitterbug 904
982 static void TestJ904(void) {
988 UErrorCode status
= U_ZERO_ERROR
;
989 const char* PAT
= "Number {1,number,#0.000}, String {0}, Date {2,date,12:mm:ss.SSS}";
990 const char* EXP
= "Number 0,143, String foo, Date 12:34:56.789";
992 ctest_setTimeZone(NULL
, &status
);
994 u_uastrcpy(string
, "foo");
995 /* Slight hack here -- instead of date pattern HH:mm:ss.SSS, use
996 * 12:mm:ss.SSS. Why? So this test generates the same output --
997 * "12:34:56.789" -- regardless of time zone (as long as we aren't
998 * in one of the 30 minute offset zones!). */
999 u_uastrcpy(pattern
, PAT
);
1000 length
= u_formatMessage("nl", pattern
, u_strlen(pattern
),
1001 result
, 256, &status
,
1003 789.0+1000*(56+60*(34+60*12)));
1005 u_austrncpy(cresult
, result
, sizeof(cresult
));
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
);
1015 log_data_err("FAIL: got \"%s\", expected \"%s\" -> %s (Are you missing data?)\n", cresult
, EXP
, u_errorName(status
));
1018 ctest_resetTimeZone();
1021 static void OpenMessageFormatTest(void)
1023 UMessageFormat
*f1
, *f2
, *f3
;
1027 UParseError parseError
;
1028 const char* locale
= "hi_IN";
1030 const char* PAT
= "Number {1,number,#0.000}, String {0}, Date {2,date,12:mm:ss.SSS}";
1032 UErrorCode status
= U_ZERO_ERROR
;
1034 u_uastrncpy(pattern
, PAT
, sizeof(pattern
)/sizeof(pattern
[0]));
1036 /* Test umsg_open */
1037 f1
= umsg_open(pattern
,length
,NULL
,NULL
,&status
);
1039 if(U_FAILURE(status
))
1041 log_err("umsg_open failed with pattern %s. Error: \n", PAT
, u_errorName(status
));
1045 /* Test umsg_open with parse error */
1046 status
= U_ZERO_ERROR
;
1047 f2
= umsg_open(pattern
,length
,NULL
,&parseError
,&status
);
1049 if(U_FAILURE(status
))
1051 log_err("umsg_open with parseError failed with pattern %s. Error: %s\n", PAT
, u_errorName(status
));
1055 /* Test umsg_clone */
1056 status
= U_ZERO_ERROR
;
1057 f3
= umsg_clone(f1
,&status
);
1058 if(U_FAILURE(status
))
1060 log_err("umsg_clone failed. Error %s \n", u_errorName(status
));
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)
1069 log_err("umsg_setLocale and umsg_getLocale methods failed. Expected:%s Got: %s \n", locale
, retLoc
);
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
))
1077 log_data_err("umsg_applyPattern failed. Error %s (Are you missing data?)\n",u_errorName(status
));
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
));
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
);
1090 /* umsg_format umsg_parse */
1097 static void MessageLength(void)
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
)];
1107 u_uastrncpy(pattern
, patChars
, sizeof(pattern
)/sizeof(pattern
[0]));
1108 u_uastrncpy(expected
, expectedChars
, sizeof(expected
)/sizeof(expected
[0]));
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
));
1114 if (u_strcmp(result
, expected
) != 0) {
1115 log_err("u_formatMessage didn't return expected result\n");
1119 static 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);
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
, 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
));
1137 static void TestErrorChaining(void) {
1138 UErrorCode status
= U_USELESS_COLLATOR_ERROR
;
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
);
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
));
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
));
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
));
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
));
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
));
1175 void addMsgForTest(TestNode
** root
);
1177 void addMsgForTest(TestNode
** root
)
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");
1196 #endif /* #if !UCONFIG_NO_FORMATTING */