1 /********************************************************************
3 * Copyright (c) 1997-2011, 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 static const char* const txt_testCasePatterns
[] = {
32 "Quotes '', '{', a {0,number,integer} '{'0}",
33 "Quotes '', '{', a {0,number,integer} '{'0}",
34 "You deposited {0,number,integer} times an amount of {1,number,currency} on {2,date,short}",
35 "'{'2,time,full}, for {1, number }, {0,number,integer} is {2,time,full} and full date is {2,date,full}",
36 "'{'1,number,percent} for {0,number,integer} is {1,number,percent}",
39 static const char* const txt_testResultStrings
[] = {
40 "Quotes ', {, a 1 {0}",
41 "Quotes ', {, a 1 {0}",
42 "You deposited 1 times an amount of $3,456.00 on 1/12/70",
43 "{2,time,full}, for 3,456, 1 is 5:46:40 AM Pacific Standard Time and full date is Monday, January 12, 1970",
44 "{1,number,percent} for 1 is 345,600%"
47 const int32_t cnt_testCases
= 5;
48 static UChar
* testCasePatterns
[5];
50 static UChar
* testResultStrings
[5];
52 static UBool strings_initialized
= FALSE
;
54 /* function used to create the test patterns for testing Message formatting */
55 static void InitStrings( void )
58 if (strings_initialized
)
61 for (i
=0; i
< cnt_testCases
; i
++ ) {
62 uint32_t strSize
= (uint32_t)strlen(txt_testCasePatterns
[i
]) + 1;
63 testCasePatterns
[i
]=(UChar
*)malloc(sizeof(UChar
) * strSize
);
64 u_uastrncpy(testCasePatterns
[i
], txt_testCasePatterns
[i
], strSize
);
66 for (i
=0; i
< cnt_testCases
; i
++ ) {
67 uint32_t strSize
= (uint32_t)strlen(txt_testResultStrings
[i
]) + 1;
68 testResultStrings
[i
] = (UChar
*)malloc(sizeof(UChar
) * strSize
);
69 u_uastrncpy(testResultStrings
[i
], txt_testResultStrings
[i
], strSize
);
72 strings_initialized
= TRUE
;
75 static void FreeStrings( void )
78 if (!strings_initialized
)
81 for (i
=0; i
< cnt_testCases
; i
++ ) {
82 free(testCasePatterns
[i
]);
84 for (i
=0; i
< cnt_testCases
; i
++ ) {
85 free(testResultStrings
[i
]);
87 strings_initialized
= FALSE
;
90 /* Platform dependent test to detect if this type will return NULL when interpreted as a pointer. */
91 static UBool
returnsNullForType(int firstParam
, ...) {
94 va_start(marker
, firstParam
);
95 isNULL
= (UBool
)(va_arg(marker
, void*) == NULL
);
100 /* Test u_formatMessage() with various test patterns() */
101 static void MessageFormatTest( void )
105 int32_t resultLengthOut
,resultlength
,i
, patternlength
;
106 UErrorCode status
= U_ZERO_ERROR
;
107 UDate d1
=1000000000.0;
109 ctest_setTimeZone(NULL
, &status
);
111 str
=(UChar
*)malloc(sizeof(UChar
) * 7);
112 u_uastrncpy(str
, "MyDisk", 7);
114 result
=(UChar
*)malloc(sizeof(UChar
) * 1);
115 log_verbose("Testing u_formatMessage()\n");
117 for (i
= 0; i
< cnt_testCases
; i
++) {
119 patternlength
=u_strlen(testCasePatterns
[i
]);
120 resultLengthOut
=u_formatMessage( "en_US",testCasePatterns
[i
], patternlength
, result
, resultlength
,
121 &status
, 1, 3456.00, d1
);
122 if(status
== U_BUFFER_OVERFLOW_ERROR
)
125 resultlength
=resultLengthOut
+1;
126 result
=(UChar
*)realloc(result
,sizeof(UChar
) * resultlength
);
127 u_formatMessage( "en_US",testCasePatterns
[i
], patternlength
, result
, resultlength
,
128 &status
, 1, 3456.00, d1
);
130 if(U_FAILURE(status
)){
131 log_data_err("ERROR: failure in message format on testcase %d: %s (Are you missing data?)\n", i
, myErrorName(status
) );
134 if(u_strcmp(result
, testResultStrings
[i
])==0){
135 log_verbose("PASS: MessagFormat successful on testcase : %d\n", i
);
138 log_err("FAIL: Error in MessageFormat on testcase : %d\n GOT %s EXPECTED %s\n", i
,
139 austrdup(result
), austrdup(testResultStrings
[i
]) );
147 for (i
= 0; i
< cnt_testCases
; i
++) {
148 UParseError parseError
;
150 patternlength
=u_strlen(testCasePatterns
[i
]);
152 resultLengthOut
=u_formatMessageWithError( "en_US",testCasePatterns
[i
], patternlength
, result
, resultlength
,
153 &parseError
,&status
, 1, 3456.00, d1
);
154 if(status
== U_BUFFER_OVERFLOW_ERROR
)
157 resultlength
=resultLengthOut
+1;
158 result
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
159 u_formatMessage( "en_US",testCasePatterns
[i
], patternlength
, result
, resultlength
,
160 &status
, 1, 3456.00, d1
);
162 if(U_FAILURE(status
)){
163 log_data_err("ERROR: failure in message format on testcase %d: %s (Are you missing data?)\n", i
, myErrorName(status
) );
166 if(u_strcmp(result
, testResultStrings
[i
])==0){
167 log_verbose("PASS: MessagFormat successful on testcase : %d\n", i
);
170 log_err("FAIL: Error in MessageFormat on testcase : %d\n GOT %s EXPECTED %s\n", i
,
171 austrdup(result
), austrdup(testResultStrings
[i
]) );
178 UErrorCode ec
= U_ZERO_ERROR
;
179 int32_t patternLength
= u_strlen(testCasePatterns
[0]);
181 UMessageFormat formatter
= umsg_open(testCasePatterns
[0],patternLength
,"en_US",NULL
,&ec
);
184 log_data_err("umsg_open() failed for testCasePattens[%d]. -> %s (Are you missing data?)\n",i
, u_errorName(ec
));
187 for(i
= 0;i
<cnt_testCases
; i
++){
188 UParseError parseError
;
189 int32_t resultLength
=0,count
=0;
195 patternLength
= u_strlen(testCasePatterns
[i
]);
197 umsg_applyPattern(formatter
,testCasePatterns
[i
],patternLength
,&parseError
,&ec
);
199 log_err("umsg_applyPattern() failed for testCasePattens[%d].\n",i
);
203 resultLength
= umsg_format(formatter
,result
,resultLength
,&ec
,1,3456.00,d1
);
204 if(ec
==U_BUFFER_OVERFLOW_ERROR
){
206 result
= (UChar
*) malloc(U_SIZEOF_UCHAR
*resultLength
+2);
207 resultLength
= umsg_format(formatter
,result
,resultLength
+2,&ec
,1,3456.00,d1
);
209 log_err("ERROR: failure in message format on testcase %d: %s\n", i
, u_errorName(status
) );
214 if(u_strcmp(result
, testResultStrings
[i
])==0){
215 log_verbose("PASS: MessagFormat successful on testcase : %d\n", i
);
218 log_err("FAIL: Error in MessageFormat on testcase : %d\n GOT %s EXPECTED %s\n", i
,
219 austrdup(result
), austrdup(testResultStrings
[i
]) );
222 #if U_PLATFORM_IS_DARWIN_BASED || (U_PLATFORM == U_PF_LINUX) /* add platforms here .. */
223 log_verbose("Skipping potentially crashing test for mismatched varargs.\n");
225 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__
);
227 if (returnsNullForType(1, (double)2.0)) {
228 /* HP/UX and possibly other platforms don't properly check for this case.
229 We pass in a UDate, but the function expects a UDate *. When va_arg is used,
230 most compilers will return NULL, but HP-UX won't do that and will return 2
231 in this case. This is a platform dependent test. It crashes on some systems.
233 If you get a crash here, see the definition of returnsNullForType.
235 This relies upon "undefined" behavior, as indicated by C99 7.15.1.1 paragraph 2
237 umsg_parse(formatter
,result
,resultLength
,&count
,&ec
,one
,two
,d2
);
238 if(ec
!=U_ILLEGAL_ARGUMENT_ERROR
){
239 log_err("FAIL: Did not get expected error for umsg_parse(). Expected: U_ILLEGAL_ARGUMENT_ERROR Got: %s \n",u_errorName(ec
));
245 log_verbose("Warning: Returning NULL for a mismatched va_arg type isn't supported on this platform.\n", i
);
249 umsg_parse(formatter
,result
,resultLength
,&count
,&ec
,&one
,&two
,&d2
);
251 log_err("umsg_parse could not parse the pattern. Error: %s.\n",u_errorName(ec
));
255 log_err("FAIL: Expected U_BUFFER_OVERFLOW error while preflighting got: %s for testCasePatterns[%d]",u_errorName(ec
),i
);
258 umsg_close(formatter
);
262 ctest_resetTimeZone();
266 /*test u_formatMessage() with sample patterns */
267 static void TestSampleMessageFormat(void)
271 UChar pattern
[100], expected
[100];
272 int32_t resultLengthOut
, resultlength
;
273 UDate d
= 837039928046.0;
274 UErrorCode status
= U_ZERO_ERROR
;
276 ctest_setTimeZone(NULL
, &status
);
278 str
=(UChar
*)malloc(sizeof(UChar
) * 15);
279 u_uastrcpy(str
, "abc");
281 u_uastrcpy(pattern
, "There are {0} files on {1,date}");
282 u_uastrcpy(expected
, "There are abc files on Jul 10, 1996");
283 result
=(UChar
*)malloc(sizeof(UChar
) * 1);
284 log_verbose("\nTesting a sample for Message format test#1\n");
286 resultLengthOut
=u_formatMessage( "en_US", pattern
, u_strlen(pattern
), result
, resultlength
, &status
, str
, d
);
287 if(status
==U_BUFFER_OVERFLOW_ERROR
)
290 resultlength
=resultLengthOut
+1;
291 result
=(UChar
*)realloc(result
, sizeof(UChar
) * resultlength
);
292 u_formatMessage( "en_US", pattern
, u_strlen(pattern
), result
, resultlength
, &status
, str
, d
);
294 if(U_FAILURE(status
)){
295 log_data_err("Error: failure in message format on test#1: %s (Are you missing data?)\n", myErrorName(status
));
297 else if(u_strcmp(result
, expected
)==0)
298 log_verbose("PASS: MessagFormat successful on test#1\n");
300 log_err("FAIL: Error in MessageFormat on test#1 \n GOT: %s EXPECTED: %s\n",
301 austrdup(result
), austrdup(expected
) );
305 log_verbose("\nTesting message format with another pattern test#2\n");
306 u_uastrcpy(pattern
, "The disk \"{0}\" contains {1,number,integer} file(s)");
307 u_uastrcpy(expected
, "The disk \"MyDisk\" contains 23 file(s)");
308 u_uastrcpy(str
, "MyDisk");
310 resultLengthOut
=u_formatMessage( "en_US",
318 if(status
==U_BUFFER_OVERFLOW_ERROR
)
321 resultlength
=resultLengthOut
+1;
322 result
=(UChar
*)realloc(result
, sizeof(UChar
) * (resultlength
+1));
323 u_formatMessage( "en_US", pattern
, u_strlen(pattern
), result
, resultlength
, &status
, str
, 23);
325 if(U_FAILURE(status
)){
326 log_data_err("Error: failure in message format on test#2 : %s (Are you missing data?)\n", myErrorName(status
));
328 else if(u_strcmp(result
, expected
)==0)
329 log_verbose("PASS: MessagFormat successful on test#2\n");
331 log_err("FAIL: Error in MessageFormat on test#2\n GOT: %s EXPECTED: %s\n",
332 austrdup(result
), austrdup(expected
) );
337 log_verbose("\nTesting message format with another pattern test#3\n");
338 u_uastrcpy(pattern
, "You made a {0} of {1,number,currency}");
339 u_uastrcpy(expected
, "You made a deposit of $500.00");
340 u_uastrcpy(str
, "deposit");
342 resultLengthOut
=u_formatMessage( "en_US", pattern
, u_strlen(pattern
), NULL
, resultlength
, &status
, str
, 500.00);
343 if(status
==U_BUFFER_OVERFLOW_ERROR
)
346 resultlength
=resultLengthOut
+1;
347 result
=(UChar
*)realloc(result
, sizeof(UChar
) * resultlength
);
348 u_formatMessage( "en_US", pattern
, u_strlen(pattern
), result
, resultlength
, &status
, str
, 500.00);
350 if(U_FAILURE(status
)){
351 log_data_err("Error: failure in message format on test#3 : %s (Are you missing data?)\n", myErrorName(status
));
353 else if(u_strcmp(result
, expected
)==0)
354 log_verbose("PASS: MessagFormat successful on test#3\n");
356 log_err("FAIL: Error in MessageFormat on test#3\n GOT: %s EXPECTED %s\n", austrdup(result
),
357 austrdup(expected
) );
363 ctest_resetTimeZone();
366 /* Test umsg_format() and umsg_parse() , format and parse sequence and round trip */
367 static void TestNewFormatAndParseAPI(void)
370 UChar
*result
, tzID
[4], str
[25];
373 int32_t resultLengthOut
, resultlength
;
377 UErrorCode status
= U_ZERO_ERROR
;
380 UParseError parseError
;
381 UMessageFormat
* fmt
= NULL
;
384 ctest_setTimeZone(NULL
, &status
);
386 log_verbose("Testing format and parse with parse error\n");
388 u_uastrcpy(str
, "disturbance in force");
389 u_uastrcpy(tzID
, "PST");
390 cal
=ucal_open(tzID
, u_strlen(tzID
), "en_US", UCAL_TRADITIONAL
, &status
);
391 if(U_FAILURE(status
)){
392 log_data_err("error in ucal_open caldef : %s - (Are you missing data?)\n", myErrorName(status
) );
395 ucal_setDateTime(cal
, 1999, UCAL_MARCH
, 18, 0, 0, 0, &status
);
396 d1
=ucal_getMillis(cal
, &status
);
397 if(U_FAILURE(status
)){
398 log_err("Error: failure in get millis: %s\n", myErrorName(status
) );
402 log_verbose("\nTesting with pattern test#4");
403 u_uastrcpy(pattern
, "On {0, date, long}, there was a {1} on planet {2,number,integer}");
404 u_uastrcpy(expected
, "On March 18, 1999, there was a disturbance in force on planet 7");
406 fmt
= umsg_open(pattern
,u_strlen(pattern
),"en_US",&parseError
,&status
);
407 if(U_FAILURE(status
)){
408 log_data_err("error in umsg_open : %s (Are you missing data?)\n", u_errorName(status
) );
411 result
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
413 resultLengthOut
=umsg_format(fmt
,result
, resultlength
,&status
, d1
, str
, 7);
414 if(status
==U_BUFFER_OVERFLOW_ERROR
)
417 resultlength
=resultLengthOut
+1;
418 result
=(UChar
*)realloc(result
, sizeof(UChar
) * resultlength
);
419 u_formatMessageWithError( "en_US", pattern
, u_strlen(pattern
), result
, resultlength
,&parseError
, &status
, d1
, str
, 7);
422 if(U_FAILURE(status
)){
423 log_err("ERROR: failure in message format test#4: %s\n", myErrorName(status
));
425 if(u_strcmp(result
, expected
)==0)
426 log_verbose("PASS: MessagFormat successful on test#4\n");
428 log_err("FAIL: Error in MessageFormat on test#4\n GOT: %s EXPECTED: %s\n", austrdup(result
),
429 austrdup(expected
) );
433 /*try to parse this and check*/
434 log_verbose("\nTesting the parse Message test#5\n");
436 umsg_parse(fmt
, result
, u_strlen(result
),&count
,&status
, &d
, ret
, &value
);
437 if(U_FAILURE(status
)){
438 log_err("ERROR: error in parsing: test#5: %s\n", myErrorName(status
));
440 if(value
!=7 && u_strcmp(str
,ret
)!=0)
441 log_err("FAIL: Error in parseMessage on test#5 \n");
443 log_verbose("PASS: parseMessage successful on test#5\n");
445 def1
= udat_open(UDAT_DEFAULT
,UDAT_DEFAULT
,NULL
, NULL
, 0, NULL
,0,&status
);
446 if(U_FAILURE(status
))
448 log_err("error in creating the dateformat using short date and time style:\n %s\n", myErrorName(status
));
451 if(u_strcmp(myDateFormat(def1
, d
), myDateFormat(def1
, d1
))==0)
452 log_verbose("PASS: parseMessage successful test#5\n");
454 log_err("FAIL: parseMessage didn't parse the date successfully\n GOT: %s EXPECTED %s\n",
455 austrdup(myDateFormat(def1
,d
)), austrdup(myDateFormat(def1
,d1
)) );
464 ctest_resetTimeZone();
467 /* Test u_formatMessageWithError() and u_parseMessageWithError() , format and parse sequence and round trip */
468 static void TestSampleFormatAndParseWithError(void)
471 UChar
*result
, *tzID
, *str
;
475 int32_t resultLengthOut
, resultlength
;
479 UErrorCode status
= U_ZERO_ERROR
;
482 UParseError parseError
;
484 ctest_setTimeZone(NULL
, &status
);
486 log_verbose("Testing format and parse with parse error\n");
488 str
=(UChar
*)malloc(sizeof(UChar
) * 25);
489 u_uastrcpy(str
, "disturbance in force");
490 tzID
=(UChar
*)malloc(sizeof(UChar
) * 4);
491 u_uastrcpy(tzID
, "PST");
492 cal
=ucal_open(tzID
, u_strlen(tzID
), "en_US", UCAL_TRADITIONAL
, &status
);
493 if(U_FAILURE(status
)){
494 log_data_err("error in ucal_open caldef : %s - (Are you missing data?)\n", myErrorName(status
) );
496 ucal_setDateTime(cal
, 1999, UCAL_MARCH
, 18, 0, 0, 0, &status
);
497 d1
=ucal_getMillis(cal
, &status
);
498 if(U_FAILURE(status
)){
499 log_data_err("Error: failure in get millis: %s - (Are you missing data?)\n", myErrorName(status
) );
502 log_verbose("\nTesting with pattern test#4");
503 u_uastrcpy(pattern
, "On {0, date, long}, there was a {1} on planet {2,number,integer}");
504 u_uastrcpy(expected
, "On March 18, 1999, there was a disturbance in force on planet 7");
506 result
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
507 resultLengthOut
=u_formatMessageWithError( "en_US", pattern
, u_strlen(pattern
), result
, resultlength
,&parseError
, &status
, d1
, str
, 7);
508 if(status
==U_BUFFER_OVERFLOW_ERROR
)
511 resultlength
=resultLengthOut
+1;
512 result
=(UChar
*)realloc(result
, sizeof(UChar
) * resultlength
);
513 u_formatMessageWithError( "en_US", pattern
, u_strlen(pattern
), result
, resultlength
,&parseError
, &status
, d1
, str
, 7);
516 if(U_FAILURE(status
)){
517 log_data_err("ERROR: failure in message format test#4: %s (Are you missing data?)\n", myErrorName(status
));
519 else if(u_strcmp(result
, expected
)==0)
520 log_verbose("PASS: MessagFormat successful on test#4\n");
522 log_err("FAIL: Error in MessageFormat on test#4\n GOT: %s EXPECTED: %s\n", austrdup(result
),
523 austrdup(expected
) );
527 /*try to parse this and check*/
528 log_verbose("\nTesting the parse Message test#5\n");
530 u_parseMessageWithError("en_US", pattern
, u_strlen(pattern
), result
, u_strlen(result
), &parseError
,&status
, &d
, ret
, &value
);
531 if(U_FAILURE(status
)){
532 log_data_err("ERROR: error in parsing: test#5: %s (Are you missing data?)\n", myErrorName(status
));
534 else if(value
!=7 && u_strcmp(str
,ret
)!=0)
535 log_err("FAIL: Error in parseMessage on test#5 \n");
537 log_verbose("PASS: parseMessage successful on test#5\n");
539 def1
= udat_open(UDAT_DEFAULT
,UDAT_DEFAULT
,NULL
, NULL
, 0, NULL
,0,&status
);
540 if(U_FAILURE(status
))
542 log_data_err("error in creating the dateformat using short date and time style: %s (Are you missing data?)\n", myErrorName(status
));
545 if(u_strcmp(myDateFormat(def1
, d
), myDateFormat(def1
, d1
))==0)
546 log_verbose("PASS: parseMessage successful test#5\n");
548 log_err("FAIL: parseMessage didn't parse the date successfully\n GOT: %s EXPECTED %s\n",
549 austrdup(myDateFormat(def1
,d
)), austrdup(myDateFormat(def1
,d1
)) );
559 ctest_resetTimeZone();
562 /* Test u_formatMessage() and u_parseMessage() , format and parse sequence and round trip */
563 static void TestSampleFormatAndParse(void)
566 UChar
*result
, *tzID
, *str
;
569 int32_t resultLengthOut
, resultlength
;
573 UErrorCode status
= U_ZERO_ERROR
;
577 ctest_setTimeZone(NULL
, &status
);
579 log_verbose("Testing format and parse\n");
581 str
=(UChar
*)malloc(sizeof(UChar
) * 25);
582 u_uastrcpy(str
, "disturbance in force");
583 tzID
=(UChar
*)malloc(sizeof(UChar
) * 4);
584 u_uastrcpy(tzID
, "PST");
585 cal
=ucal_open(tzID
, u_strlen(tzID
), "en_US", UCAL_TRADITIONAL
, &status
);
586 if(U_FAILURE(status
)){
587 log_data_err("error in ucal_open caldef : %s - (Are you missing data?)\n", myErrorName(status
) );
589 ucal_setDateTime(cal
, 1999, UCAL_MARCH
, 18, 0, 0, 0, &status
);
590 d1
=ucal_getMillis(cal
, &status
);
591 if(U_FAILURE(status
)){
592 log_data_err("Error: failure in get millis: %s - (Are you missing data?)\n", myErrorName(status
) );
595 log_verbose("\nTesting with pattern test#4");
596 u_uastrcpy(pattern
, "On {0, date, long}, there was a {1} on planet {2,number,integer}");
597 u_uastrcpy(expected
, "On March 18, 1999, there was a disturbance in force on planet 7");
599 result
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
600 resultLengthOut
=u_formatMessage( "en_US", pattern
, u_strlen(pattern
), result
, resultlength
, &status
, d1
, str
, 7);
601 if(status
==U_BUFFER_OVERFLOW_ERROR
)
604 resultlength
=resultLengthOut
+1;
605 result
=(UChar
*)realloc(result
, sizeof(UChar
) * resultlength
);
606 u_formatMessage( "en_US", pattern
, u_strlen(pattern
), result
, resultlength
, &status
, d1
, str
, 7);
609 if(U_FAILURE(status
)){
610 log_data_err("ERROR: failure in message format test#4: %s (Are you missing data?)\n", myErrorName(status
));
612 else if(u_strcmp(result
, expected
)==0)
613 log_verbose("PASS: MessagFormat successful on test#4\n");
615 log_err("FAIL: Error in MessageFormat on test#4\n GOT: %s EXPECTED: %s\n", austrdup(result
),
616 austrdup(expected
) );
620 /*try to parse this and check*/
621 log_verbose("\nTesting the parse Message test#5\n");
623 u_parseMessage("en_US", pattern
, u_strlen(pattern
), result
, u_strlen(result
), &status
, &d
, ret
, &value
);
624 if(U_FAILURE(status
)){
625 log_data_err("ERROR: error in parsing: test#5: %s (Are you missing data?)\n", myErrorName(status
));
627 else if(value
!=7 && u_strcmp(str
,ret
)!=0)
628 log_err("FAIL: Error in parseMessage on test#5 \n");
630 log_verbose("PASS: parseMessage successful on test#5\n");
632 def1
= udat_open(UDAT_DEFAULT
,UDAT_DEFAULT
,NULL
, NULL
, 0, NULL
,0,&status
);
633 if(U_FAILURE(status
))
635 log_data_err("error in creating the dateformat using short date and time style: %s (Are you missing data?)\n", myErrorName(status
));
638 if(u_strcmp(myDateFormat(def1
, d
), myDateFormat(def1
, d1
))==0)
639 log_verbose("PASS: parseMessage successful test#5\n");
641 log_err("FAIL: parseMessage didn't parse the date successfully\n GOT: %s EXPECTED %s\n",
642 austrdup(myDateFormat(def1
,d
)), austrdup(myDateFormat(def1
,d1
)) );
652 ctest_resetTimeZone();
655 /* Test message format with a Select option */
656 static void TestMsgFormatSelect(void)
660 UErrorCode status
= U_ZERO_ERROR
;
664 int32_t resultlength
,resultLengthOut
;
666 str
=(UChar
*)malloc(sizeof(UChar
) * 25);
667 u_uastrcpy(str
, "Kirti");
668 str1
=(UChar
*)malloc(sizeof(UChar
) * 25);
669 u_uastrcpy(str1
, "female");
670 log_verbose("Testing message format with Select test #1\n:");
671 u_uastrcpy(pattern
, "{0} est {1, select, female {all\\u00E9e} other {all\\u00E9}} \\u00E0 Paris.");
672 u_uastrcpy(expected
, "Kirti est all\\u00E9e \\u00E0 Paris.");
674 resultLengthOut
=u_formatMessage( "fr", pattern
, u_strlen(pattern
), NULL
, resultlength
, &status
, str
, str1
);
675 if(status
==U_BUFFER_OVERFLOW_ERROR
)
678 resultlength
=resultLengthOut
+1;
679 result
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
680 u_formatMessage( "fr", pattern
, u_strlen(pattern
), result
, resultlength
, &status
, str
, str1
);
681 if(u_strcmp(result
, expected
)==0)
682 log_verbose("PASS: MessagFormat successful on Select test#1\n");
684 log_err("FAIL: Error in MessageFormat on Select test#1\n GOT %s EXPECTED %s\n", austrdup(result
),
685 austrdup(expected
) );
689 if(U_FAILURE(status
)){
690 log_data_err("ERROR: failure in message format on Select test#1 : %s \n", myErrorName(status
));
695 /*Test a nested pattern*/
696 str
=(UChar
*)malloc(sizeof(UChar
) * 25);
697 u_uastrcpy(str
, "Noname");
698 str1
=(UChar
*)malloc(sizeof(UChar
) * 25);
699 u_uastrcpy(str1
, "other");
700 log_verbose("Testing message format with Select test #2\n:");
701 u_uastrcpy(pattern
, "{0} est {1, select, female {{2,number,integer} all\\u00E9e} other {all\\u00E9}} \\u00E0 Paris.");
702 u_uastrcpy(expected
, "Noname est all\\u00E9 \\u00E0 Paris.");
704 resultLengthOut
=u_formatMessage( "fr", pattern
, u_strlen(pattern
), NULL
, resultlength
, &status
, str
, str1
,6);
705 if(status
==U_BUFFER_OVERFLOW_ERROR
)
708 resultlength
=resultLengthOut
+1;
709 result
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
710 u_formatMessage( "fr", pattern
, u_strlen(pattern
), result
, resultlength
, &status
, str
, str1
);
711 if(u_strcmp(result
, expected
)==0)
712 log_verbose("PASS: MessagFormat successful on Select test#2\n");
714 log_err("FAIL: Error in MessageFormat on Select test#2\n GOT %s EXPECTED %s\n", austrdup(result
),
715 austrdup(expected
) );
719 if(U_FAILURE(status
)){
720 log_data_err("ERROR: failure in message format on Select test#2 : %s \n", myErrorName(status
));
726 /* test message format with a choice option */
727 static void TestMsgFormatChoice(void)
730 UErrorCode status
= U_ZERO_ERROR
;
734 int32_t resultlength
,resultLengthOut
;
736 str
=(UChar
*)malloc(sizeof(UChar
) * 25);
737 u_uastrcpy(str
, "MyDisk");
738 log_verbose("Testing message format with choice test #6\n:");
740 * Before ICU 4.8, umsg_xxx() did not detect conflicting argument types,
741 * and this pattern had {0,number,integer} as the inner argument.
742 * The choice argument has kDouble type while {0,number,integer} has kLong (int32_t).
743 * ICU 4.8 and above detects this as an error.
744 * We changed this pattern to work as intended.
746 u_uastrcpy(pattern
, "The disk {1} contains {0,choice,0#no files|1#one file|1<{0,number} files}");
747 u_uastrcpy(expected
, "The disk MyDisk contains 100 files");
749 resultLengthOut
=u_formatMessage( "en_US", pattern
, u_strlen(pattern
), NULL
, resultlength
, &status
, 100., str
);
750 if(status
==U_BUFFER_OVERFLOW_ERROR
)
753 resultlength
=resultLengthOut
+1;
754 result
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
755 u_formatMessage( "en_US", pattern
, u_strlen(pattern
), result
, resultlength
, &status
, 100., str
);
756 if(u_strcmp(result
, expected
)==0)
757 log_verbose("PASS: MessagFormat successful on test#6\n");
759 log_err("FAIL: Error in MessageFormat on test#6\n GOT %s EXPECTED %s\n", austrdup(result
),
760 austrdup(expected
) );
764 if(U_FAILURE(status
)){
765 log_data_err("ERROR: failure in message format on test#6 : %s (Are you missing data?)\n", myErrorName(status
));
768 log_verbose("Testing message format with choice test #7\n:");
769 u_uastrcpy(expected
, "The disk MyDisk contains no files");
771 resultLengthOut
=u_formatMessage( "en_US", pattern
, u_strlen(pattern
), NULL
, resultlength
, &status
, 0., str
);
772 if(status
==U_BUFFER_OVERFLOW_ERROR
)
775 resultlength
=resultLengthOut
+1;
776 result
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
777 u_formatMessage( "en_US", pattern
, u_strlen(pattern
), result
, resultlength
, &status
, 0., str
);
779 if(u_strcmp(result
, expected
)==0)
780 log_verbose("PASS: MessagFormat successful on test#7\n");
782 log_err("FAIL: Error in MessageFormat on test#7\n GOT: %s EXPECTED %s\n", austrdup(result
),
783 austrdup(expected
) );
787 if(U_FAILURE(status
)){
788 log_data_err("ERROR: failure in message format on test#7 : %s (Are you missing data?)\n", myErrorName(status
));
791 log_verbose("Testing message format with choice test #8\n:");
792 u_uastrcpy(expected
, "The disk MyDisk contains one file");
794 resultLengthOut
=u_formatMessage( "en_US", pattern
, u_strlen(pattern
), NULL
, resultlength
, &status
, 1., str
);
795 if(status
==U_BUFFER_OVERFLOW_ERROR
)
798 resultlength
=resultLengthOut
+1;
799 result
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
800 u_formatMessage( "en_US", pattern
, u_strlen(pattern
), result
, resultlength
, &status
, 1., str
);
802 if(u_strcmp(result
, expected
)==0)
803 log_verbose("PASS: MessagFormat successful on test#8\n");
805 log_err("FAIL: Error in MessageFormat on test#8\n GOT %s EXPECTED: %s\n", austrdup(result
),
806 austrdup(expected
) );
811 if(U_FAILURE(status
)){
812 log_data_err("ERROR: failure in message format on test#8 : %s (Are you missing data?)\n", myErrorName(status
));
819 /*test u_parseMessage() with various test patterns */
820 static void TestParseMessage(void)
824 UErrorCode status
= U_ZERO_ERROR
;
829 log_verbose("\nTesting a sample for parse Message test#9\n");
831 u_uastrcpy(source
, "You deposited an amount of $500.00");
832 u_uastrcpy(pattern
, "You {0} an amount of {1,number,currency}");
833 u_uastrcpy(res
,"deposited");
835 u_parseMessage( "en_US", pattern
, u_strlen(pattern
), source
, u_strlen(source
), &status
, str
, &value
);
836 if(U_FAILURE(status
)){
837 log_data_err("ERROR: failure in parse Message on test#9: %s (Are you missing data?)\n", myErrorName(status
));
839 else if(value
==500.00 && u_strcmp(str
,res
)==0)
840 log_verbose("PASS: parseMessage successful on test#9\n");
842 log_err("FAIL: Error in parseMessage on test#9 \n");
846 log_verbose("\nTesting a sample for parse Message test#10\n");
848 u_uastrcpy(source
, "There are 123 files on MyDisk created");
849 u_uastrcpy(pattern
, "There are {0,number,integer} files on {1} created");
850 u_uastrcpy(res
,"MyDisk");
852 u_parseMessage( "en_US", pattern
, u_strlen(pattern
), source
, u_strlen(source
), &status
, &value
, str
);
853 if(U_FAILURE(status
)){
854 log_data_err("ERROR: failure in parse Message on test#10: %s (Are you missing data?)\n", myErrorName(status
));
856 else if(value
==123.00 && u_strcmp(str
,res
)==0)
857 log_verbose("PASS: parseMessage successful on test#10\n");
859 log_err("FAIL: Error in parseMessage on test#10 \n");
862 static int32_t CallFormatMessage(const char* locale
, UChar
* testCasePattern
, int32_t patternLength
,
863 UChar
* result
, int32_t resultLength
, UErrorCode
*status
, ...)
867 va_start(ap
, status
);
868 len
= u_vformatMessage(locale
, testCasePattern
, patternLength
, result
, resultLength
, ap
, status
);
873 /* Test u_vformatMessage() with various test patterns. */
874 static void TestMessageFormatWithValist( void )
879 int32_t resultLengthOut
,resultlength
,i
, patternlength
;
880 UErrorCode status
= U_ZERO_ERROR
;
881 UDate d1
=1000000000.0;
883 ctest_setTimeZone(NULL
, &status
);
885 str
=(UChar
*)malloc(sizeof(UChar
) * 7);
886 u_uastrcpy(str
, "MyDisk");
888 result
=(UChar
*)malloc(sizeof(UChar
) * 1);
889 log_verbose("Testing u_formatMessage90\n");
891 for (i
= 0; i
< cnt_testCases
; i
++) {
893 patternlength
=u_strlen(testCasePatterns
[i
]);
894 resultLengthOut
=CallFormatMessage( "en_US",testCasePatterns
[i
], patternlength
, result
, resultlength
,
895 &status
, 1, 3456.00, d1
);
896 if(status
== U_BUFFER_OVERFLOW_ERROR
)
899 resultlength
=resultLengthOut
+1;
900 result
=(UChar
*)realloc(result
,sizeof(UChar
) * resultlength
);
901 CallFormatMessage( "en_US",testCasePatterns
[i
], patternlength
, result
, resultlength
,
902 &status
, 1, 3456.00, d1
);
904 if(U_FAILURE(status
)){
905 log_data_err("ERROR: failure in message format on testcase %d: %s (Are you missing data?)\n", i
, myErrorName(status
) );
907 else if(u_strcmp(result
, testResultStrings
[i
])==0){
908 log_verbose("PASS: MessagFormat successful on testcase : %d\n", i
);
911 log_err("FAIL: Error in MessageFormat on testcase : %d\n GOT %s EXPECTED %s\n", i
,
912 austrdup(result
), austrdup(testResultStrings
[i
]) );
919 ctest_resetTimeZone();
922 static void CallParseMessage(const char* locale
, UChar
* pattern
, int32_t patternLength
,
923 UChar
* source
, int32_t sourceLength
, UErrorCode
*status
, ...)
926 va_start(ap
, status
);
927 u_vparseMessage(locale
, pattern
, patternLength
, source
, sourceLength
, ap
, status
);
931 /*test u_vparseMessage() with various test patterns */
932 static void TestParseMessageWithValist(void)
936 UErrorCode status
= U_ZERO_ERROR
;
941 log_verbose("\nTesting a sample for parse Message test#9\n");
943 u_uastrcpy(source
, "You deposited an amount of $500.00");
944 u_uastrcpy(pattern
, "You {0} an amount of {1,number,currency}");
945 u_uastrcpy(res
,"deposited");
947 CallParseMessage( "en_US", pattern
, u_strlen(pattern
), source
, u_strlen(source
), &status
, str
, &value
);
948 if(U_FAILURE(status
)){
949 log_data_err("ERROR: failure in parse Message on test#9: %s (Are you missing data?)\n", myErrorName(status
));
951 else if(value
==500.00 && u_strcmp(str
,res
)==0)
952 log_verbose("PASS: parseMessage successful on test#9\n");
954 log_err("FAIL: Error in parseMessage on test#9\n");
957 log_verbose("\nTesting a sample for parse Message test#10\n");
959 u_uastrcpy(source
, "There are 123 files on MyDisk created");
960 u_uastrcpy(pattern
, "There are {0,number,integer} files on {1} created");
961 u_uastrcpy(res
,"MyDisk");
963 CallParseMessage( "en_US", pattern
, u_strlen(pattern
), source
, u_strlen(source
), &status
, &value
, str
);
964 if(U_FAILURE(status
)){
965 log_data_err("ERROR: failure in parse Message on test#10: %s (Are you missing data?)\n", myErrorName(status
));
967 else if(value
==123.00 && u_strcmp(str
,res
)==0)
968 log_verbose("PASS: parseMessage successful on test#10\n");
970 log_err("FAIL: Error in parseMessage on test#10 \n");
974 * Regression test for ICU4C Jitterbug 904
976 static void TestJ904(void) {
982 UErrorCode status
= U_ZERO_ERROR
;
983 const char* PAT
= "Number {1,number,#0.000}, String {0}, Date {2,date,12:mm:ss.SSS}";
984 const char* EXP
= "Number 0,143, String foo, Date 12:34:56.789";
986 ctest_setTimeZone(NULL
, &status
);
988 u_uastrcpy(string
, "foo");
989 /* Slight hack here -- instead of date pattern HH:mm:ss.SSS, use
990 * 12:mm:ss.SSS. Why? So this test generates the same output --
991 * "12:34:56.789" -- regardless of time zone (as long as we aren't
992 * in one of the 30 minute offset zones!). */
993 u_uastrcpy(pattern
, PAT
);
994 length
= u_formatMessage("nl", pattern
, u_strlen(pattern
),
995 result
, 256, &status
,
997 789.0+1000*(56+60*(34+60*12)));
999 u_austrncpy(cresult
, result
, sizeof(cresult
));
1001 /* This test passes if it DOESN'T CRASH. However, we test the
1002 * output anyway. If the string doesn't match in the date part,
1003 * check to see that the machine doesn't have an unusual time zone
1004 * offset, that is, one with a non-zero minutes/seconds offset
1005 * from GMT -- see above. */
1006 if (strcmp(cresult
, EXP
) == 0) {
1007 log_verbose("Ok: \"%s\"\n", cresult
);
1009 log_data_err("FAIL: got \"%s\", expected \"%s\" -> %s (Are you missing data?)\n", cresult
, EXP
, u_errorName(status
));
1012 ctest_resetTimeZone();
1015 static void OpenMessageFormatTest(void)
1017 UMessageFormat
*f1
, *f2
, *f3
;
1021 UParseError parseError
;
1022 const char* locale
= "hi_IN";
1024 const char* PAT
= "Number {1,number,#0.000}, String {0}, Date {2,date,12:mm:ss.SSS}";
1026 UErrorCode status
= U_ZERO_ERROR
;
1028 u_uastrncpy(pattern
, PAT
, sizeof(pattern
)/sizeof(pattern
[0]));
1030 /* Test umsg_open */
1031 f1
= umsg_open(pattern
,length
,NULL
,NULL
,&status
);
1033 if(U_FAILURE(status
))
1035 log_err("umsg_open failed with pattern %s. Error: \n", PAT
, u_errorName(status
));
1039 /* Test umsg_open with parse error */
1040 status
= U_ZERO_ERROR
;
1041 f2
= umsg_open(pattern
,length
,NULL
,&parseError
,&status
);
1043 if(U_FAILURE(status
))
1045 log_err("umsg_open with parseError failed with pattern %s. Error: %s\n", PAT
, u_errorName(status
));
1049 /* Test umsg_clone */
1050 status
= U_ZERO_ERROR
;
1051 f3
= umsg_clone(f1
,&status
);
1052 if(U_FAILURE(status
))
1054 log_err("umsg_clone failed. Error %s \n", u_errorName(status
));
1057 /* Test umsg_setLocale */
1058 umsg_setLocale(f1
,locale
);
1059 /* Test umsg_getLocale */
1060 retLoc
= (char*)umsg_getLocale(f1
);
1061 if(strcmp(retLoc
,locale
)!=0)
1063 log_err("umsg_setLocale and umsg_getLocale methods failed. Expected:%s Got: %s \n", locale
, retLoc
);
1066 /* Test umsg_applyPattern */
1067 status
= U_ZERO_ERROR
;
1068 umsg_applyPattern(f1
,pattern
,(int32_t)strlen(PAT
),NULL
,&status
);
1069 if(U_FAILURE(status
))
1071 log_data_err("umsg_applyPattern failed. Error %s (Are you missing data?)\n",u_errorName(status
));
1074 /* Test umsg_toPattern */
1075 umsg_toPattern(f1
,result
,256,&status
);
1076 if(U_FAILURE(status
) ){
1077 log_data_err("umsg_toPattern method failed. Error: %s (Are you missing data?)\n",u_errorName(status
));
1079 if(u_strcmp(result
,pattern
)!=0){
1080 u_UCharsToChars(result
,cresult
,256);
1081 log_err("umsg_toPattern method failed. Expected: %s Got: %s \n",PAT
,cresult
);
1084 /* umsg_format umsg_parse */
1091 static void MessageLength(void)
1093 UErrorCode status
= U_ZERO_ERROR
;
1094 const char patChars
[] = {"123{0}456{0}"};
1095 const char expectedChars
[] = {"123abc"};
1096 UChar pattern
[sizeof(patChars
)];
1097 UChar arg
[] = {0x61,0x62,0x63,0};
1098 UChar result
[128] = {0};
1099 UChar expected
[sizeof(expectedChars
)];
1101 u_uastrncpy(pattern
, patChars
, sizeof(pattern
)/sizeof(pattern
[0]));
1102 u_uastrncpy(expected
, expectedChars
, sizeof(expected
)/sizeof(expected
[0]));
1104 u_formatMessage("en_US", pattern
, 6, result
, sizeof(result
)/sizeof(result
[0]), &status
, arg
);
1105 if (U_FAILURE(status
)) {
1106 log_err("u_formatMessage method failed. Error: %s \n",u_errorName(status
));
1108 if (u_strcmp(result
, expected
) != 0) {
1109 log_err("u_formatMessage didn't return expected result\n");
1113 static void TestErrorChaining(void) {
1114 UErrorCode status
= U_USELESS_COLLATOR_ERROR
;
1116 umsg_open(NULL
, 0, NULL
, NULL
, &status
);
1117 umsg_applyPattern(NULL
, NULL
, 0, NULL
, &status
);
1118 umsg_toPattern(NULL
, NULL
, 0, &status
);
1119 umsg_clone(NULL
, &status
);
1120 umsg_format(NULL
, NULL
, 0, &status
);
1121 umsg_parse(NULL
, NULL
, 0, NULL
, &status
);
1124 /* All of this code should have done nothing. */
1125 if (status
!= U_USELESS_COLLATOR_ERROR
) {
1126 log_err("Status got changed to %s\n", u_errorName(status
));
1129 status
= U_ZERO_ERROR
;
1130 umsg_open(NULL
, 0, NULL
, NULL
, &status
);
1131 if (status
!= U_ILLEGAL_ARGUMENT_ERROR
) {
1132 log_err("Status should be U_ILLEGAL_ARGUMENT_ERROR instead of %s\n", u_errorName(status
));
1134 status
= U_ZERO_ERROR
;
1135 umsg_applyPattern(NULL
, NULL
, 0, NULL
, &status
);
1136 if (status
!= U_ILLEGAL_ARGUMENT_ERROR
) {
1137 log_err("Status should be U_ILLEGAL_ARGUMENT_ERROR instead of %s\n", u_errorName(status
));
1139 status
= U_ZERO_ERROR
;
1140 umsg_toPattern(NULL
, NULL
, 0, &status
);
1141 if (status
!= U_ILLEGAL_ARGUMENT_ERROR
) {
1142 log_err("Status should be U_ILLEGAL_ARGUMENT_ERROR instead of %s\n", u_errorName(status
));
1144 status
= U_ZERO_ERROR
;
1145 umsg_clone(NULL
, &status
);
1146 if (status
!= U_ILLEGAL_ARGUMENT_ERROR
) {
1147 log_err("Status should be U_ILLEGAL_ARGUMENT_ERROR instead of %s\n", u_errorName(status
));
1151 void addMsgForTest(TestNode
** root
);
1153 void addMsgForTest(TestNode
** root
)
1155 addTest(root
, &OpenMessageFormatTest
, "tsformat/cmsgtst/OpenMessageFormatTest");
1156 addTest(root
, &MessageFormatTest
, "tsformat/cmsgtst/MessageFormatTest");
1157 addTest(root
, &TestSampleMessageFormat
, "tsformat/cmsgtst/TestSampleMessageFormat");
1158 addTest(root
, &TestSampleFormatAndParse
, "tsformat/cmsgtst/TestSampleFormatAndParse");
1159 addTest(root
, &TestSampleFormatAndParseWithError
, "tsformat/cmsgtst/TestSampleFormatAndParseWithError");
1160 addTest(root
, &TestNewFormatAndParseAPI
, "tsformat/cmsgtst/TestNewFormatAndParseAPI");
1161 addTest(root
, &TestMsgFormatChoice
, "tsformat/cmsgtst/TestMsgFormatChoice");
1162 addTest(root
, &TestParseMessage
, "tsformat/cmsgtst/TestParseMessage");
1163 addTest(root
, &TestMessageFormatWithValist
, "tsformat/cmsgtst/TestMessageFormatWithValist");
1164 addTest(root
, &TestParseMessageWithValist
, "tsformat/cmsgtst/TestParseMessageWithValist");
1165 addTest(root
, &TestJ904
, "tsformat/cmsgtst/TestJ904");
1166 addTest(root
, &MessageLength
, "tsformat/cmsgtst/MessageLength");
1167 addTest(root
, &TestErrorChaining
, "tsformat/cmsgtst/TestErrorChaining");
1168 addTest(root
, &TestMsgFormatSelect
, "tsformat/cmsgtst/TestMsgFormatSelect");
1171 #endif /* #if !UCONFIG_NO_FORMATTING */