1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /********************************************************************
5 * Copyright (c) 1997-2016, International Business Machines Corporation and
6 * others. All Rights Reserved.
7 ********************************************************************
11 * Modification History:
13 * Madhu Katragadda Creation
14 ********************************************************************/
15 /* C API TEST FOR MESSAGE FORMAT */
17 #include "unicode/utypes.h"
19 #if !UCONFIG_NO_FORMATTING
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"
34 static const char* const txt_testCasePatterns
[] = {
35 "Quotes '', '{', a {0,number,integer} '{'0}",
36 "Quotes '', '{', a {0,number,integer} '{'0}",
37 "You deposited {0,number,integer} times an amount of {1,number,currency} on {2,date,short}",
38 "'{'2,time,full}, for {1, number }, {0,number,integer} is {2,time,full} and full date is {2,date,full}",
39 "'{'1,number,percent} for {0,number,integer} is {1,number,percent}",
42 static const char* const txt_testResultStrings
[] = {
43 "Quotes ', {, a 1 {0}",
44 "Quotes ', {, a 1 {0}",
45 "You deposited 1 times an amount of $3,456.00 on 1/12/70",
46 "{2,time,full}, for 3,456, 1 is 5:46:40 AM Pacific Standard Time and full date is Monday, January 12, 1970",
47 "{1,number,percent} for 1 is 345,600%"
50 const int32_t cnt_testCases
= 5;
51 static UChar
* testCasePatterns
[5];
53 static UChar
* testResultStrings
[5];
55 static UBool strings_initialized
= FALSE
;
57 /* function used to create the test patterns for testing Message formatting */
58 static void InitStrings( void )
61 if (strings_initialized
)
64 for (i
=0; i
< cnt_testCases
; i
++ ) {
65 uint32_t strSize
= (uint32_t)strlen(txt_testCasePatterns
[i
]) + 1;
66 testCasePatterns
[i
]=(UChar
*)malloc(sizeof(UChar
) * strSize
);
67 u_uastrncpy(testCasePatterns
[i
], txt_testCasePatterns
[i
], strSize
);
69 for (i
=0; i
< cnt_testCases
; i
++ ) {
70 uint32_t strSize
= (uint32_t)strlen(txt_testResultStrings
[i
]) + 1;
71 testResultStrings
[i
] = (UChar
*)malloc(sizeof(UChar
) * strSize
);
72 u_uastrncpy(testResultStrings
[i
], txt_testResultStrings
[i
], strSize
);
75 strings_initialized
= TRUE
;
78 static void FreeStrings( void )
81 if (!strings_initialized
)
84 for (i
=0; i
< cnt_testCases
; i
++ ) {
85 free(testCasePatterns
[i
]);
87 for (i
=0; i
< cnt_testCases
; i
++ ) {
88 free(testResultStrings
[i
]);
90 strings_initialized
= FALSE
;
93 #if (U_PLATFORM == U_PF_LINUX) /* add platforms here .. */
94 /* Keep the #if above in sync with the one below that has the same "add platforms here .." comment. */
96 /* Platform dependent test to detect if this type will return NULL when interpreted as a pointer. */
97 static UBool
returnsNullForType(int firstParam
, ...) {
100 va_start(marker
, firstParam
);
101 isNULL
= (UBool
)(va_arg(marker
, void*) == NULL
);
107 /* Test u_formatMessage() with various test patterns() */
108 static void MessageFormatTest( void )
112 int32_t resultLengthOut
,resultlength
,i
, patternlength
;
113 UErrorCode status
= U_ZERO_ERROR
;
114 UDate d1
=1000000000.0;
116 ctest_setTimeZone(NULL
, &status
);
118 str
=(UChar
*)malloc(sizeof(UChar
) * 7);
119 u_uastrncpy(str
, "MyDisk", 7);
121 result
=(UChar
*)malloc(sizeof(UChar
) * 1);
122 log_verbose("Testing u_formatMessage()\n");
124 for (i
= 0; i
< cnt_testCases
; i
++) {
126 patternlength
=u_strlen(testCasePatterns
[i
]);
127 resultLengthOut
=u_formatMessage( "en_US",testCasePatterns
[i
], patternlength
, result
, resultlength
,
128 &status
, 1, 3456.00, d1
);
129 if(status
== U_BUFFER_OVERFLOW_ERROR
)
132 resultlength
=resultLengthOut
+1;
133 result
=(UChar
*)realloc(result
,sizeof(UChar
) * resultlength
);
134 u_formatMessage( "en_US",testCasePatterns
[i
], patternlength
, result
, resultlength
,
135 &status
, 1, 3456.00, d1
);
137 if(U_FAILURE(status
)){
138 log_data_err("ERROR: failure in message format on testcase %d: %s (Are you missing data?)\n", i
, myErrorName(status
) );
141 if(u_strcmp(result
, testResultStrings
[i
])==0){
142 log_verbose("PASS: MessagFormat successful on testcase : %d\n", i
);
145 log_err("FAIL: Error in MessageFormat on testcase : %d\n GOT %s EXPECTED %s\n", i
,
146 austrdup(result
), austrdup(testResultStrings
[i
]) );
154 for (i
= 0; i
< cnt_testCases
; i
++) {
155 UParseError parseError
;
157 patternlength
=u_strlen(testCasePatterns
[i
]);
159 resultLengthOut
=u_formatMessageWithError( "en_US",testCasePatterns
[i
], patternlength
, result
, resultlength
,
160 &parseError
,&status
, 1, 3456.00, d1
);
161 if(status
== U_BUFFER_OVERFLOW_ERROR
)
164 resultlength
=resultLengthOut
+1;
165 result
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
166 u_formatMessage( "en_US",testCasePatterns
[i
], patternlength
, result
, resultlength
,
167 &status
, 1, 3456.00, d1
);
169 if(U_FAILURE(status
)){
170 log_data_err("ERROR: failure in message format on testcase %d: %s (Are you missing data?)\n", i
, myErrorName(status
) );
173 if(u_strcmp(result
, testResultStrings
[i
])==0){
174 log_verbose("PASS: MessagFormat successful on testcase : %d\n", i
);
177 log_err("FAIL: Error in MessageFormat on testcase : %d\n GOT %s EXPECTED %s\n", i
,
178 austrdup(result
), austrdup(testResultStrings
[i
]) );
185 UErrorCode ec
= U_ZERO_ERROR
;
186 int32_t patternLength
= u_strlen(testCasePatterns
[0]);
188 UMessageFormat formatter
= umsg_open(testCasePatterns
[0],patternLength
,"en_US",NULL
,&ec
);
191 log_data_err("umsg_open() failed for testCasePattens[0]. -> %s (Are you missing data?)\n", u_errorName(ec
));
192 umsg_close(formatter
);
195 for(i
= 0;i
<cnt_testCases
; i
++){
196 UParseError parseError
;
197 int32_t resultLength
=0,count
=0;
203 // Alternate between specifying the length and using NUL-termination.
204 patternLength
= ((i
& 1) == 0) ? u_strlen(testCasePatterns
[i
]) : -1;
206 umsg_applyPattern(formatter
,testCasePatterns
[i
],patternLength
,&parseError
,&ec
);
208 log_err("umsg_applyPattern() failed for testCasePattens[%d].\n",i
);
209 umsg_close(formatter
);
213 resultLength
= umsg_format(formatter
,result
,resultLength
,&ec
,1,3456.00,d1
);
214 if(ec
==U_BUFFER_OVERFLOW_ERROR
){
216 result
= (UChar
*) malloc(U_SIZEOF_UCHAR
*resultLength
+2);
217 resultLength
= umsg_format(formatter
,result
,resultLength
+2,&ec
,1,3456.00,d1
);
219 log_err("ERROR: failure in message format on testcase %d: %s\n", i
, u_errorName(status
) );
221 umsg_close(formatter
);
225 if(u_strcmp(result
, testResultStrings
[i
])==0){
226 log_verbose("PASS: MessagFormat successful on testcase : %d\n", i
);
229 log_err("FAIL: Error in MessageFormat on testcase : %d\n GOT %s EXPECTED %s\n", i
,
230 austrdup(result
), austrdup(testResultStrings
[i
]) );
233 #if (U_PLATFORM == U_PF_LINUX) /* add platforms here .. */
234 log_verbose("Skipping potentially crashing test for mismatched varargs.\n");
236 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__
);
238 if (returnsNullForType(1, (double)2.0)) {
239 /* HP/UX and possibly other platforms don't properly check for this case.
240 We pass in a UDate, but the function expects a UDate *. When va_arg is used,
241 most compilers will return NULL, but HP-UX won't do that and will return 2
242 in this case. This is a platform dependent test. It crashes on some systems.
244 If you get a crash here, see the definition of returnsNullForType.
246 This relies upon "undefined" behavior, as indicated by C99 7.15.1.1 paragraph 2
248 umsg_parse(formatter
,result
,resultLength
,&count
,&ec
,one
,two
,d2
);
249 if(ec
!=U_ILLEGAL_ARGUMENT_ERROR
){
250 log_err("FAIL: Did not get expected error for umsg_parse(). Expected: U_ILLEGAL_ARGUMENT_ERROR Got: %s \n",u_errorName(ec
));
256 log_verbose("Warning: Returning NULL for a mismatched va_arg type isn't supported on this platform.\n", i
);
260 umsg_parse(formatter
,result
,resultLength
,&count
,&ec
,&one
,&two
,&d2
);
262 log_err("umsg_parse could not parse the pattern. Error: %s.\n",u_errorName(ec
));
266 log_err("FAIL: Expected U_BUFFER_OVERFLOW error while preflighting got: %s for testCasePatterns[%d]",u_errorName(ec
),i
);
269 umsg_close(formatter
);
273 ctest_resetTimeZone();
277 /*test u_formatMessage() with sample patterns */
278 static void TestSampleMessageFormat(void)
282 UChar pattern
[100], expected
[100];
283 int32_t resultLengthOut
, resultlength
;
284 UDate d
= 837039928046.0;
285 UErrorCode status
= U_ZERO_ERROR
;
287 ctest_setTimeZone(NULL
, &status
);
289 str
=(UChar
*)malloc(sizeof(UChar
) * 15);
290 u_uastrcpy(str
, "abc");
292 u_uastrcpy(pattern
, "There are {0} files on {1,date}");
293 u_uastrcpy(expected
, "There are abc files on Jul 10, 1996");
294 result
=(UChar
*)malloc(sizeof(UChar
) * 1);
295 log_verbose("\nTesting a sample for Message format test#1\n");
297 resultLengthOut
=u_formatMessage( "en_US", pattern
, u_strlen(pattern
), result
, resultlength
, &status
, str
, d
);
298 if(status
==U_BUFFER_OVERFLOW_ERROR
)
301 resultlength
=resultLengthOut
+1;
302 result
=(UChar
*)realloc(result
, sizeof(UChar
) * resultlength
);
303 u_formatMessage( "en_US", pattern
, u_strlen(pattern
), result
, resultlength
, &status
, str
, d
);
305 if(U_FAILURE(status
)){
306 log_data_err("Error: failure in message format on test#1: %s (Are you missing data?)\n", myErrorName(status
));
308 else if(u_strcmp(result
, expected
)==0)
309 log_verbose("PASS: MessagFormat successful on test#1\n");
311 log_err("FAIL: Error in MessageFormat on test#1 \n GOT: %s EXPECTED: %s\n",
312 austrdup(result
), austrdup(expected
) );
316 log_verbose("\nTesting message format with another pattern test#2\n");
317 u_uastrcpy(pattern
, "The disk \"{0}\" contains {1,number,integer} file(s)");
318 u_uastrcpy(expected
, "The disk \"MyDisk\" contains 23 file(s)");
319 u_uastrcpy(str
, "MyDisk");
321 resultLengthOut
=u_formatMessage( "en_US",
329 if(status
==U_BUFFER_OVERFLOW_ERROR
)
332 resultlength
=resultLengthOut
+1;
333 result
=(UChar
*)realloc(result
, sizeof(UChar
) * (resultlength
+1));
334 u_formatMessage( "en_US", pattern
, u_strlen(pattern
), result
, resultlength
, &status
, str
, 23);
336 if(U_FAILURE(status
)){
337 log_data_err("Error: failure in message format on test#2 : %s (Are you missing data?)\n", myErrorName(status
));
339 else if(u_strcmp(result
, expected
)==0)
340 log_verbose("PASS: MessagFormat successful on test#2\n");
342 log_err("FAIL: Error in MessageFormat on test#2\n GOT: %s EXPECTED: %s\n",
343 austrdup(result
), austrdup(expected
) );
348 log_verbose("\nTesting message format with another pattern test#3\n");
349 u_uastrcpy(pattern
, "You made a {0} of {1,number,currency}");
350 u_uastrcpy(expected
, "You made a deposit of $500.00");
351 u_uastrcpy(str
, "deposit");
353 resultLengthOut
=u_formatMessage( "en_US", pattern
, u_strlen(pattern
), NULL
, resultlength
, &status
, str
, 500.00);
354 if(status
==U_BUFFER_OVERFLOW_ERROR
)
357 resultlength
=resultLengthOut
+1;
358 result
=(UChar
*)realloc(result
, sizeof(UChar
) * resultlength
);
359 u_formatMessage( "en_US", pattern
, u_strlen(pattern
), result
, resultlength
, &status
, str
, 500.00);
361 if(U_FAILURE(status
)){
362 log_data_err("Error: failure in message format on test#3 : %s (Are you missing data?)\n", myErrorName(status
));
364 else if(u_strcmp(result
, expected
)==0)
365 log_verbose("PASS: MessagFormat successful on test#3\n");
367 log_err("FAIL: Error in MessageFormat on test#3\n GOT: %s EXPECTED %s\n", austrdup(result
),
368 austrdup(expected
) );
374 ctest_resetTimeZone();
377 /* Test umsg_format() and umsg_parse() , format and parse sequence and round trip */
378 static void TestNewFormatAndParseAPI(void)
381 UChar
*result
= NULL
, tzID
[4], str
[25];
384 int32_t resultLengthOut
, resultlength
;
387 UDateFormat
*def1
= NULL
;
388 UErrorCode status
= U_ZERO_ERROR
;
391 UParseError parseError
;
392 UMessageFormat
* fmt
= NULL
;
395 ctest_setTimeZone(NULL
, &status
);
397 log_verbose("Testing format and parse with parse error\n");
399 u_uastrcpy(str
, "disturbance in force");
400 u_uastrcpy(tzID
, "PST");
401 cal
=ucal_open(tzID
, u_strlen(tzID
), "en_US", UCAL_TRADITIONAL
, &status
);
402 if(U_FAILURE(status
)){
403 log_data_err("error in ucal_open caldef : %s - (Are you missing data?)\n", myErrorName(status
) );
406 ucal_setDateTime(cal
, 1999, UCAL_MARCH
, 18, 0, 0, 0, &status
);
407 d1
=ucal_getMillis(cal
, &status
);
408 if(U_FAILURE(status
)){
409 log_err("Error: failure in get millis: %s\n", myErrorName(status
) );
413 log_verbose("\nTesting with pattern test#4");
414 u_uastrcpy(pattern
, "On {0, date, long}, there was a {1} on planet {2,number,integer}");
415 u_uastrcpy(expected
, "On March 18, 1999, there was a disturbance in force on planet 7");
417 fmt
= umsg_open(pattern
,u_strlen(pattern
),"en_US",&parseError
,&status
);
418 if(U_FAILURE(status
)){
419 log_data_err("error in umsg_open : %s (Are you missing data?)\n", u_errorName(status
) );
422 result
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
424 resultLengthOut
=umsg_format(fmt
,result
, resultlength
,&status
, d1
, str
, 7);
425 if(status
==U_BUFFER_OVERFLOW_ERROR
)
428 resultlength
=resultLengthOut
+1;
429 result
=(UChar
*)realloc(result
, sizeof(UChar
) * resultlength
);
430 u_formatMessageWithError( "en_US", pattern
, u_strlen(pattern
), result
, resultlength
,&parseError
, &status
, d1
, str
, 7);
433 if(U_FAILURE(status
)){
434 log_err("ERROR: failure in message format test#4: %s\n", myErrorName(status
));
436 if(u_strcmp(result
, expected
)==0)
437 log_verbose("PASS: MessagFormat successful on test#4\n");
439 log_err("FAIL: Error in MessageFormat on test#4\n GOT: %s EXPECTED: %s\n", austrdup(result
),
440 austrdup(expected
) );
444 /*try to parse this and check*/
445 log_verbose("\nTesting the parse Message test#5\n");
447 umsg_parse(fmt
, result
, u_strlen(result
),&count
,&status
, &d
, ret
, &value
);
448 if(U_FAILURE(status
)){
449 log_err("ERROR: error in parsing: test#5: %s\n", myErrorName(status
));
451 if(value
!=7 && u_strcmp(str
,ret
)!=0)
452 log_err("FAIL: Error in parseMessage on test#5 \n");
454 log_verbose("PASS: parseMessage successful on test#5\n");
456 def1
= udat_open(UDAT_DEFAULT
,UDAT_DEFAULT
,NULL
, NULL
, 0, NULL
,0,&status
);
457 if(U_FAILURE(status
))
459 log_err("error in creating the dateformat using short date and time style:\n %s\n", myErrorName(status
));
462 if(u_strcmp(myDateFormat(def1
, d
), myDateFormat(def1
, d1
))==0)
463 log_verbose("PASS: parseMessage successful test#5\n");
465 log_err("FAIL: parseMessage didn't parse the date successfully\n GOT: %s EXPECTED %s\n",
466 austrdup(myDateFormat(def1
,d
)), austrdup(myDateFormat(def1
,d1
)) );
476 ctest_resetTimeZone();
479 /* Test u_formatMessageWithError() and u_parseMessageWithError() , format and parse sequence and round trip */
480 static void TestSampleFormatAndParseWithError(void)
483 UChar
*result
, *tzID
, *str
;
487 int32_t resultLengthOut
, resultlength
;
490 UDateFormat
*def1
= NULL
;
491 UErrorCode status
= U_ZERO_ERROR
;
494 UParseError parseError
;
496 ctest_setTimeZone(NULL
, &status
);
498 log_verbose("Testing format and parse with parse error\n");
500 str
=(UChar
*)malloc(sizeof(UChar
) * 25);
501 u_uastrcpy(str
, "disturbance in force");
502 tzID
=(UChar
*)malloc(sizeof(UChar
) * 4);
503 u_uastrcpy(tzID
, "PST");
504 cal
=ucal_open(tzID
, u_strlen(tzID
), "en_US", UCAL_TRADITIONAL
, &status
);
505 if(U_FAILURE(status
)){
506 log_data_err("error in ucal_open caldef : %s - (Are you missing data?)\n", myErrorName(status
) );
508 ucal_setDateTime(cal
, 1999, UCAL_MARCH
, 18, 0, 0, 0, &status
);
509 d1
=ucal_getMillis(cal
, &status
);
510 if(U_FAILURE(status
)){
511 log_data_err("Error: failure in get millis: %s - (Are you missing data?)\n", myErrorName(status
) );
514 log_verbose("\nTesting with pattern test#4");
515 u_uastrcpy(pattern
, "On {0, date, long}, there was a {1} on planet {2,number,integer}");
516 u_uastrcpy(expected
, "On March 18, 1999, there was a disturbance in force on planet 7");
518 result
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
519 resultLengthOut
=u_formatMessageWithError( "en_US", pattern
, u_strlen(pattern
), result
, resultlength
,&parseError
, &status
, d1
, str
, 7);
520 if(status
==U_BUFFER_OVERFLOW_ERROR
)
523 resultlength
=resultLengthOut
+1;
524 result
=(UChar
*)realloc(result
, sizeof(UChar
) * resultlength
);
525 u_formatMessageWithError( "en_US", pattern
, u_strlen(pattern
), result
, resultlength
,&parseError
, &status
, d1
, str
, 7);
528 if(U_FAILURE(status
)){
529 log_data_err("ERROR: failure in message format test#4: %s (Are you missing data?)\n", myErrorName(status
));
532 else if(u_strcmp(result
, expected
)==0)
533 log_verbose("PASS: MessagFormat successful on test#4\n");
535 log_err("FAIL: Error in MessageFormat on test#4\n GOT: %s EXPECTED: %s\n", austrdup(result
),
536 austrdup(expected
) );
540 /*try to parse this and check*/
541 log_verbose("\nTesting the parse Message test#5\n");
543 if (U_SUCCESS(status
)) {
544 u_parseMessageWithError("en_US", pattern
, u_strlen(pattern
), result
, u_strlen(result
),
545 &parseError
,&status
, &d
, ret
, &value
);
546 if(U_FAILURE(status
)){
547 log_data_err("ERROR: error in parsing: test#5: %s (Are you missing data?)\n", myErrorName(status
));
549 else if(value
!=7 && u_strcmp(str
,ret
)!=0)
550 log_err("FAIL: Error in parseMessage on test#5 \n");
552 log_verbose("PASS: parseMessage successful on test#5\n");
555 def1
= udat_open(UDAT_DEFAULT
,UDAT_DEFAULT
,NULL
, NULL
, 0, NULL
,0,&status
);
556 if(U_FAILURE(status
))
558 log_data_err("error in creating the dateformat using short date and time style: %s (Are you missing data?)\n", myErrorName(status
));
561 if(u_strcmp(myDateFormat(def1
, d
), myDateFormat(def1
, d1
))==0)
562 log_verbose("PASS: parseMessage successful test#5\n");
564 log_err("FAIL: parseMessage didn't parse the date successfully\n GOT: %s EXPECTED %s\n",
565 austrdup(myDateFormat(def1
,d
)), austrdup(myDateFormat(def1
,d1
)) );
576 ctest_resetTimeZone();
579 /* Test u_formatMessage() and u_parseMessage() , format and parse sequence and round trip */
580 static void TestSampleFormatAndParse(void)
583 UChar
*result
, *tzID
, *str
;
586 int32_t resultLengthOut
, resultlength
;
590 UErrorCode status
= U_ZERO_ERROR
;
594 ctest_setTimeZone(NULL
, &status
);
596 log_verbose("Testing format and parse\n");
598 str
=(UChar
*)malloc(sizeof(UChar
) * 25);
599 u_uastrcpy(str
, "disturbance in force");
600 tzID
=(UChar
*)malloc(sizeof(UChar
) * 4);
601 u_uastrcpy(tzID
, "PST");
602 cal
=ucal_open(tzID
, u_strlen(tzID
), "en_US", UCAL_TRADITIONAL
, &status
);
603 if(U_FAILURE(status
)){
604 log_data_err("error in ucal_open caldef : %s - (Are you missing data?)\n", myErrorName(status
) );
607 ucal_setDateTime(cal
, 1999, UCAL_MARCH
, 18, 0, 0, 0, &status
);
608 d1
=ucal_getMillis(cal
, &status
);
609 if(U_FAILURE(status
)){
610 log_data_err("Error: failure in get millis: %s - (Are you missing data?)\n", myErrorName(status
) );
613 log_verbose("\nTesting with pattern test#4");
614 u_uastrcpy(pattern
, "On {0, date, long}, there was a {1} on planet {2,number,integer}");
615 u_uastrcpy(expected
, "On March 18, 1999, there was a disturbance in force on planet 7");
617 result
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
618 resultLengthOut
=u_formatMessage( "en_US", pattern
, u_strlen(pattern
), result
, resultlength
, &status
, d1
, str
, 7);
619 if(status
==U_BUFFER_OVERFLOW_ERROR
)
622 resultlength
=resultLengthOut
+1;
623 result
=(UChar
*)realloc(result
, sizeof(UChar
) * resultlength
);
624 u_formatMessage( "en_US", pattern
, u_strlen(pattern
), result
, resultlength
, &status
, d1
, str
, 7);
627 if(U_FAILURE(status
)){
628 log_data_err("ERROR: failure in message format test#4: %s (Are you missing data?)\n", myErrorName(status
));
631 else if(u_strcmp(result
, expected
)==0)
632 log_verbose("PASS: MessagFormat successful on test#4\n");
634 log_err("FAIL: Error in MessageFormat on test#4\n GOT: %s EXPECTED: %s\n", austrdup(result
),
635 austrdup(expected
) );
639 /*try to parse this and check*/
640 log_verbose("\nTesting the parse Message test#5\n");
642 if (U_SUCCESS(status
)) {
643 u_parseMessage("en_US", pattern
, u_strlen(pattern
), result
, u_strlen(result
), &status
, &d
, ret
, &value
);
644 if(U_FAILURE(status
)){
645 log_data_err("ERROR: error in parsing: test#5: %s (Are you missing data?)\n", myErrorName(status
));
647 else if(value
!=7 && u_strcmp(str
,ret
)!=0)
648 log_err("FAIL: Error in parseMessage on test#5 \n");
650 log_verbose("PASS: parseMessage successful on test#5\n");
653 def1
= udat_open(UDAT_DEFAULT
,UDAT_DEFAULT
,NULL
, NULL
, 0, NULL
,0,&status
);
654 if(U_FAILURE(status
))
656 log_data_err("error in creating the dateformat using short date and time style: %s (Are you missing data?)\n", myErrorName(status
));
659 if(u_strcmp(myDateFormat(def1
, d
), myDateFormat(def1
, d1
))==0)
660 log_verbose("PASS: parseMessage successful test#5\n");
662 log_err("FAIL: parseMessage didn't parse the date successfully\n GOT: %s EXPECTED %s\n",
663 austrdup(myDateFormat(def1
,d
)), austrdup(myDateFormat(def1
,d1
)) );
673 ctest_resetTimeZone();
676 /* Test message format with a Select option */
677 static void TestMsgFormatSelect(void)
681 UErrorCode status
= U_ZERO_ERROR
;
685 int32_t resultlength
,resultLengthOut
;
687 str
=(UChar
*)malloc(sizeof(UChar
) * 25);
688 u_uastrcpy(str
, "Kirti");
689 str1
=(UChar
*)malloc(sizeof(UChar
) * 25);
690 u_uastrcpy(str1
, "female");
691 log_verbose("Testing message format with Select test #1\n:");
692 u_uastrcpy(pattern
, "{0} est {1, select, female {all\\u00E9e} other {all\\u00E9}} \\u00E0 Paris.");
693 u_uastrcpy(expected
, "Kirti est all\\u00E9e \\u00E0 Paris.");
695 resultLengthOut
=u_formatMessage( "fr", pattern
, u_strlen(pattern
), NULL
, resultlength
, &status
, str
, str1
);
696 if(status
==U_BUFFER_OVERFLOW_ERROR
)
699 resultlength
=resultLengthOut
+1;
700 result
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
701 u_formatMessage( "fr", pattern
, u_strlen(pattern
), result
, resultlength
, &status
, str
, str1
);
702 if(u_strcmp(result
, expected
)==0)
703 log_verbose("PASS: MessagFormat successful on Select test#1\n");
705 log_err("FAIL: Error in MessageFormat on Select test#1\n GOT %s EXPECTED %s\n", austrdup(result
),
706 austrdup(expected
) );
710 if(U_FAILURE(status
)){
711 log_data_err("ERROR: failure in message format on Select test#1 : %s \n", myErrorName(status
));
716 /*Test a nested pattern*/
717 str
=(UChar
*)malloc(sizeof(UChar
) * 25);
718 u_uastrcpy(str
, "Noname");
719 str1
=(UChar
*)malloc(sizeof(UChar
) * 25);
720 u_uastrcpy(str1
, "other");
721 log_verbose("Testing message format with Select test #2\n:");
722 u_uastrcpy(pattern
, "{0} est {1, select, female {{2,number,integer} all\\u00E9e} other {all\\u00E9}} \\u00E0 Paris.");
723 u_uastrcpy(expected
, "Noname est all\\u00E9 \\u00E0 Paris.");
725 resultLengthOut
=u_formatMessage( "fr", pattern
, u_strlen(pattern
), NULL
, resultlength
, &status
, str
, str1
,6);
726 if(status
==U_BUFFER_OVERFLOW_ERROR
)
729 resultlength
=resultLengthOut
+1;
730 result
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
731 u_formatMessage( "fr", pattern
, u_strlen(pattern
), result
, resultlength
, &status
, str
, str1
, 6);
732 if(u_strcmp(result
, expected
)==0)
733 log_verbose("PASS: MessagFormat successful on Select test#2\n");
735 log_err("FAIL: Error in MessageFormat on Select test#2\n GOT %s EXPECTED %s\n", austrdup(result
),
736 austrdup(expected
) );
740 if(U_FAILURE(status
)){
741 log_data_err("ERROR: failure in message format on Select test#2 : %s \n", myErrorName(status
));
747 /* test message format with a choice option */
748 static void TestMsgFormatChoice(void)
751 UErrorCode status
= U_ZERO_ERROR
;
755 int32_t resultlength
,resultLengthOut
;
757 str
=(UChar
*)malloc(sizeof(UChar
) * 25);
758 u_uastrcpy(str
, "MyDisk");
759 log_verbose("Testing message format with choice test #6\n:");
761 * Before ICU 4.8, umsg_xxx() did not detect conflicting argument types,
762 * and this pattern had {0,number,integer} as the inner argument.
763 * The choice argument has kDouble type while {0,number,integer} has kLong (int32_t).
764 * ICU 4.8 and above detects this as an error.
765 * We changed this pattern to work as intended.
767 u_uastrcpy(pattern
, "The disk {1} contains {0,choice,0#no files|1#one file|1<{0,number} files}");
768 u_uastrcpy(expected
, "The disk MyDisk contains 100 files");
770 resultLengthOut
=u_formatMessage( "en_US", pattern
, u_strlen(pattern
), NULL
, resultlength
, &status
, 100., str
);
771 if(status
==U_BUFFER_OVERFLOW_ERROR
)
774 resultlength
=resultLengthOut
+1;
775 result
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
776 u_formatMessage( "en_US", pattern
, u_strlen(pattern
), result
, resultlength
, &status
, 100., str
);
777 if(u_strcmp(result
, expected
)==0)
778 log_verbose("PASS: MessagFormat successful on test#6\n");
780 log_err("FAIL: Error in MessageFormat on test#6\n GOT %s EXPECTED %s\n", austrdup(result
),
781 austrdup(expected
) );
785 if(U_FAILURE(status
)){
786 log_data_err("ERROR: failure in message format on test#6 : %s (Are you missing data?)\n", myErrorName(status
));
789 log_verbose("Testing message format with choice test #7\n:");
790 u_uastrcpy(expected
, "The disk MyDisk contains no files");
792 resultLengthOut
=u_formatMessage( "en_US", pattern
, u_strlen(pattern
), NULL
, resultlength
, &status
, 0., str
);
793 if(status
==U_BUFFER_OVERFLOW_ERROR
)
796 resultlength
=resultLengthOut
+1;
797 result
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
798 u_formatMessage( "en_US", pattern
, u_strlen(pattern
), result
, resultlength
, &status
, 0., str
);
800 if(u_strcmp(result
, expected
)==0)
801 log_verbose("PASS: MessagFormat successful on test#7\n");
803 log_err("FAIL: Error in MessageFormat on test#7\n GOT: %s EXPECTED %s\n", austrdup(result
),
804 austrdup(expected
) );
808 if(U_FAILURE(status
)){
809 log_data_err("ERROR: failure in message format on test#7 : %s (Are you missing data?)\n", myErrorName(status
));
812 log_verbose("Testing message format with choice test #8\n:");
813 u_uastrcpy(expected
, "The disk MyDisk contains one file");
815 resultLengthOut
=u_formatMessage( "en_US", pattern
, u_strlen(pattern
), NULL
, resultlength
, &status
, 1., str
);
816 if(status
==U_BUFFER_OVERFLOW_ERROR
)
819 resultlength
=resultLengthOut
+1;
820 result
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
821 u_formatMessage( "en_US", pattern
, u_strlen(pattern
), result
, resultlength
, &status
, 1., str
);
823 if(u_strcmp(result
, expected
)==0)
824 log_verbose("PASS: MessagFormat successful on test#8\n");
826 log_err("FAIL: Error in MessageFormat on test#8\n GOT %s EXPECTED: %s\n", austrdup(result
),
827 austrdup(expected
) );
832 if(U_FAILURE(status
)){
833 log_data_err("ERROR: failure in message format on test#8 : %s (Are you missing data?)\n", myErrorName(status
));
840 /*test u_parseMessage() with various test patterns */
841 static void TestParseMessage(void)
845 UErrorCode status
= U_ZERO_ERROR
;
850 log_verbose("\nTesting a sample for parse Message test#9\n");
852 u_uastrcpy(source
, "You deposited an amount of $500.00");
853 u_uastrcpy(pattern
, "You {0} an amount of {1,number,currency}");
854 u_uastrcpy(res
,"deposited");
856 u_parseMessage( "en_US", pattern
, u_strlen(pattern
), source
, u_strlen(source
), &status
, str
, &value
);
857 if(U_FAILURE(status
)){
858 log_data_err("ERROR: failure in parse Message on test#9: %s (Are you missing data?)\n", myErrorName(status
));
860 else if(value
==500.00 && u_strcmp(str
,res
)==0)
861 log_verbose("PASS: parseMessage successful on test#9\n");
863 log_err("FAIL: Error in parseMessage on test#9 \n");
867 log_verbose("\nTesting a sample for parse Message test#10\n");
869 u_uastrcpy(source
, "There are 123 files on MyDisk created");
870 u_uastrcpy(pattern
, "There are {0,number,integer} files on {1} created");
871 u_uastrcpy(res
,"MyDisk");
873 u_parseMessage( "en_US", pattern
, u_strlen(pattern
), source
, u_strlen(source
), &status
, &value
, str
);
874 if(U_FAILURE(status
)){
875 log_data_err("ERROR: failure in parse Message on test#10: %s (Are you missing data?)\n", myErrorName(status
));
877 else if(value
==123.00 && u_strcmp(str
,res
)==0)
878 log_verbose("PASS: parseMessage successful on test#10\n");
880 log_err("FAIL: Error in parseMessage on test#10 \n");
883 static int32_t CallFormatMessage(const char* locale
, UChar
* testCasePattern
, int32_t patternLength
,
884 UChar
* result
, int32_t resultLength
, UErrorCode
*status
, ...)
888 va_start(ap
, status
);
889 len
= u_vformatMessage(locale
, testCasePattern
, patternLength
, result
, resultLength
, ap
, status
);
894 /* Test u_vformatMessage() with various test patterns. */
895 static void TestMessageFormatWithValist( void )
900 int32_t resultLengthOut
,resultlength
,i
, patternlength
;
901 UErrorCode status
= U_ZERO_ERROR
;
902 UDate d1
=1000000000.0;
904 ctest_setTimeZone(NULL
, &status
);
906 str
=(UChar
*)malloc(sizeof(UChar
) * 7);
907 u_uastrcpy(str
, "MyDisk");
909 result
=(UChar
*)malloc(sizeof(UChar
) * 1);
910 log_verbose("Testing u_formatMessage90\n");
912 for (i
= 0; i
< cnt_testCases
; i
++) {
914 patternlength
=u_strlen(testCasePatterns
[i
]);
915 resultLengthOut
=CallFormatMessage( "en_US",testCasePatterns
[i
], patternlength
, result
, resultlength
,
916 &status
, 1, 3456.00, d1
);
917 if(status
== U_BUFFER_OVERFLOW_ERROR
)
920 resultlength
=resultLengthOut
+1;
921 result
=(UChar
*)realloc(result
,sizeof(UChar
) * resultlength
);
922 CallFormatMessage( "en_US",testCasePatterns
[i
], patternlength
, result
, resultlength
,
923 &status
, 1, 3456.00, d1
);
925 if(U_FAILURE(status
)){
926 log_data_err("ERROR: failure in message format on testcase %d: %s (Are you missing data?)\n", i
, myErrorName(status
) );
928 else if(u_strcmp(result
, testResultStrings
[i
])==0){
929 log_verbose("PASS: MessagFormat successful on testcase : %d\n", i
);
932 log_err("FAIL: Error in MessageFormat on testcase : %d\n GOT %s EXPECTED %s\n", i
,
933 austrdup(result
), austrdup(testResultStrings
[i
]) );
940 ctest_resetTimeZone();
943 static void CallParseMessage(const char* locale
, UChar
* pattern
, int32_t patternLength
,
944 UChar
* source
, int32_t sourceLength
, UErrorCode
*status
, ...)
947 va_start(ap
, status
);
948 u_vparseMessage(locale
, pattern
, patternLength
, source
, sourceLength
, ap
, status
);
952 /*test u_vparseMessage() with various test patterns */
953 static void TestParseMessageWithValist(void)
957 UErrorCode status
= U_ZERO_ERROR
;
962 log_verbose("\nTesting a sample for parse Message test#9\n");
964 u_uastrcpy(source
, "You deposited an amount of $500.00");
965 u_uastrcpy(pattern
, "You {0} an amount of {1,number,currency}");
966 u_uastrcpy(res
,"deposited");
968 CallParseMessage( "en_US", pattern
, u_strlen(pattern
), source
, u_strlen(source
), &status
, str
, &value
);
969 if(U_FAILURE(status
)){
970 log_data_err("ERROR: failure in parse Message on test#9: %s (Are you missing data?)\n", myErrorName(status
));
972 else if(value
==500.00 && u_strcmp(str
,res
)==0)
973 log_verbose("PASS: parseMessage successful on test#9\n");
975 log_err("FAIL: Error in parseMessage on test#9\n");
978 log_verbose("\nTesting a sample for parse Message test#10\n");
980 u_uastrcpy(source
, "There are 123 files on MyDisk created");
981 u_uastrcpy(pattern
, "There are {0,number,integer} files on {1} created");
982 u_uastrcpy(res
,"MyDisk");
984 CallParseMessage( "en_US", pattern
, u_strlen(pattern
), source
, u_strlen(source
), &status
, &value
, str
);
985 if(U_FAILURE(status
)){
986 log_data_err("ERROR: failure in parse Message on test#10: %s (Are you missing data?)\n", myErrorName(status
));
988 else if(value
==123.00 && u_strcmp(str
,res
)==0)
989 log_verbose("PASS: parseMessage successful on test#10\n");
991 log_err("FAIL: Error in parseMessage on test#10 \n");
995 * Regression test for ICU4C Jitterbug 904
997 static void TestJ904(void) {
1003 UErrorCode status
= U_ZERO_ERROR
;
1004 const char* PAT
= "Number {1,number,#0.000}, String {0}, Date {2,date,12:mm:ss.SSS}";
1005 const char* EXP
= "Number 0,143, String foo, Date 12:34:56.789";
1007 ctest_setTimeZone(NULL
, &status
);
1009 u_uastrcpy(string
, "foo");
1010 /* Slight hack here -- instead of date pattern HH:mm:ss.SSS, use
1011 * 12:mm:ss.SSS. Why? So this test generates the same output --
1012 * "12:34:56.789" -- regardless of time zone (as long as we aren't
1013 * in one of the 30 minute offset zones!). */
1014 u_uastrcpy(pattern
, PAT
);
1015 length
= u_formatMessage("nl", pattern
, u_strlen(pattern
),
1016 result
, 256, &status
,
1018 789.0+1000*(56+60*(34+60*12)));
1019 (void)length
; /* Suppress set but not used warning. */
1021 u_austrncpy(cresult
, result
, sizeof(cresult
));
1023 /* This test passes if it DOESN'T CRASH. However, we test the
1024 * output anyway. If the string doesn't match in the date part,
1025 * check to see that the machine doesn't have an unusual time zone
1026 * offset, that is, one with a non-zero minutes/seconds offset
1027 * from GMT -- see above. */
1028 if (strcmp(cresult
, EXP
) == 0) {
1029 log_verbose("Ok: \"%s\"\n", cresult
);
1031 log_data_err("FAIL: got \"%s\", expected \"%s\" -> %s (Are you missing data?)\n", cresult
, EXP
, u_errorName(status
));
1034 ctest_resetTimeZone();
1037 static void OpenMessageFormatTest(void)
1039 UMessageFormat
*f1
, *f2
, *f3
;
1043 UParseError parseError
;
1044 const char* locale
= "hi_IN";
1046 const char* PAT
= "Number {1,number,#0.000}, String {0}, Date {2,date,12:mm:ss.SSS}";
1048 UErrorCode status
= U_ZERO_ERROR
;
1050 u_uastrncpy(pattern
, PAT
, UPRV_LENGTHOF(pattern
));
1052 /* Test umsg_open */
1053 f1
= umsg_open(pattern
,length
,NULL
,NULL
,&status
);
1055 if(U_FAILURE(status
))
1057 log_err("umsg_open failed with pattern %s. Error: \n", PAT
, u_errorName(status
));
1061 /* Test umsg_open with parse error */
1062 status
= U_ZERO_ERROR
;
1063 f2
= umsg_open(pattern
,length
,NULL
,&parseError
,&status
);
1065 if(U_FAILURE(status
))
1067 log_err("umsg_open with parseError failed with pattern %s. Error: %s\n", PAT
, u_errorName(status
));
1071 /* Test umsg_clone */
1072 status
= U_ZERO_ERROR
;
1073 f3
= umsg_clone(f1
,&status
);
1074 if(U_FAILURE(status
))
1076 log_err("umsg_clone failed. Error %s \n", u_errorName(status
));
1079 /* Test umsg_setLocale */
1080 umsg_setLocale(f1
,locale
);
1081 /* Test umsg_getLocale */
1082 retLoc
= (char*)umsg_getLocale(f1
);
1083 if(strcmp(retLoc
,locale
)!=0)
1085 log_err("umsg_setLocale and umsg_getLocale methods failed. Expected:%s Got: %s \n", locale
, retLoc
);
1088 /* Test umsg_applyPattern */
1089 status
= U_ZERO_ERROR
;
1090 umsg_applyPattern(f1
,pattern
,(int32_t)strlen(PAT
),NULL
,&status
);
1091 if(U_FAILURE(status
))
1093 log_data_err("umsg_applyPattern failed. Error %s (Are you missing data?)\n",u_errorName(status
));
1096 /* Test umsg_toPattern */
1097 umsg_toPattern(f1
,result
,256,&status
);
1098 if(U_FAILURE(status
) ){
1099 log_data_err("umsg_toPattern method failed. Error: %s (Are you missing data?)\n",u_errorName(status
));
1101 if(u_strcmp(result
,pattern
)!=0){
1102 u_UCharsToChars(result
,cresult
,256);
1103 log_err("umsg_toPattern method failed. Expected: %s Got: %s \n",PAT
,cresult
);
1106 /* umsg_format umsg_parse */
1113 static void MessageLength(void)
1115 UErrorCode status
= U_ZERO_ERROR
;
1116 const char patChars
[] = {"123{0}456{0}"};
1117 const char expectedChars
[] = {"123abc"};
1118 UChar pattern
[sizeof(patChars
)];
1119 UChar arg
[] = {0x61,0x62,0x63,0};
1120 UChar result
[128] = {0};
1121 UChar expected
[sizeof(expectedChars
)];
1123 u_uastrncpy(pattern
, patChars
, UPRV_LENGTHOF(pattern
));
1124 u_uastrncpy(expected
, expectedChars
, UPRV_LENGTHOF(expected
));
1126 u_formatMessage("en_US", pattern
, 6, result
, UPRV_LENGTHOF(result
), &status
, arg
);
1127 if (U_FAILURE(status
)) {
1128 log_err("u_formatMessage method failed. Error: %s \n",u_errorName(status
));
1130 if (u_strcmp(result
, expected
) != 0) {
1131 log_err("u_formatMessage didn't return expected result\n");
1135 static void TestMessageWithUnusedArgNumber(void) {
1136 UErrorCode errorCode
= U_ZERO_ERROR
;
1137 U_STRING_DECL(pattern
, "abc {1} def", 11);
1138 UChar x
[2] = { 0x78, 0 }; // "x"
1139 UChar y
[2] = { 0x79, 0 }; // "y"
1140 U_STRING_DECL(expected
, "abc y def", 9);
1144 U_STRING_INIT(pattern
, "abc {1} def", 11);
1145 U_STRING_INIT(expected
, "abc y def", 9);
1146 length
= u_formatMessage("en", pattern
, -1, result
, UPRV_LENGTHOF(result
), &errorCode
, x
, y
);
1147 if (U_FAILURE(errorCode
) || length
!= u_strlen(expected
) || u_strcmp(result
, expected
) != 0) {
1148 log_err("u_formatMessage(pattern with only {1}, 2 args) failed: result length %d, UErrorCode %s \n",
1149 (int)length
, u_errorName(errorCode
));
1153 static void TestErrorChaining(void) {
1154 UErrorCode status
= U_USELESS_COLLATOR_ERROR
;
1156 umsg_open(NULL
, 0, NULL
, NULL
, &status
);
1157 umsg_applyPattern(NULL
, NULL
, 0, NULL
, &status
);
1158 umsg_toPattern(NULL
, NULL
, 0, &status
);
1159 umsg_clone(NULL
, &status
);
1160 umsg_format(NULL
, NULL
, 0, &status
);
1161 umsg_parse(NULL
, NULL
, 0, NULL
, &status
);
1164 /* All of this code should have done nothing. */
1165 if (status
!= U_USELESS_COLLATOR_ERROR
) {
1166 log_err("Status got changed to %s\n", u_errorName(status
));
1169 status
= U_ZERO_ERROR
;
1170 umsg_open(NULL
, 0, NULL
, NULL
, &status
);
1171 if (status
!= U_ILLEGAL_ARGUMENT_ERROR
) {
1172 log_err("Status should be U_ILLEGAL_ARGUMENT_ERROR instead of %s\n", u_errorName(status
));
1174 status
= U_ZERO_ERROR
;
1175 umsg_applyPattern(NULL
, NULL
, 0, NULL
, &status
);
1176 if (status
!= U_ILLEGAL_ARGUMENT_ERROR
) {
1177 log_err("Status should be U_ILLEGAL_ARGUMENT_ERROR instead of %s\n", u_errorName(status
));
1179 status
= U_ZERO_ERROR
;
1180 umsg_toPattern(NULL
, NULL
, 0, &status
);
1181 if (status
!= U_ILLEGAL_ARGUMENT_ERROR
) {
1182 log_err("Status should be U_ILLEGAL_ARGUMENT_ERROR instead of %s\n", u_errorName(status
));
1184 status
= U_ZERO_ERROR
;
1185 umsg_clone(NULL
, &status
);
1186 if (status
!= U_ILLEGAL_ARGUMENT_ERROR
) {
1187 log_err("Status should be U_ILLEGAL_ARGUMENT_ERROR instead of %s\n", u_errorName(status
));
1191 void addMsgForTest(TestNode
** root
);
1193 void addMsgForTest(TestNode
** root
)
1195 addTest(root
, &OpenMessageFormatTest
, "tsformat/cmsgtst/OpenMessageFormatTest");
1196 addTest(root
, &MessageFormatTest
, "tsformat/cmsgtst/MessageFormatTest");
1197 addTest(root
, &TestSampleMessageFormat
, "tsformat/cmsgtst/TestSampleMessageFormat");
1198 addTest(root
, &TestSampleFormatAndParse
, "tsformat/cmsgtst/TestSampleFormatAndParse");
1199 addTest(root
, &TestSampleFormatAndParseWithError
, "tsformat/cmsgtst/TestSampleFormatAndParseWithError");
1200 addTest(root
, &TestNewFormatAndParseAPI
, "tsformat/cmsgtst/TestNewFormatAndParseAPI");
1201 addTest(root
, &TestMsgFormatChoice
, "tsformat/cmsgtst/TestMsgFormatChoice");
1202 addTest(root
, &TestParseMessage
, "tsformat/cmsgtst/TestParseMessage");
1203 addTest(root
, &TestMessageFormatWithValist
, "tsformat/cmsgtst/TestMessageFormatWithValist");
1204 addTest(root
, &TestParseMessageWithValist
, "tsformat/cmsgtst/TestParseMessageWithValist");
1205 addTest(root
, &TestJ904
, "tsformat/cmsgtst/TestJ904");
1206 addTest(root
, &MessageLength
, "tsformat/cmsgtst/MessageLength");
1207 addTest(root
, &TestMessageWithUnusedArgNumber
, "tsformat/cmsgtst/TestMessageWithUnusedArgNumber");
1208 addTest(root
, &TestErrorChaining
, "tsformat/cmsgtst/TestErrorChaining");
1209 addTest(root
, &TestMsgFormatSelect
, "tsformat/cmsgtst/TestMsgFormatSelect");
1212 #endif /* #if !UCONFIG_NO_FORMATTING */