1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /********************************************************************
4 * COPYRIGHT:
5 * Copyright (c) 1997-2016, International Business Machines Corporation and
6 * others. All Rights Reserved.
7 ********************************************************************
8 *
9 * File CMSGTST.C
10 *
11 * Modification History:
12 * Name Description
13 * Madhu Katragadda Creation
14 ********************************************************************/
15 /* C API TEST FOR MESSAGE FORMAT */
16
17 #include "unicode/utypes.h"
18
19 #if !UCONFIG_NO_FORMATTING
20
21 #include <stdlib.h>
22 #include <string.h>
23 #include <stdarg.h>
24 #include "unicode/uloc.h"
25 #include "unicode/umsg.h"
26 #include "unicode/udat.h"
27 #include "unicode/umsg.h"
28 #include "unicode/ustring.h"
29 #include "cintltst.h"
30 #include "cmsgtst.h"
31 #include "cformtst.h"
32 #include "cmemory.h"
33
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}",
40 };
41
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%"
48 };
49
50 const int32_t cnt_testCases = 5;
51 static UChar* testCasePatterns[5];
52
53 static UChar* testResultStrings[5];
54
55 static UBool strings_initialized = FALSE;
56
57 /* function used to create the test patterns for testing Message formatting */
InitStrings(void)58 static void InitStrings( void )
59 {
60 int32_t i;
61 if (strings_initialized)
62 return;
63
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);
68 }
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);
73 }
74
75 strings_initialized = TRUE;
76 }
77
FreeStrings(void)78 static void FreeStrings( void )
79 {
80 int32_t i;
81 if (!strings_initialized)
82 return;
83
84 for (i=0; i < cnt_testCases; i++ ) {
85 free(testCasePatterns[i]);
86 }
87 for (i=0; i < cnt_testCases; i++ ) {
88 free(testResultStrings[i]);
89 }
90 strings_initialized = FALSE;
91 }
92
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. */
95 #else
96 /* Platform dependent test to detect if this type will return NULL when interpreted as a pointer. */
returnsNullForType(int firstParam,...)97 static UBool returnsNullForType(int firstParam, ...) {
98 UBool isNULL;
99 va_list marker;
100 va_start(marker, firstParam);
101 isNULL = (UBool)(va_arg(marker, void*) == NULL);
102 va_end(marker);
103 return isNULL;
104 }
105 #endif
106
107 /* Test u_formatMessage() with various test patterns() */
MessageFormatTest(void)108 static void MessageFormatTest( void )
109 {
110 UChar *str;
111 UChar* result;
112 int32_t resultLengthOut,resultlength,i, patternlength;
113 UErrorCode status = U_ZERO_ERROR;
114 UDate d1=1000000000.0;
115
116 ctest_setTimeZone(NULL, &status);
117
118 str=(UChar*)malloc(sizeof(UChar) * 7);
119 u_uastrncpy(str, "MyDisk", 7);
120 resultlength=1;
121 result=(UChar*)malloc(sizeof(UChar) * 1);
122 log_verbose("Testing u_formatMessage()\n");
123 InitStrings();
124 for (i = 0; i < cnt_testCases; i++) {
125 status=U_ZERO_ERROR;
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)
130 {
131 status=U_ZERO_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);
136 }
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) );
139 continue;
140 }
141 if(u_strcmp(result, testResultStrings[i])==0){
142 log_verbose("PASS: MessagFormat successful on testcase : %d\n", i);
143 }
144 else{
145 log_err("FAIL: Error in MessageFormat on testcase : %d\n GOT %s EXPECTED %s\n", i,
146 austrdup(result), austrdup(testResultStrings[i]) );
147 }
148 }
149 free(result);
150 result = NULL;
151 free(str);
152 {
153
154 for (i = 0; i < cnt_testCases; i++) {
155 UParseError parseError;
156 status=U_ZERO_ERROR;
157 patternlength=u_strlen(testCasePatterns[i]);
158 resultlength=0;
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)
162 {
163 status=U_ZERO_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);
168 }
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) );
171 continue;
172 }
173 if(u_strcmp(result, testResultStrings[i])==0){
174 log_verbose("PASS: MessagFormat successful on testcase : %d\n", i);
175 }
176 else{
177 log_err("FAIL: Error in MessageFormat on testcase : %d\n GOT %s EXPECTED %s\n", i,
178 austrdup(result), austrdup(testResultStrings[i]) );
179 }
180 free(result);
181 result=NULL;
182 }
183 }
184 {
185 UErrorCode ec = U_ZERO_ERROR;
186 int32_t patternLength = u_strlen(testCasePatterns[0]);
187
188 UMessageFormat formatter = umsg_open(testCasePatterns[0],patternLength,"en_US",NULL,&ec);
189
190 if(U_FAILURE(ec)){
191 log_data_err("umsg_open() failed for testCasePattens[0]. -> %s (Are you missing data?)\n", u_errorName(ec));
192 umsg_close(formatter);
193 return;
194 }
195 for(i = 0;i<cnt_testCases; i++){
196 UParseError parseError;
197 int32_t resultLength =0,count=0;
198 int32_t one=0;
199 int32_t two=0;
200 UDate d2=0;
201
202 result=NULL;
203 // Alternate between specifying the length and using NUL-termination.
204 patternLength = ((i & 1) == 0) ? u_strlen(testCasePatterns[i]) : -1;
205
206 umsg_applyPattern(formatter,testCasePatterns[i],patternLength,&parseError,&ec);
207 if(U_FAILURE(ec)){
208 log_err("umsg_applyPattern() failed for testCasePattens[%d].\n",i);
209 umsg_close(formatter);
210 return;
211 }
212 /* pre-flight */
213 resultLength = umsg_format(formatter,result,resultLength,&ec,1,3456.00,d1);
214 if(ec==U_BUFFER_OVERFLOW_ERROR){
215 ec=U_ZERO_ERROR;
216 result = (UChar*) malloc(U_SIZEOF_UCHAR*resultLength+2);
217 resultLength = umsg_format(formatter,result,resultLength+2,&ec,1,3456.00,d1);
218 if(U_FAILURE(ec)){
219 log_err("ERROR: failure in message format on testcase %d: %s\n", i, u_errorName(status) );
220 free(result);
221 umsg_close(formatter);
222 return;
223 }
224
225 if(u_strcmp(result, testResultStrings[i])==0){
226 log_verbose("PASS: MessagFormat successful on testcase : %d\n", i);
227 }
228 else{
229 log_err("FAIL: Error in MessageFormat on testcase : %d\n GOT %s EXPECTED %s\n", i,
230 austrdup(result), austrdup(testResultStrings[i]) );
231 }
232
233 #if (U_PLATFORM == U_PF_LINUX) /* add platforms here .. */
234 log_verbose("Skipping potentially crashing test for mismatched varargs.\n");
235 #else
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__);
237
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.
243
244 If you get a crash here, see the definition of returnsNullForType.
245
246 This relies upon "undefined" behavior, as indicated by C99 7.15.1.1 paragraph 2
247 */
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));
251 }else{
252 ec = U_ZERO_ERROR;
253 }
254 }
255 else {
256 log_verbose("Warning: Returning NULL for a mismatched va_arg type isn't supported on this platform.\n", i);
257 }
258 #endif
259
260 umsg_parse(formatter,result,resultLength,&count,&ec,&one,&two,&d2);
261 if(U_FAILURE(ec)){
262 log_err("umsg_parse could not parse the pattern. Error: %s.\n",u_errorName(ec));
263 }
264 free(result);
265 }else{
266 log_err("FAIL: Expected U_BUFFER_OVERFLOW error while preflighting got: %s for testCasePatterns[%d]",u_errorName(ec),i);
267 }
268 }
269 umsg_close(formatter);
270 }
271 FreeStrings();
272
273 ctest_resetTimeZone();
274 }
275
276
277 /*test u_formatMessage() with sample patterns */
TestSampleMessageFormat(void)278 static void TestSampleMessageFormat(void)
279 {
280 UChar *str;
281 UChar *result;
282 UChar pattern[100], expected[100];
283 int32_t resultLengthOut, resultlength;
284 UDate d = 837039928046.0;
285 UErrorCode status = U_ZERO_ERROR;
286
287 ctest_setTimeZone(NULL, &status);
288
289 str=(UChar*)malloc(sizeof(UChar) * 15);
290 u_uastrcpy(str, "abc");
291
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");
296 resultlength=1;
297 resultLengthOut=u_formatMessage( "en_US", pattern, u_strlen(pattern), result, resultlength, &status, str, d);
298 if(status==U_BUFFER_OVERFLOW_ERROR)
299 {
300 status=U_ZERO_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);
304 }
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));
307 }
308 else if(u_strcmp(result, expected)==0)
309 log_verbose("PASS: MessagFormat successful on test#1\n");
310 else{
311 log_err("FAIL: Error in MessageFormat on test#1 \n GOT: %s EXPECTED: %s\n",
312 austrdup(result), austrdup(expected) );
313 }
314
315
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");
320
321 resultLengthOut=u_formatMessage( "en_US",
322 pattern,
323 u_strlen(pattern),
324 result,
325 resultlength,
326 &status,
327 str,
328 235);
329 if(status==U_BUFFER_OVERFLOW_ERROR)
330 {
331 status=U_ZERO_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);
335 }
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));
338 }
339 else if(u_strcmp(result, expected)==0)
340 log_verbose("PASS: MessagFormat successful on test#2\n");
341 else{
342 log_err("FAIL: Error in MessageFormat on test#2\n GOT: %s EXPECTED: %s\n",
343 austrdup(result), austrdup(expected) );
344 }
345
346
347
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");
352 resultlength=0;
353 resultLengthOut=u_formatMessage( "en_US", pattern, u_strlen(pattern), NULL, resultlength, &status, str, 500.00);
354 if(status==U_BUFFER_OVERFLOW_ERROR)
355 {
356 status=U_ZERO_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);
360 }
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));
363 }
364 else if(u_strcmp(result, expected)==0)
365 log_verbose("PASS: MessagFormat successful on test#3\n");
366 else{
367 log_err("FAIL: Error in MessageFormat on test#3\n GOT: %s EXPECTED %s\n", austrdup(result),
368 austrdup(expected) );
369 }
370
371 free(result);
372 free(str);
373
374 ctest_resetTimeZone();
375 }
376
377 /* Test umsg_format() and umsg_parse() , format and parse sequence and round trip */
TestNewFormatAndParseAPI(void)378 static void TestNewFormatAndParseAPI(void)
379 {
380
381 UChar *result = NULL, tzID[4], str[25];
382 UChar pattern[100];
383 UChar expected[100];
384 int32_t resultLengthOut, resultlength;
385 UCalendar *cal;
386 UDate d1,d;
387 UDateFormat *def1 = NULL;
388 UErrorCode status = U_ZERO_ERROR;
389 int32_t value = 0;
390 UChar ret[30];
391 UParseError parseError;
392 UMessageFormat* fmt = NULL;
393 int32_t count=0;
394
395 ctest_setTimeZone(NULL, &status);
396
397 log_verbose("Testing format and parse with parse error\n");
398
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) );
404 goto cleanup;
405 }
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) );
410 goto cleanup;
411 }
412
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");
416 resultlength=1;
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) );
420 goto cleanup;
421 }
422 result=(UChar*)malloc(sizeof(UChar) * resultlength);
423
424 resultLengthOut=umsg_format(fmt ,result, resultlength,&status, d1, str, 7);
425 if(status==U_BUFFER_OVERFLOW_ERROR)
426 {
427 status=U_ZERO_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);
431
432 }
433 if(U_FAILURE(status)){
434 log_err("ERROR: failure in message format test#4: %s\n", myErrorName(status));
435 }
436 if(u_strcmp(result, expected)==0)
437 log_verbose("PASS: MessagFormat successful on test#4\n");
438 else{
439 log_err("FAIL: Error in MessageFormat on test#4\n GOT: %s EXPECTED: %s\n", austrdup(result),
440 austrdup(expected) );
441 }
442
443
444 /*try to parse this and check*/
445 log_verbose("\nTesting the parse Message test#5\n");
446
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));
450 }
451 if(value!=7 && u_strcmp(str,ret)!=0)
452 log_err("FAIL: Error in parseMessage on test#5 \n");
453 else
454 log_verbose("PASS: parseMessage successful on test#5\n");
455
456 def1 = udat_open(UDAT_DEFAULT,UDAT_DEFAULT ,NULL, NULL, 0, NULL,0,&status);
457 if(U_FAILURE(status))
458 {
459 log_err("error in creating the dateformat using short date and time style:\n %s\n", myErrorName(status));
460 }else{
461
462 if(u_strcmp(myDateFormat(def1, d), myDateFormat(def1, d1))==0)
463 log_verbose("PASS: parseMessage successful test#5\n");
464 else{
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)) );
467 }
468 }
469 cleanup:
470 umsg_close(fmt);
471 udat_close(def1);
472 ucal_close(cal);
473
474 free(result);
475
476 ctest_resetTimeZone();
477 }
478
479 /* Test u_formatMessageWithError() and u_parseMessageWithError() , format and parse sequence and round trip */
TestSampleFormatAndParseWithError(void)480 static void TestSampleFormatAndParseWithError(void)
481 {
482
483 UChar *result, *tzID, *str;
484 UChar pattern[100];
485
486 UChar expected[100];
487 int32_t resultLengthOut, resultlength;
488 UCalendar *cal;
489 UDate d1,d;
490 UDateFormat *def1 = NULL;
491 UErrorCode status = U_ZERO_ERROR;
492 int32_t value = 0;
493 UChar ret[30];
494 UParseError parseError;
495
496 ctest_setTimeZone(NULL, &status);
497
498 log_verbose("Testing format and parse with parse error\n");
499
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) );
507 }
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) );
512 }
513
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");
517 resultlength=1;
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)
521 {
522 status=U_ZERO_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);
526
527 }
528 if(U_FAILURE(status)){
529 log_data_err("ERROR: failure in message format test#4: %s (Are you missing data?)\n", myErrorName(status));
530 goto cleanup;
531 }
532 else if(u_strcmp(result, expected)==0)
533 log_verbose("PASS: MessagFormat successful on test#4\n");
534 else{
535 log_err("FAIL: Error in MessageFormat on test#4\n GOT: %s EXPECTED: %s\n", austrdup(result),
536 austrdup(expected) );
537 }
538
539
540 /*try to parse this and check*/
541 log_verbose("\nTesting the parse Message test#5\n");
542
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));
548 }
549 else if(value!=7 && u_strcmp(str,ret)!=0)
550 log_err("FAIL: Error in parseMessage on test#5 \n");
551 else
552 log_verbose("PASS: parseMessage successful on test#5\n");
553 }
554
555 def1 = udat_open(UDAT_DEFAULT,UDAT_DEFAULT ,NULL, NULL, 0, NULL,0,&status);
556 if(U_FAILURE(status))
557 {
558 log_data_err("error in creating the dateformat using short date and time style: %s (Are you missing data?)\n", myErrorName(status));
559 }else{
560
561 if(u_strcmp(myDateFormat(def1, d), myDateFormat(def1, d1))==0)
562 log_verbose("PASS: parseMessage successful test#5\n");
563 else{
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)) );
566 }
567 }
568 cleanup:
569 udat_close(def1);
570 ucal_close(cal);
571
572 free(result);
573 free(str);
574 free(tzID);
575
576 ctest_resetTimeZone();
577 }
578
579 /* Test u_formatMessage() and u_parseMessage() , format and parse sequence and round trip */
TestSampleFormatAndParse(void)580 static void TestSampleFormatAndParse(void)
581 {
582
583 UChar *result, *tzID, *str;
584 UChar pattern[100];
585 UChar expected[100];
586 int32_t resultLengthOut, resultlength;
587 UCalendar *cal;
588 UDate d1,d;
589 UDateFormat *def1;
590 UErrorCode status = U_ZERO_ERROR;
591 int32_t value = 0;
592 UChar ret[30];
593
594 ctest_setTimeZone(NULL, &status);
595
596 log_verbose("Testing format and parse\n");
597
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) );
605 return;
606 }
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) );
611 }
612
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");
616 resultlength=1;
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)
620 {
621 status=U_ZERO_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);
625
626 }
627 if(U_FAILURE(status)){
628 log_data_err("ERROR: failure in message format test#4: %s (Are you missing data?)\n", myErrorName(status));
629 return;
630 }
631 else if(u_strcmp(result, expected)==0)
632 log_verbose("PASS: MessagFormat successful on test#4\n");
633 else{
634 log_err("FAIL: Error in MessageFormat on test#4\n GOT: %s EXPECTED: %s\n", austrdup(result),
635 austrdup(expected) );
636 }
637
638
639 /*try to parse this and check*/
640 log_verbose("\nTesting the parse Message test#5\n");
641
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));
646 }
647 else if(value!=7 && u_strcmp(str,ret)!=0)
648 log_err("FAIL: Error in parseMessage on test#5 \n");
649 else
650 log_verbose("PASS: parseMessage successful on test#5\n");
651 }
652
653 def1 = udat_open(UDAT_DEFAULT,UDAT_DEFAULT ,NULL, NULL, 0, NULL,0,&status);
654 if(U_FAILURE(status))
655 {
656 log_data_err("error in creating the dateformat using short date and time style: %s (Are you missing data?)\n", myErrorName(status));
657 }else{
658
659 if(u_strcmp(myDateFormat(def1, d), myDateFormat(def1, d1))==0)
660 log_verbose("PASS: parseMessage successful test#5\n");
661 else{
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)) );
664 }
665 }
666 udat_close(def1);
667 ucal_close(cal);
668
669 free(result);
670 free(str);
671 free(tzID);
672
673 ctest_resetTimeZone();
674 }
675
676 /* Test message format with a Select option */
TestMsgFormatSelect(void)677 static void TestMsgFormatSelect(void)
678 {
679 UChar* str;
680 UChar* str1;
681 UErrorCode status = U_ZERO_ERROR;
682 UChar *result;
683 UChar pattern[100];
684 UChar expected[100];
685 int32_t resultlength,resultLengthOut;
686
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.");
694 resultlength=0;
695 resultLengthOut=u_formatMessage( "fr", pattern, u_strlen(pattern), NULL, resultlength, &status, str , str1);
696 if(status==U_BUFFER_OVERFLOW_ERROR)
697 {
698 status=U_ZERO_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");
704 else{
705 log_err("FAIL: Error in MessageFormat on Select test#1\n GOT %s EXPECTED %s\n", austrdup(result),
706 austrdup(expected) );
707 }
708 free(result);
709 }
710 if(U_FAILURE(status)){
711 log_data_err("ERROR: failure in message format on Select test#1 : %s \n", myErrorName(status));
712 }
713 free(str);
714 free(str1);
715
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.");
724 resultlength=0;
725 resultLengthOut=u_formatMessage( "fr", pattern, u_strlen(pattern), NULL, resultlength, &status, str , str1,6);
726 if(status==U_BUFFER_OVERFLOW_ERROR)
727 {
728 status=U_ZERO_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");
734 else{
735 log_err("FAIL: Error in MessageFormat on Select test#2\n GOT %s EXPECTED %s\n", austrdup(result),
736 austrdup(expected) );
737 }
738 free(result);
739 }
740 if(U_FAILURE(status)){
741 log_data_err("ERROR: failure in message format on Select test#2 : %s \n", myErrorName(status));
742 }
743 free(str);
744 free(str1);
745 }
746
747 /* test message format with a choice option */
TestMsgFormatChoice(void)748 static void TestMsgFormatChoice(void)
749 {
750 UChar* str;
751 UErrorCode status = U_ZERO_ERROR;
752 UChar *result;
753 UChar pattern[100];
754 UChar expected[100];
755 int32_t resultlength,resultLengthOut;
756
757 str=(UChar*)malloc(sizeof(UChar) * 25);
758 u_uastrcpy(str, "MyDisk");
759 log_verbose("Testing message format with choice test #6\n:");
760 /*
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.
766 */
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");
769 resultlength=0;
770 resultLengthOut=u_formatMessage( "en_US", pattern, u_strlen(pattern), NULL, resultlength, &status, 100., str);
771 if(status==U_BUFFER_OVERFLOW_ERROR)
772 {
773 status=U_ZERO_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");
779 else{
780 log_err("FAIL: Error in MessageFormat on test#6\n GOT %s EXPECTED %s\n", austrdup(result),
781 austrdup(expected) );
782 }
783 free(result);
784 }
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));
787 }
788
789 log_verbose("Testing message format with choice test #7\n:");
790 u_uastrcpy(expected, "The disk MyDisk contains no files");
791 resultlength=0;
792 resultLengthOut=u_formatMessage( "en_US", pattern, u_strlen(pattern), NULL, resultlength, &status, 0., str);
793 if(status==U_BUFFER_OVERFLOW_ERROR)
794 {
795 status=U_ZERO_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);
799
800 if(u_strcmp(result, expected)==0)
801 log_verbose("PASS: MessagFormat successful on test#7\n");
802 else{
803 log_err("FAIL: Error in MessageFormat on test#7\n GOT: %s EXPECTED %s\n", austrdup(result),
804 austrdup(expected) );
805 }
806 free(result);
807 }
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));
810 }
811
812 log_verbose("Testing message format with choice test #8\n:");
813 u_uastrcpy(expected, "The disk MyDisk contains one file");
814 resultlength=0;
815 resultLengthOut=u_formatMessage( "en_US", pattern, u_strlen(pattern), NULL, resultlength, &status, 1., str);
816 if(status==U_BUFFER_OVERFLOW_ERROR)
817 {
818 status=U_ZERO_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);
822
823 if(u_strcmp(result, expected)==0)
824 log_verbose("PASS: MessagFormat successful on test#8\n");
825 else{
826 log_err("FAIL: Error in MessageFormat on test#8\n GOT %s EXPECTED: %s\n", austrdup(result),
827 austrdup(expected) );
828 }
829
830 free(result);
831 }
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));
834 }
835
836 free(str);
837
838 }
839
840 /*test u_parseMessage() with various test patterns */
TestParseMessage(void)841 static void TestParseMessage(void)
842 {
843 UChar pattern[100];
844 UChar source[100];
845 UErrorCode status = U_ZERO_ERROR;
846 int32_t value;
847 UChar str[10];
848 UChar res[10];
849
850 log_verbose("\nTesting a sample for parse Message test#9\n");
851
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");
855
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));
859 }
860 else if(value==500.00 && u_strcmp(str,res)==0)
861 log_verbose("PASS: parseMessage successful on test#9\n");
862 else
863 log_err("FAIL: Error in parseMessage on test#9 \n");
864
865
866
867 log_verbose("\nTesting a sample for parse Message test#10\n");
868
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");
872
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));
876 }
877 else if(value==123.00 && u_strcmp(str,res)==0)
878 log_verbose("PASS: parseMessage successful on test#10\n");
879 else
880 log_err("FAIL: Error in parseMessage on test#10 \n");
881 }
882
CallFormatMessage(const char * locale,UChar * testCasePattern,int32_t patternLength,UChar * result,int32_t resultLength,UErrorCode * status,...)883 static int32_t CallFormatMessage(const char* locale, UChar* testCasePattern, int32_t patternLength,
884 UChar* result, int32_t resultLength, UErrorCode *status, ...)
885 {
886 int32_t len = 0;
887 va_list ap;
888 va_start(ap, status);
889 len = u_vformatMessage(locale, testCasePattern, patternLength, result, resultLength, ap, status);
890 va_end(ap);
891 return len;
892 }
893
894 /* Test u_vformatMessage() with various test patterns. */
TestMessageFormatWithValist(void)895 static void TestMessageFormatWithValist( void )
896 {
897
898 UChar *str;
899 UChar* result;
900 int32_t resultLengthOut,resultlength,i, patternlength;
901 UErrorCode status = U_ZERO_ERROR;
902 UDate d1=1000000000.0;
903
904 ctest_setTimeZone(NULL, &status);
905
906 str=(UChar*)malloc(sizeof(UChar) * 7);
907 u_uastrcpy(str, "MyDisk");
908 resultlength=1;
909 result=(UChar*)malloc(sizeof(UChar) * 1);
910 log_verbose("Testing u_formatMessage90\n");
911 InitStrings();
912 for (i = 0; i < cnt_testCases; i++) {
913 status=U_ZERO_ERROR;
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)
918 {
919 status=U_ZERO_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);
924 }
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) );
927 }
928 else if(u_strcmp(result, testResultStrings[i])==0){
929 log_verbose("PASS: MessagFormat successful on testcase : %d\n", i);
930 }
931 else{
932 log_err("FAIL: Error in MessageFormat on testcase : %d\n GOT %s EXPECTED %s\n", i,
933 austrdup(result), austrdup(testResultStrings[i]) );
934 }
935 }
936 free(result);
937 free(str);
938 FreeStrings();
939
940 ctest_resetTimeZone();
941 }
942
CallParseMessage(const char * locale,UChar * pattern,int32_t patternLength,UChar * source,int32_t sourceLength,UErrorCode * status,...)943 static void CallParseMessage(const char* locale, UChar* pattern, int32_t patternLength,
944 UChar* source, int32_t sourceLength, UErrorCode *status, ...)
945 {
946 va_list ap;
947 va_start(ap, status);
948 u_vparseMessage(locale, pattern, patternLength, source, sourceLength, ap, status);
949 va_end(ap);
950 }
951
952 /*test u_vparseMessage() with various test patterns */
TestParseMessageWithValist(void)953 static void TestParseMessageWithValist(void)
954 {
955 UChar pattern[100];
956 UChar source[100];
957 UErrorCode status = U_ZERO_ERROR;
958 int32_t value;
959 UChar str[10];
960 UChar res[10];
961
962 log_verbose("\nTesting a sample for parse Message test#9\n");
963
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");
967
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));
971 }
972 else if(value==500.00 && u_strcmp(str,res)==0)
973 log_verbose("PASS: parseMessage successful on test#9\n");
974 else
975 log_err("FAIL: Error in parseMessage on test#9\n");
976
977
978 log_verbose("\nTesting a sample for parse Message test#10\n");
979
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");
983
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));
987 }
988 else if(value==123.00 && u_strcmp(str,res)==0)
989 log_verbose("PASS: parseMessage successful on test#10\n");
990 else
991 log_err("FAIL: Error in parseMessage on test#10 \n");
992 }
993
994 /**
995 * Regression test for ICU4C Jitterbug 904
996 */
TestJ904(void)997 static void TestJ904(void) {
998 UChar pattern[256];
999 UChar result[256];
1000 UChar string[16];
1001 char cresult[256];
1002 int32_t length;
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";
1006
1007 ctest_setTimeZone(NULL, &status);
1008
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,
1017 string, 1/7.0,
1018 789.0+1000*(56+60*(34+60*12)));
1019 (void)length; /* Suppress set but not used warning. */
1020
1021 u_austrncpy(cresult, result, sizeof(cresult));
1022
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);
1030 } else {
1031 log_data_err("FAIL: got \"%s\", expected \"%s\" -> %s (Are you missing data?)\n", cresult, EXP, u_errorName(status));
1032 }
1033
1034 ctest_resetTimeZone();
1035 }
1036
OpenMessageFormatTest(void)1037 static void OpenMessageFormatTest(void)
1038 {
1039 UMessageFormat *f1, *f2, *f3;
1040 UChar pattern[256];
1041 UChar result[256];
1042 char cresult[256];
1043 UParseError parseError;
1044 const char* locale = "hi_IN";
1045 char* retLoc;
1046 const char* PAT = "Number {1,number,#0.000}, String {0}, Date {2,date,12:mm:ss.SSS}";
1047 int32_t length=0;
1048 UErrorCode status = U_ZERO_ERROR;
1049
1050 u_uastrncpy(pattern, PAT, UPRV_LENGTHOF(pattern));
1051
1052 /* Test umsg_open */
1053 f1 = umsg_open(pattern,length,NULL,NULL,&status);
1054
1055 if(U_FAILURE(status))
1056 {
1057 log_err("umsg_open failed with pattern %s. Error: \n", PAT, u_errorName(status));
1058 return;
1059 }
1060
1061 /* Test umsg_open with parse error */
1062 status = U_ZERO_ERROR;
1063 f2 = umsg_open(pattern,length,NULL,&parseError,&status);
1064
1065 if(U_FAILURE(status))
1066 {
1067 log_err("umsg_open with parseError failed with pattern %s. Error: %s\n", PAT, u_errorName(status));
1068 return;
1069 }
1070
1071 /* Test umsg_clone */
1072 status = U_ZERO_ERROR;
1073 f3 = umsg_clone(f1,&status);
1074 if(U_FAILURE(status))
1075 {
1076 log_err("umsg_clone failed. Error %s \n", u_errorName(status));
1077 }
1078
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)
1084 {
1085 log_err("umsg_setLocale and umsg_getLocale methods failed. Expected:%s Got: %s \n", locale, retLoc);
1086 }
1087
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))
1092 {
1093 log_data_err("umsg_applyPattern failed. Error %s (Are you missing data?)\n",u_errorName(status));
1094 }
1095
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));
1100 } else {
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);
1104 }
1105 }
1106 /* umsg_format umsg_parse */
1107
1108 umsg_close(f1);
1109 umsg_close(f2);
1110 umsg_close(f3);
1111 }
1112
MessageLength(void)1113 static void MessageLength(void)
1114 {
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)];
1122
1123 u_uastrncpy(pattern, patChars, UPRV_LENGTHOF(pattern));
1124 u_uastrncpy(expected, expectedChars, UPRV_LENGTHOF(expected));
1125
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));
1129 }
1130 if (u_strcmp(result, expected) != 0) {
1131 log_err("u_formatMessage didn't return expected result\n");
1132 }
1133 }
1134
TestMessageWithUnusedArgNumber(void)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);
1141 UChar result[20];
1142 int32_t length;
1143
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));
1150 }
1151 }
1152
TestErrorChaining(void)1153 static void TestErrorChaining(void) {
1154 UErrorCode status = U_USELESS_COLLATOR_ERROR;
1155
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);
1162 umsg_close(NULL);
1163
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));
1167 }
1168
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));
1173 }
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));
1178 }
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));
1183 }
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));
1188 }
1189 }
1190
1191 void addMsgForTest(TestNode** root);
1192
addMsgForTest(TestNode ** root)1193 void addMsgForTest(TestNode** root)
1194 {
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");
1210 }
1211
1212 #endif /* #if !UCONFIG_NO_FORMATTING */
1213