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 <stdarg.h>
22 #include <stdbool.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include "unicode/uloc.h"
26 #include "unicode/umsg.h"
27 #include "unicode/udat.h"
28 #include "unicode/umsg.h"
29 #include "unicode/ustring.h"
30 #include "cintltst.h"
31 #include "cmsgtst.h"
32 #include "cformtst.h"
33 #include "cmemory.h"
34
35 static const char* const txt_testCasePatterns[] = {
36 "Quotes '', '{', a {0,number,integer} '{'0}",
37 "Quotes '', '{', a {0,number,integer} '{'0}",
38 "You deposited {0,number,integer} times an amount of {1,number,currency} on {2,date,short}",
39 "'{'2,time,full}, for {1, number }, {0,number,integer} is {2,time,full} and full date is {2,date,full}",
40 "'{'1,number,percent} for {0,number,integer} is {1,number,percent}",
41 };
42
43 static const char* const txt_testResultStrings[] = {
44 "Quotes ', {, a 1 {0}",
45 "Quotes ', {, a 1 {0}",
46 "You deposited 1 times an amount of $3,456.00 on 1/12/70",
47 "{2,time,full}, for 3,456, 1 is 5:46:40\\u202FAM Pacific Standard Time and full date is Monday, January 12, 1970",
48 "{1,number,percent} for 1 is 345,600%"
49 };
50
51 const int32_t cnt_testCases = 5;
52 static UChar* testCasePatterns[5];
53
54 static UChar* testResultStrings[5];
55
56 static UBool strings_initialized = false;
57
58 /* function used to create the test patterns for testing Message formatting */
InitStrings(void)59 static void InitStrings( void )
60 {
61 int32_t i;
62 if (strings_initialized)
63 return;
64
65 for (i=0; i < cnt_testCases; i++ ) {
66 uint32_t strSize = (uint32_t)strlen(txt_testCasePatterns[i]) + 1;
67 testCasePatterns[i]=(UChar*)malloc(sizeof(UChar) * strSize);
68 u_uastrncpy(testCasePatterns[i], txt_testCasePatterns[i], strSize);
69 }
70 for (i=0; i < cnt_testCases; i++ ) {
71 uint32_t strSize = (uint32_t)strlen(txt_testResultStrings[i]) + 1;
72 testResultStrings[i] = (UChar*)malloc(sizeof(UChar) * strSize);
73 u_unescape(txt_testResultStrings[i], testResultStrings[i], strSize);
74 }
75
76 strings_initialized = true;
77 }
78
FreeStrings(void)79 static void FreeStrings( void )
80 {
81 int32_t i;
82 if (!strings_initialized)
83 return;
84
85 for (i=0; i < cnt_testCases; i++ ) {
86 free(testCasePatterns[i]);
87 }
88 for (i=0; i < cnt_testCases; i++ ) {
89 free(testResultStrings[i]);
90 }
91 strings_initialized = false;
92 }
93
94 #if (U_PLATFORM == U_PF_LINUX) /* add platforms here .. */
95 /* Keep the #if above in sync with the one below that has the same "add platforms here .." comment. */
96 #else
97 /* Platform dependent test to detect if this type will return NULL when interpreted as a pointer. */
returnsNullForType(int firstParam,...)98 static UBool returnsNullForType(int firstParam, ...) {
99 UBool isNULL;
100 va_list marker;
101 va_start(marker, firstParam);
102 isNULL = (UBool)(va_arg(marker, void*) == NULL);
103 va_end(marker);
104 return isNULL;
105 }
106 #endif
107
108 /* Test u_formatMessage() with various test patterns() */
MessageFormatTest(void)109 static void MessageFormatTest( void )
110 {
111 UChar *str;
112 UChar* result;
113 int32_t resultLengthOut,resultlength,i, patternlength;
114 UErrorCode status = U_ZERO_ERROR;
115 UDate d1=1000000000.0;
116
117 ctest_setTimeZone(NULL, &status);
118
119 str=(UChar*)malloc(sizeof(UChar) * 7);
120 u_uastrncpy(str, "MyDisk", 7);
121 resultlength=1;
122 result=(UChar*)malloc(sizeof(UChar) * 1);
123 log_verbose("Testing u_formatMessage()\n");
124 InitStrings();
125 for (i = 0; i < cnt_testCases; i++) {
126 status=U_ZERO_ERROR;
127 patternlength=u_strlen(testCasePatterns[i]);
128 resultLengthOut=u_formatMessage( "en_US",testCasePatterns[i], patternlength, result, resultlength,
129 &status, 1, 3456.00, d1);
130 if(status== U_BUFFER_OVERFLOW_ERROR)
131 {
132 status=U_ZERO_ERROR;
133 resultlength=resultLengthOut+1;
134 result=(UChar*)realloc(result,sizeof(UChar) * resultlength);
135 u_formatMessage( "en_US",testCasePatterns[i], patternlength, result, resultlength,
136 &status, 1, 3456.00, d1);
137 }
138 if(U_FAILURE(status)){
139 log_data_err("ERROR: failure in message format on testcase %d: %s (Are you missing data?)\n", i, myErrorName(status) );
140 continue;
141 }
142 if(u_strcmp(result, testResultStrings[i])==0){
143 log_verbose("PASS: MessagFormat successful on testcase : %d\n", i);
144 }
145 else{
146 log_err("FAIL: Error in MessageFormat on testcase : %d\n GOT %s EXPECTED %s\n", i,
147 austrdup(result), austrdup(testResultStrings[i]) );
148 }
149 }
150 free(result);
151 result = NULL;
152 free(str);
153 {
154
155 for (i = 0; i < cnt_testCases; i++) {
156 UParseError parseError;
157 status=U_ZERO_ERROR;
158 patternlength=u_strlen(testCasePatterns[i]);
159 resultlength=0;
160 resultLengthOut=u_formatMessageWithError( "en_US",testCasePatterns[i], patternlength, result, resultlength,
161 &parseError,&status, 1, 3456.00, d1);
162 if(status== U_BUFFER_OVERFLOW_ERROR)
163 {
164 status=U_ZERO_ERROR;
165 resultlength=resultLengthOut+1;
166 result=(UChar*)malloc(sizeof(UChar) * resultlength);
167 u_formatMessage( "en_US",testCasePatterns[i], patternlength, result, resultlength,
168 &status, 1, 3456.00, d1);
169 }
170 if(U_FAILURE(status)){
171 log_data_err("ERROR: failure in message format on testcase %d: %s (Are you missing data?)\n", i, myErrorName(status) );
172 continue;
173 }
174 if(u_strcmp(result, testResultStrings[i])==0){
175 log_verbose("PASS: MessagFormat successful on testcase : %d\n", i);
176 }
177 else{
178 log_err("FAIL: Error in MessageFormat on testcase : %d\n GOT %s EXPECTED %s\n", i,
179 austrdup(result), austrdup(testResultStrings[i]) );
180 }
181 free(result);
182 result=NULL;
183 }
184 }
185 {
186 UErrorCode ec = U_ZERO_ERROR;
187 int32_t patternLength = u_strlen(testCasePatterns[0]);
188
189 UMessageFormat formatter = umsg_open(testCasePatterns[0],patternLength,"en_US",NULL,&ec);
190
191 if(U_FAILURE(ec)){
192 log_data_err("umsg_open() failed for testCasePattens[0]. -> %s (Are you missing data?)\n", u_errorName(ec));
193 umsg_close(formatter);
194 return;
195 }
196 for(i = 0;i<cnt_testCases; i++){
197 UParseError parseError;
198 int32_t resultLength =0,count=0;
199 int32_t one=0;
200 int32_t two=0;
201 UDate d2=0;
202
203 result=NULL;
204 // Alternate between specifying the length and using NUL-termination.
205 patternLength = ((i & 1) == 0) ? u_strlen(testCasePatterns[i]) : -1;
206
207 umsg_applyPattern(formatter,testCasePatterns[i],patternLength,&parseError,&ec);
208 if(U_FAILURE(ec)){
209 log_err("umsg_applyPattern() failed for testCasePattens[%d].\n",i);
210 umsg_close(formatter);
211 return;
212 }
213 /* pre-flight */
214 resultLength = umsg_format(formatter,result,resultLength,&ec,1,3456.00,d1);
215 if(ec==U_BUFFER_OVERFLOW_ERROR){
216 ec=U_ZERO_ERROR;
217 result = (UChar*) malloc(U_SIZEOF_UCHAR*resultLength+2);
218 resultLength = umsg_format(formatter,result,resultLength+2,&ec,1,3456.00,d1);
219 if(U_FAILURE(ec)){
220 log_err("ERROR: failure in message format on testcase %d: %s\n", i, u_errorName(status) );
221 free(result);
222 umsg_close(formatter);
223 return;
224 }
225
226 if(u_strcmp(result, testResultStrings[i])==0){
227 log_verbose("PASS: MessagFormat successful on testcase : %d\n", i);
228 }
229 else{
230 log_err("FAIL: Error in MessageFormat on testcase : %d\n GOT %s EXPECTED %s\n", i,
231 austrdup(result), austrdup(testResultStrings[i]) );
232 }
233
234 #if (U_PLATFORM == U_PF_LINUX) /* add platforms here .. */
235 log_verbose("Skipping potentially crashing test for mismatched varargs.\n");
236 #else
237 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
239 if (returnsNullForType(1, (double)2.0)) {
240 /* HP/UX and possibly other platforms don't properly check for this case.
241 We pass in a UDate, but the function expects a UDate *. When va_arg is used,
242 most compilers will return NULL, but HP-UX won't do that and will return 2
243 in this case. This is a platform dependent test. It crashes on some systems.
244
245 If you get a crash here, see the definition of returnsNullForType.
246
247 This relies upon "undefined" behavior, as indicated by C99 7.15.1.1 paragraph 2
248 */
249 umsg_parse(formatter,result,resultLength,&count,&ec,one,two,d2);
250 if(ec!=U_ILLEGAL_ARGUMENT_ERROR){
251 log_err("FAIL: Did not get expected error for umsg_parse(). Expected: U_ILLEGAL_ARGUMENT_ERROR Got: %s \n",u_errorName(ec));
252 }else{
253 ec = U_ZERO_ERROR;
254 }
255 }
256 else {
257 log_verbose("Warning: Returning NULL for a mismatched va_arg type isn't supported on this platform.\n", i);
258 }
259 #endif
260
261 umsg_parse(formatter,result,resultLength,&count,&ec,&one,&two,&d2);
262 if(U_FAILURE(ec)){
263 log_err("umsg_parse could not parse the pattern. Error: %s.\n",u_errorName(ec));
264 }
265 free(result);
266 }else{
267 log_err("FAIL: Expected U_BUFFER_OVERFLOW error while preflighting got: %s for testCasePatterns[%d]",u_errorName(ec),i);
268 }
269 }
270 umsg_close(formatter);
271 }
272 FreeStrings();
273
274 ctest_resetTimeZone();
275 }
276
277
278 /*test u_formatMessage() with sample patterns */
TestSampleMessageFormat(void)279 static void TestSampleMessageFormat(void)
280 {
281 UChar *str;
282 UChar *result;
283 UChar pattern[100], expected[100];
284 int32_t resultLengthOut, resultlength;
285 UDate d = 837039928046.0;
286 UErrorCode status = U_ZERO_ERROR;
287
288 ctest_setTimeZone(NULL, &status);
289
290 str=(UChar*)malloc(sizeof(UChar) * 15);
291 u_uastrcpy(str, "abc");
292
293 u_uastrcpy(pattern, "There are {0} files on {1,date}");
294 u_uastrcpy(expected, "There are abc files on Jul 10, 1996");
295 result=(UChar*)malloc(sizeof(UChar) * 1);
296 log_verbose("\nTesting a sample for Message format test#1\n");
297 resultlength=1;
298 resultLengthOut=u_formatMessage( "en_US", pattern, u_strlen(pattern), result, resultlength, &status, str, d);
299 if(status==U_BUFFER_OVERFLOW_ERROR)
300 {
301 status=U_ZERO_ERROR;
302 resultlength=resultLengthOut+1;
303 result=(UChar*)realloc(result, sizeof(UChar) * resultlength);
304 u_formatMessage( "en_US", pattern, u_strlen(pattern), result, resultlength, &status, str, d);
305 }
306 if(U_FAILURE(status)){
307 log_data_err("Error: failure in message format on test#1: %s (Are you missing data?)\n", myErrorName(status));
308 }
309 else if(u_strcmp(result, expected)==0)
310 log_verbose("PASS: MessagFormat successful on test#1\n");
311 else{
312 log_err("FAIL: Error in MessageFormat on test#1 \n GOT: %s EXPECTED: %s\n",
313 austrdup(result), austrdup(expected) );
314 }
315
316
317 log_verbose("\nTesting message format with another pattern test#2\n");
318 u_uastrcpy(pattern, "The disk \"{0}\" contains {1,number,integer} file(s)");
319 u_uastrcpy(expected, "The disk \"MyDisk\" contains 23 file(s)");
320 u_uastrcpy(str, "MyDisk");
321
322 resultLengthOut=u_formatMessage( "en_US",
323 pattern,
324 u_strlen(pattern),
325 result,
326 resultlength,
327 &status,
328 str,
329 235);
330 if(status==U_BUFFER_OVERFLOW_ERROR)
331 {
332 status=U_ZERO_ERROR;
333 resultlength=resultLengthOut+1;
334 result=(UChar*)realloc(result, sizeof(UChar) * (resultlength+1));
335 u_formatMessage( "en_US", pattern, u_strlen(pattern), result, resultlength, &status, str, 23);
336 }
337 if(U_FAILURE(status)){
338 log_data_err("Error: failure in message format on test#2 : %s (Are you missing data?)\n", myErrorName(status));
339 }
340 else if(u_strcmp(result, expected)==0)
341 log_verbose("PASS: MessagFormat successful on test#2\n");
342 else{
343 log_err("FAIL: Error in MessageFormat on test#2\n GOT: %s EXPECTED: %s\n",
344 austrdup(result), austrdup(expected) );
345 }
346
347
348
349 log_verbose("\nTesting message format with another pattern test#3\n");
350 u_uastrcpy(pattern, "You made a {0} of {1,number,currency}");
351 u_uastrcpy(expected, "You made a deposit of $500.00");
352 u_uastrcpy(str, "deposit");
353 resultlength=0;
354 resultLengthOut=u_formatMessage( "en_US", pattern, u_strlen(pattern), NULL, resultlength, &status, str, 500.00);
355 if(status==U_BUFFER_OVERFLOW_ERROR)
356 {
357 status=U_ZERO_ERROR;
358 resultlength=resultLengthOut+1;
359 result=(UChar*)realloc(result, sizeof(UChar) * resultlength);
360 u_formatMessage( "en_US", pattern, u_strlen(pattern), result, resultlength, &status, str, 500.00);
361 }
362 if(U_FAILURE(status)){
363 log_data_err("Error: failure in message format on test#3 : %s (Are you missing data?)\n", myErrorName(status));
364 }
365 else if(u_strcmp(result, expected)==0)
366 log_verbose("PASS: MessagFormat successful on test#3\n");
367 else{
368 log_err("FAIL: Error in MessageFormat on test#3\n GOT: %s EXPECTED %s\n", austrdup(result),
369 austrdup(expected) );
370 }
371
372 free(result);
373 free(str);
374
375 ctest_resetTimeZone();
376 }
377
378 /* Test umsg_format() and umsg_parse() , format and parse sequence and round trip */
TestNewFormatAndParseAPI(void)379 static void TestNewFormatAndParseAPI(void)
380 {
381
382 UChar *result = NULL, tzID[4], str[25];
383 UChar pattern[100];
384 UChar expected[100];
385 int32_t resultLengthOut, resultlength;
386 UCalendar *cal;
387 UDate d1,d;
388 UDateFormat *def1 = NULL;
389 UErrorCode status = U_ZERO_ERROR;
390 int32_t value = 0;
391 UChar ret[30];
392 UParseError parseError;
393 UMessageFormat* fmt = NULL;
394 int32_t count=0;
395
396 ctest_setTimeZone(NULL, &status);
397
398 log_verbose("Testing format and parse with parse error\n");
399
400 u_uastrcpy(str, "disturbance in force");
401 u_uastrcpy(tzID, "PST");
402 cal=ucal_open(tzID, u_strlen(tzID), "en_US", UCAL_TRADITIONAL, &status);
403 if(U_FAILURE(status)){
404 log_data_err("error in ucal_open caldef : %s - (Are you missing data?)\n", myErrorName(status) );
405 goto cleanup;
406 }
407 ucal_setDateTime(cal, 1999, UCAL_MARCH, 18, 0, 0, 0, &status);
408 d1=ucal_getMillis(cal, &status);
409 if(U_FAILURE(status)){
410 log_err("Error: failure in get millis: %s\n", myErrorName(status) );
411 goto cleanup;
412 }
413
414 log_verbose("\nTesting with pattern test#4");
415 u_uastrcpy(pattern, "On {0, date, long}, there was a {1} on planet {2,number,integer}");
416 u_uastrcpy(expected, "On March 18, 1999, there was a disturbance in force on planet 7");
417 resultlength=1;
418 fmt = umsg_open(pattern,u_strlen(pattern),"en_US",&parseError,&status);
419 if(U_FAILURE(status)){
420 log_data_err("error in umsg_open : %s (Are you missing data?)\n", u_errorName(status) );
421 goto cleanup;
422 }
423 result=(UChar*)malloc(sizeof(UChar) * resultlength);
424
425 resultLengthOut=umsg_format(fmt ,result, resultlength,&status, d1, str, 7);
426 if(status==U_BUFFER_OVERFLOW_ERROR)
427 {
428 status=U_ZERO_ERROR;
429 resultlength=resultLengthOut+1;
430 result=(UChar*)realloc(result, sizeof(UChar) * resultlength);
431 u_formatMessageWithError( "en_US", pattern, u_strlen(pattern), result, resultlength,&parseError, &status, d1, str, 7);
432
433 }
434 if(U_FAILURE(status)){
435 log_err("ERROR: failure in message format test#4: %s\n", myErrorName(status));
436 }
437 if(u_strcmp(result, expected)==0)
438 log_verbose("PASS: MessagFormat successful on test#4\n");
439 else{
440 log_err("FAIL: Error in MessageFormat on test#4\n GOT: %s EXPECTED: %s\n", austrdup(result),
441 austrdup(expected) );
442 }
443
444
445 /*try to parse this and check*/
446 log_verbose("\nTesting the parse Message test#5\n");
447
448 umsg_parse(fmt, result, u_strlen(result),&count,&status, &d, ret, &value);
449 if(U_FAILURE(status)){
450 log_err("ERROR: error in parsing: test#5: %s\n", myErrorName(status));
451 }
452 if(value!=7 && u_strcmp(str,ret)!=0)
453 log_err("FAIL: Error in parseMessage on test#5 \n");
454 else
455 log_verbose("PASS: parseMessage successful on test#5\n");
456
457 def1 = udat_open(UDAT_DEFAULT,UDAT_DEFAULT ,NULL, NULL, 0, NULL,0,&status);
458 if(U_FAILURE(status))
459 {
460 log_err("error in creating the dateformat using short date and time style:\n %s\n", myErrorName(status));
461 }else{
462
463 if(u_strcmp(myDateFormat(def1, d), myDateFormat(def1, d1))==0)
464 log_verbose("PASS: parseMessage successful test#5\n");
465 else{
466 log_err("FAIL: parseMessage didn't parse the date successfully\n GOT: %s EXPECTED %s\n",
467 austrdup(myDateFormat(def1,d)), austrdup(myDateFormat(def1,d1)) );
468 }
469 }
470 cleanup:
471 umsg_close(fmt);
472 udat_close(def1);
473 ucal_close(cal);
474
475 free(result);
476
477 ctest_resetTimeZone();
478 }
479
480 /* Test u_formatMessageWithError() and u_parseMessageWithError() , format and parse sequence and round trip */
TestSampleFormatAndParseWithError(void)481 static void TestSampleFormatAndParseWithError(void)
482 {
483
484 UChar *result, *tzID, *str;
485 UChar pattern[100];
486
487 UChar expected[100];
488 int32_t resultLengthOut, resultlength;
489 UCalendar *cal;
490 UDate d1,d;
491 UDateFormat *def1 = NULL;
492 UErrorCode status = U_ZERO_ERROR;
493 int32_t value = 0;
494 UChar ret[30];
495 UParseError parseError;
496
497 ctest_setTimeZone(NULL, &status);
498
499 log_verbose("Testing format and parse with parse error\n");
500
501 str=(UChar*)malloc(sizeof(UChar) * 25);
502 u_uastrcpy(str, "disturbance in force");
503 tzID=(UChar*)malloc(sizeof(UChar) * 4);
504 u_uastrcpy(tzID, "PST");
505 cal=ucal_open(tzID, u_strlen(tzID), "en_US", UCAL_TRADITIONAL, &status);
506 if(U_FAILURE(status)){
507 log_data_err("error in ucal_open caldef : %s - (Are you missing data?)\n", myErrorName(status) );
508 }
509 ucal_setDateTime(cal, 1999, UCAL_MARCH, 18, 0, 0, 0, &status);
510 d1=ucal_getMillis(cal, &status);
511 if(U_FAILURE(status)){
512 log_data_err("Error: failure in get millis: %s - (Are you missing data?)\n", myErrorName(status) );
513 }
514
515 log_verbose("\nTesting with pattern test#4");
516 u_uastrcpy(pattern, "On {0, date, long}, there was a {1} on planet {2,number,integer}");
517 u_uastrcpy(expected, "On March 18, 1999, there was a disturbance in force on planet 7");
518 resultlength=1;
519 result=(UChar*)malloc(sizeof(UChar) * resultlength);
520 resultLengthOut=u_formatMessageWithError( "en_US", pattern, u_strlen(pattern), result, resultlength,&parseError, &status, d1, str, 7);
521 if(status==U_BUFFER_OVERFLOW_ERROR)
522 {
523 status=U_ZERO_ERROR;
524 resultlength=resultLengthOut+1;
525 result=(UChar*)realloc(result, sizeof(UChar) * resultlength);
526 u_formatMessageWithError( "en_US", pattern, u_strlen(pattern), result, resultlength,&parseError, &status, d1, str, 7);
527
528 }
529 if(U_FAILURE(status)){
530 log_data_err("ERROR: failure in message format test#4: %s (Are you missing data?)\n", myErrorName(status));
531 goto cleanup;
532 }
533 else if(u_strcmp(result, expected)==0)
534 log_verbose("PASS: MessagFormat successful on test#4\n");
535 else{
536 log_err("FAIL: Error in MessageFormat on test#4\n GOT: %s EXPECTED: %s\n", austrdup(result),
537 austrdup(expected) );
538 }
539
540
541 /*try to parse this and check*/
542 log_verbose("\nTesting the parse Message test#5\n");
543
544 if (U_SUCCESS(status)) {
545 u_parseMessageWithError("en_US", pattern, u_strlen(pattern), result, u_strlen(result),
546 &parseError,&status, &d, ret, &value);
547 if(U_FAILURE(status)){
548 log_data_err("ERROR: error in parsing: test#5: %s (Are you missing data?)\n", myErrorName(status));
549 }
550 else if(value!=7 && u_strcmp(str,ret)!=0)
551 log_err("FAIL: Error in parseMessage on test#5 \n");
552 else
553 log_verbose("PASS: parseMessage successful on test#5\n");
554 }
555
556 def1 = udat_open(UDAT_DEFAULT,UDAT_DEFAULT ,NULL, NULL, 0, NULL,0,&status);
557 if(U_FAILURE(status))
558 {
559 log_data_err("error in creating the dateformat using short date and time style: %s (Are you missing data?)\n", myErrorName(status));
560 }else{
561
562 if(u_strcmp(myDateFormat(def1, d), myDateFormat(def1, d1))==0)
563 log_verbose("PASS: parseMessage successful test#5\n");
564 else{
565 log_err("FAIL: parseMessage didn't parse the date successfully\n GOT: %s EXPECTED %s\n",
566 austrdup(myDateFormat(def1,d)), austrdup(myDateFormat(def1,d1)) );
567 }
568 }
569 cleanup:
570 udat_close(def1);
571 ucal_close(cal);
572
573 free(result);
574 free(str);
575 free(tzID);
576
577 ctest_resetTimeZone();
578 }
579
580 /* Test u_formatMessage() and u_parseMessage() , format and parse sequence and round trip */
TestSampleFormatAndParse(void)581 static void TestSampleFormatAndParse(void)
582 {
583
584 UChar *result, *tzID, *str;
585 UChar pattern[100];
586 UChar expected[100];
587 int32_t resultLengthOut, resultlength;
588 UCalendar *cal;
589 UDate d1,d;
590 UDateFormat *def1;
591 UErrorCode status = U_ZERO_ERROR;
592 int32_t value = 0;
593 UChar ret[30];
594
595 ctest_setTimeZone(NULL, &status);
596
597 log_verbose("Testing format and parse\n");
598
599 str=(UChar*)malloc(sizeof(UChar) * 25);
600 u_uastrcpy(str, "disturbance in force");
601 tzID=(UChar*)malloc(sizeof(UChar) * 4);
602 u_uastrcpy(tzID, "PST");
603 cal=ucal_open(tzID, u_strlen(tzID), "en_US", UCAL_TRADITIONAL, &status);
604 if(U_FAILURE(status)){
605 log_data_err("error in ucal_open caldef : %s - (Are you missing data?)\n", myErrorName(status) );
606 return;
607 }
608 ucal_setDateTime(cal, 1999, UCAL_MARCH, 18, 0, 0, 0, &status);
609 d1=ucal_getMillis(cal, &status);
610 if(U_FAILURE(status)){
611 log_data_err("Error: failure in get millis: %s - (Are you missing data?)\n", myErrorName(status) );
612 }
613
614 log_verbose("\nTesting with pattern test#4");
615 u_uastrcpy(pattern, "On {0, date, long}, there was a {1} on planet {2,number,integer}");
616 u_uastrcpy(expected, "On March 18, 1999, there was a disturbance in force on planet 7");
617 resultlength=1;
618 result=(UChar*)malloc(sizeof(UChar) * resultlength);
619 resultLengthOut=u_formatMessage( "en_US", pattern, u_strlen(pattern), result, resultlength, &status, d1, str, 7);
620 if(status==U_BUFFER_OVERFLOW_ERROR)
621 {
622 status=U_ZERO_ERROR;
623 resultlength=resultLengthOut+1;
624 result=(UChar*)realloc(result, sizeof(UChar) * resultlength);
625 u_formatMessage( "en_US", pattern, u_strlen(pattern), result, resultlength, &status, d1, str, 7);
626
627 }
628 if(U_FAILURE(status)){
629 log_data_err("ERROR: failure in message format test#4: %s (Are you missing data?)\n", myErrorName(status));
630 return;
631 }
632 else if(u_strcmp(result, expected)==0)
633 log_verbose("PASS: MessagFormat successful on test#4\n");
634 else{
635 log_err("FAIL: Error in MessageFormat on test#4\n GOT: %s EXPECTED: %s\n", austrdup(result),
636 austrdup(expected) );
637 }
638
639
640 /*try to parse this and check*/
641 log_verbose("\nTesting the parse Message test#5\n");
642
643 if (U_SUCCESS(status)) {
644 u_parseMessage("en_US", pattern, u_strlen(pattern), result, u_strlen(result), &status, &d, ret, &value);
645 if(U_FAILURE(status)){
646 log_data_err("ERROR: error in parsing: test#5: %s (Are you missing data?)\n", myErrorName(status));
647 }
648 else if(value!=7 && u_strcmp(str,ret)!=0)
649 log_err("FAIL: Error in parseMessage on test#5 \n");
650 else
651 log_verbose("PASS: parseMessage successful on test#5\n");
652 }
653
654 def1 = udat_open(UDAT_DEFAULT,UDAT_DEFAULT ,NULL, NULL, 0, NULL,0,&status);
655 if(U_FAILURE(status))
656 {
657 log_data_err("error in creating the dateformat using short date and time style: %s (Are you missing data?)\n", myErrorName(status));
658 }else{
659
660 if(u_strcmp(myDateFormat(def1, d), myDateFormat(def1, d1))==0)
661 log_verbose("PASS: parseMessage successful test#5\n");
662 else{
663 log_err("FAIL: parseMessage didn't parse the date successfully\n GOT: %s EXPECTED %s\n",
664 austrdup(myDateFormat(def1,d)), austrdup(myDateFormat(def1,d1)) );
665 }
666 }
667 udat_close(def1);
668 ucal_close(cal);
669
670 free(result);
671 free(str);
672 free(tzID);
673
674 ctest_resetTimeZone();
675 }
676
677 /* Test message format with a Select option */
TestMsgFormatSelect(void)678 static void TestMsgFormatSelect(void)
679 {
680 UChar* str;
681 UChar* str1;
682 UErrorCode status = U_ZERO_ERROR;
683 UChar *result;
684 UChar pattern[100];
685 UChar expected[100];
686 int32_t resultlength,resultLengthOut;
687
688 str=(UChar*)malloc(sizeof(UChar) * 25);
689 u_uastrcpy(str, "Kirti");
690 str1=(UChar*)malloc(sizeof(UChar) * 25);
691 u_uastrcpy(str1, "female");
692 log_verbose("Testing message format with Select test #1\n:");
693 u_uastrcpy(pattern, "{0} est {1, select, female {all\\u00E9e} other {all\\u00E9}} \\u00E0 Paris.");
694 u_uastrcpy(expected, "Kirti est all\\u00E9e \\u00E0 Paris.");
695 resultlength=0;
696 resultLengthOut=u_formatMessage( "fr", pattern, u_strlen(pattern), NULL, resultlength, &status, str , str1);
697 if(status==U_BUFFER_OVERFLOW_ERROR)
698 {
699 status=U_ZERO_ERROR;
700 resultlength=resultLengthOut+1;
701 result=(UChar*)malloc(sizeof(UChar) * resultlength);
702 u_formatMessage( "fr", pattern, u_strlen(pattern), result, resultlength, &status, str , str1);
703 if(u_strcmp(result, expected)==0)
704 log_verbose("PASS: MessagFormat successful on Select test#1\n");
705 else{
706 log_err("FAIL: Error in MessageFormat on Select test#1\n GOT %s EXPECTED %s\n", austrdup(result),
707 austrdup(expected) );
708 }
709 free(result);
710 }
711 if(U_FAILURE(status)){
712 log_data_err("ERROR: failure in message format on Select test#1 : %s \n", myErrorName(status));
713 }
714 free(str);
715 free(str1);
716
717 /*Test a nested pattern*/
718 str=(UChar*)malloc(sizeof(UChar) * 25);
719 u_uastrcpy(str, "Noname");
720 str1=(UChar*)malloc(sizeof(UChar) * 25);
721 u_uastrcpy(str1, "other");
722 log_verbose("Testing message format with Select test #2\n:");
723 u_uastrcpy(pattern, "{0} est {1, select, female {{2,number,integer} all\\u00E9e} other {all\\u00E9}} \\u00E0 Paris.");
724 u_uastrcpy(expected, "Noname est all\\u00E9 \\u00E0 Paris.");
725 resultlength=0;
726 resultLengthOut=u_formatMessage( "fr", pattern, u_strlen(pattern), NULL, resultlength, &status, str , str1,6);
727 if(status==U_BUFFER_OVERFLOW_ERROR)
728 {
729 status=U_ZERO_ERROR;
730 resultlength=resultLengthOut+1;
731 result=(UChar*)malloc(sizeof(UChar) * resultlength);
732 u_formatMessage( "fr", pattern, u_strlen(pattern), result, resultlength, &status, str , str1, 6);
733 if(u_strcmp(result, expected)==0)
734 log_verbose("PASS: MessagFormat successful on Select test#2\n");
735 else{
736 log_err("FAIL: Error in MessageFormat on Select test#2\n GOT %s EXPECTED %s\n", austrdup(result),
737 austrdup(expected) );
738 }
739 free(result);
740 }
741 if(U_FAILURE(status)){
742 log_data_err("ERROR: failure in message format on Select test#2 : %s \n", myErrorName(status));
743 }
744 free(str);
745 free(str1);
746 }
747
748 /* test message format with a choice option */
TestMsgFormatChoice(void)749 static void TestMsgFormatChoice(void)
750 {
751 UChar* str;
752 UErrorCode status = U_ZERO_ERROR;
753 UChar *result;
754 UChar pattern[100];
755 UChar expected[100];
756 int32_t resultlength,resultLengthOut;
757
758 str=(UChar*)malloc(sizeof(UChar) * 25);
759 u_uastrcpy(str, "MyDisk");
760 log_verbose("Testing message format with choice test #6\n:");
761 /*
762 * Before ICU 4.8, umsg_xxx() did not detect conflicting argument types,
763 * and this pattern had {0,number,integer} as the inner argument.
764 * The choice argument has kDouble type while {0,number,integer} has kLong (int32_t).
765 * ICU 4.8 and above detects this as an error.
766 * We changed this pattern to work as intended.
767 */
768 u_uastrcpy(pattern, "The disk {1} contains {0,choice,0#no files|1#one file|1<{0,number} files}");
769 u_uastrcpy(expected, "The disk MyDisk contains 100 files");
770 resultlength=0;
771 resultLengthOut=u_formatMessage( "en_US", pattern, u_strlen(pattern), NULL, resultlength, &status, 100., str);
772 if(status==U_BUFFER_OVERFLOW_ERROR)
773 {
774 status=U_ZERO_ERROR;
775 resultlength=resultLengthOut+1;
776 result=(UChar*)malloc(sizeof(UChar) * resultlength);
777 u_formatMessage( "en_US", pattern, u_strlen(pattern), result, resultlength, &status, 100., str);
778 if(u_strcmp(result, expected)==0)
779 log_verbose("PASS: MessagFormat successful on test#6\n");
780 else{
781 log_err("FAIL: Error in MessageFormat on test#6\n GOT %s EXPECTED %s\n", austrdup(result),
782 austrdup(expected) );
783 }
784 free(result);
785 }
786 if(U_FAILURE(status)){
787 log_data_err("ERROR: failure in message format on test#6 : %s (Are you missing data?)\n", myErrorName(status));
788 }
789
790 log_verbose("Testing message format with choice test #7\n:");
791 u_uastrcpy(expected, "The disk MyDisk contains no files");
792 resultlength=0;
793 resultLengthOut=u_formatMessage( "en_US", pattern, u_strlen(pattern), NULL, resultlength, &status, 0., str);
794 if(status==U_BUFFER_OVERFLOW_ERROR)
795 {
796 status=U_ZERO_ERROR;
797 resultlength=resultLengthOut+1;
798 result=(UChar*)malloc(sizeof(UChar) * resultlength);
799 u_formatMessage( "en_US", pattern, u_strlen(pattern), result, resultlength, &status, 0., str);
800
801 if(u_strcmp(result, expected)==0)
802 log_verbose("PASS: MessagFormat successful on test#7\n");
803 else{
804 log_err("FAIL: Error in MessageFormat on test#7\n GOT: %s EXPECTED %s\n", austrdup(result),
805 austrdup(expected) );
806 }
807 free(result);
808 }
809 if(U_FAILURE(status)){
810 log_data_err("ERROR: failure in message format on test#7 : %s (Are you missing data?)\n", myErrorName(status));
811 }
812
813 log_verbose("Testing message format with choice test #8\n:");
814 u_uastrcpy(expected, "The disk MyDisk contains one file");
815 resultlength=0;
816 resultLengthOut=u_formatMessage( "en_US", pattern, u_strlen(pattern), NULL, resultlength, &status, 1., str);
817 if(status==U_BUFFER_OVERFLOW_ERROR)
818 {
819 status=U_ZERO_ERROR;
820 resultlength=resultLengthOut+1;
821 result=(UChar*)malloc(sizeof(UChar) * resultlength);
822 u_formatMessage( "en_US", pattern, u_strlen(pattern), result, resultlength, &status, 1., str);
823
824 if(u_strcmp(result, expected)==0)
825 log_verbose("PASS: MessagFormat successful on test#8\n");
826 else{
827 log_err("FAIL: Error in MessageFormat on test#8\n GOT %s EXPECTED: %s\n", austrdup(result),
828 austrdup(expected) );
829 }
830
831 free(result);
832 }
833 if(U_FAILURE(status)){
834 log_data_err("ERROR: failure in message format on test#8 : %s (Are you missing data?)\n", myErrorName(status));
835 }
836
837 free(str);
838
839 }
840
841 /*test u_parseMessage() with various test patterns */
TestParseMessage(void)842 static void TestParseMessage(void)
843 {
844 UChar pattern[100];
845 UChar source[100];
846 UErrorCode status = U_ZERO_ERROR;
847 int32_t value;
848 UChar str[10];
849 UChar res[10];
850
851 log_verbose("\nTesting a sample for parse Message test#9\n");
852
853 u_uastrcpy(source, "You deposited an amount of $500.00");
854 u_uastrcpy(pattern, "You {0} an amount of {1,number,currency}");
855 u_uastrcpy(res,"deposited");
856
857 u_parseMessage( "en_US", pattern, u_strlen(pattern), source, u_strlen(source), &status, str, &value);
858 if(U_FAILURE(status)){
859 log_data_err("ERROR: failure in parse Message on test#9: %s (Are you missing data?)\n", myErrorName(status));
860 }
861 else if(value==500.00 && u_strcmp(str,res)==0)
862 log_verbose("PASS: parseMessage successful on test#9\n");
863 else
864 log_err("FAIL: Error in parseMessage on test#9 \n");
865
866
867
868 log_verbose("\nTesting a sample for parse Message test#10\n");
869
870 u_uastrcpy(source, "There are 123 files on MyDisk created");
871 u_uastrcpy(pattern, "There are {0,number,integer} files on {1} created");
872 u_uastrcpy(res,"MyDisk");
873
874 u_parseMessage( "en_US", pattern, u_strlen(pattern), source, u_strlen(source), &status, &value, str);
875 if(U_FAILURE(status)){
876 log_data_err("ERROR: failure in parse Message on test#10: %s (Are you missing data?)\n", myErrorName(status));
877 }
878 else if(value==123.00 && u_strcmp(str,res)==0)
879 log_verbose("PASS: parseMessage successful on test#10\n");
880 else
881 log_err("FAIL: Error in parseMessage on test#10 \n");
882 }
883
CallFormatMessage(const char * locale,UChar * testCasePattern,int32_t patternLength,UChar * result,int32_t resultLength,UErrorCode * status,...)884 static int32_t CallFormatMessage(const char* locale, UChar* testCasePattern, int32_t patternLength,
885 UChar* result, int32_t resultLength, UErrorCode *status, ...)
886 {
887 int32_t len = 0;
888 va_list ap;
889 va_start(ap, status);
890 len = u_vformatMessage(locale, testCasePattern, patternLength, result, resultLength, ap, status);
891 va_end(ap);
892 return len;
893 }
894
895 /* Test u_vformatMessage() with various test patterns. */
TestMessageFormatWithValist(void)896 static void TestMessageFormatWithValist( void )
897 {
898
899 UChar *str;
900 UChar* result;
901 int32_t resultLengthOut,resultlength,i, patternlength;
902 UErrorCode status = U_ZERO_ERROR;
903 UDate d1=1000000000.0;
904
905 ctest_setTimeZone(NULL, &status);
906
907 str=(UChar*)malloc(sizeof(UChar) * 7);
908 u_uastrcpy(str, "MyDisk");
909 resultlength=1;
910 result=(UChar*)malloc(sizeof(UChar) * 1);
911 log_verbose("Testing u_formatMessage90\n");
912 InitStrings();
913 for (i = 0; i < cnt_testCases; i++) {
914 status=U_ZERO_ERROR;
915 patternlength=u_strlen(testCasePatterns[i]);
916 resultLengthOut=CallFormatMessage( "en_US",testCasePatterns[i], patternlength, result, resultlength,
917 &status, 1, 3456.00, d1);
918 if(status== U_BUFFER_OVERFLOW_ERROR)
919 {
920 status=U_ZERO_ERROR;
921 resultlength=resultLengthOut+1;
922 result=(UChar*)realloc(result,sizeof(UChar) * resultlength);
923 CallFormatMessage( "en_US",testCasePatterns[i], patternlength, result, resultlength,
924 &status, 1, 3456.00, d1);
925 }
926 if(U_FAILURE(status)){
927 log_data_err("ERROR: failure in message format on testcase %d: %s (Are you missing data?)\n", i, myErrorName(status) );
928 }
929 else if(u_strcmp(result, testResultStrings[i])==0){
930 log_verbose("PASS: MessagFormat successful on testcase : %d\n", i);
931 }
932 else{
933 log_err("FAIL: Error in MessageFormat on testcase : %d\n GOT %s EXPECTED %s\n", i,
934 austrdup(result), austrdup(testResultStrings[i]) );
935 }
936 }
937 free(result);
938 free(str);
939 FreeStrings();
940
941 ctest_resetTimeZone();
942 }
943
CallParseMessage(const char * locale,UChar * pattern,int32_t patternLength,UChar * source,int32_t sourceLength,UErrorCode * status,...)944 static void CallParseMessage(const char* locale, UChar* pattern, int32_t patternLength,
945 UChar* source, int32_t sourceLength, UErrorCode *status, ...)
946 {
947 va_list ap;
948 va_start(ap, status);
949 u_vparseMessage(locale, pattern, patternLength, source, sourceLength, ap, status);
950 va_end(ap);
951 }
952
953 /*test u_vparseMessage() with various test patterns */
TestParseMessageWithValist(void)954 static void TestParseMessageWithValist(void)
955 {
956 UChar pattern[100];
957 UChar source[100];
958 UErrorCode status = U_ZERO_ERROR;
959 int32_t value;
960 UChar str[10];
961 UChar res[10];
962
963 log_verbose("\nTesting a sample for parse Message test#9\n");
964
965 u_uastrcpy(source, "You deposited an amount of $500.00");
966 u_uastrcpy(pattern, "You {0} an amount of {1,number,currency}");
967 u_uastrcpy(res,"deposited");
968
969 CallParseMessage( "en_US", pattern, u_strlen(pattern), source, u_strlen(source), &status, str, &value);
970 if(U_FAILURE(status)){
971 log_data_err("ERROR: failure in parse Message on test#9: %s (Are you missing data?)\n", myErrorName(status));
972 }
973 else if(value==500.00 && u_strcmp(str,res)==0)
974 log_verbose("PASS: parseMessage successful on test#9\n");
975 else
976 log_err("FAIL: Error in parseMessage on test#9\n");
977
978
979 log_verbose("\nTesting a sample for parse Message test#10\n");
980
981 u_uastrcpy(source, "There are 123 files on MyDisk created");
982 u_uastrcpy(pattern, "There are {0,number,integer} files on {1} created");
983 u_uastrcpy(res,"MyDisk");
984
985 CallParseMessage( "en_US", pattern, u_strlen(pattern), source, u_strlen(source), &status, &value, str);
986 if(U_FAILURE(status)){
987 log_data_err("ERROR: failure in parse Message on test#10: %s (Are you missing data?)\n", myErrorName(status));
988 }
989 else if(value==123.00 && u_strcmp(str,res)==0)
990 log_verbose("PASS: parseMessage successful on test#10\n");
991 else
992 log_err("FAIL: Error in parseMessage on test#10 \n");
993 }
994
995 /**
996 * Regression test for ICU4C Jitterbug 904
997 */
TestJ904(void)998 static void TestJ904(void) {
999 UChar pattern[256];
1000 UChar result[256];
1001 UChar string[16];
1002 char cresult[256];
1003 int32_t length;
1004 UErrorCode status = U_ZERO_ERROR;
1005 const char* PAT = "Number {1,number,#0.000}, String {0}, Date {2,date,12:mm:ss.SSS}";
1006 const char* EXP = "Number 0,143, String foo, Date 12:34:56.789";
1007
1008 ctest_setTimeZone(NULL, &status);
1009
1010 u_uastrcpy(string, "foo");
1011 /* Slight hack here -- instead of date pattern HH:mm:ss.SSS, use
1012 * 12:mm:ss.SSS. Why? So this test generates the same output --
1013 * "12:34:56.789" -- regardless of time zone (as long as we aren't
1014 * in one of the 30 minute offset zones!). */
1015 u_uastrcpy(pattern, PAT);
1016 length = u_formatMessage("nl", pattern, u_strlen(pattern),
1017 result, 256, &status,
1018 string, 1/7.0,
1019 789.0+1000*(56+60*(34+60*12)));
1020 (void)length; /* Suppress set but not used warning. */
1021
1022 u_austrncpy(cresult, result, sizeof(cresult));
1023
1024 /* This test passes if it DOESN'T CRASH. However, we test the
1025 * output anyway. If the string doesn't match in the date part,
1026 * check to see that the machine doesn't have an unusual time zone
1027 * offset, that is, one with a non-zero minutes/seconds offset
1028 * from GMT -- see above. */
1029 if (strcmp(cresult, EXP) == 0) {
1030 log_verbose("Ok: \"%s\"\n", cresult);
1031 } else {
1032 log_data_err("FAIL: got \"%s\", expected \"%s\" -> %s (Are you missing data?)\n", cresult, EXP, u_errorName(status));
1033 }
1034
1035 ctest_resetTimeZone();
1036 }
1037
OpenMessageFormatTest(void)1038 static void OpenMessageFormatTest(void)
1039 {
1040 UMessageFormat *f1, *f2, *f3;
1041 UChar pattern[256];
1042 UChar result[256];
1043 char cresult[256];
1044 UParseError parseError;
1045 const char* locale = "hi_IN";
1046 char* retLoc;
1047 const char* PAT = "Number {1,number,#0.000}, String {0}, Date {2,date,12:mm:ss.SSS}";
1048 int32_t length=0;
1049 UErrorCode status = U_ZERO_ERROR;
1050
1051 u_uastrncpy(pattern, PAT, UPRV_LENGTHOF(pattern));
1052
1053 /* Test umsg_open */
1054 f1 = umsg_open(pattern,length,NULL,NULL,&status);
1055
1056 if(U_FAILURE(status))
1057 {
1058 log_err("umsg_open failed with pattern %s. Error: \n", PAT, u_errorName(status));
1059 return;
1060 }
1061
1062 /* Test umsg_open with parse error */
1063 status = U_ZERO_ERROR;
1064 f2 = umsg_open(pattern,length,NULL,&parseError,&status);
1065
1066 if(U_FAILURE(status))
1067 {
1068 log_err("umsg_open with parseError failed with pattern %s. Error: %s\n", PAT, u_errorName(status));
1069 return;
1070 }
1071
1072 /* Test umsg_clone */
1073 status = U_ZERO_ERROR;
1074 f3 = umsg_clone(f1,&status);
1075 if(U_FAILURE(status))
1076 {
1077 log_err("umsg_clone failed. Error %s \n", u_errorName(status));
1078 }
1079
1080 /* Test umsg_setLocale */
1081 umsg_setLocale(f1,locale);
1082 /* Test umsg_getLocale */
1083 retLoc = (char*)umsg_getLocale(f1);
1084 if(strcmp(retLoc,locale)!=0)
1085 {
1086 log_err("umsg_setLocale and umsg_getLocale methods failed. Expected:%s Got: %s \n", locale, retLoc);
1087 }
1088
1089 /* Test umsg_applyPattern */
1090 status = U_ZERO_ERROR;
1091 umsg_applyPattern(f1,pattern,(int32_t)strlen(PAT),NULL,&status);
1092 if(U_FAILURE(status))
1093 {
1094 log_data_err("umsg_applyPattern failed. Error %s (Are you missing data?)\n",u_errorName(status));
1095 }
1096
1097 /* Test umsg_toPattern */
1098 umsg_toPattern(f1,result,256,&status);
1099 if(U_FAILURE(status) ){
1100 log_data_err("umsg_toPattern method failed. Error: %s (Are you missing data?)\n",u_errorName(status));
1101 } else {
1102 if(u_strcmp(result,pattern)!=0){
1103 u_UCharsToChars(result,cresult,256);
1104 log_err("umsg_toPattern method failed. Expected: %s Got: %s \n",PAT,cresult);
1105 }
1106 }
1107 /* umsg_format umsg_parse */
1108
1109 umsg_close(f1);
1110 umsg_close(f2);
1111 umsg_close(f3);
1112 }
1113
MessageLength(void)1114 static void MessageLength(void)
1115 {
1116 UErrorCode status = U_ZERO_ERROR;
1117 const char patChars[] = {"123{0}456{0}"};
1118 const char expectedChars[] = {"123abc"};
1119 UChar pattern[sizeof(patChars)];
1120 UChar arg[] = {0x61,0x62,0x63,0};
1121 UChar result[128] = {0};
1122 UChar expected[sizeof(expectedChars)];
1123
1124 u_uastrncpy(pattern, patChars, UPRV_LENGTHOF(pattern));
1125 u_uastrncpy(expected, expectedChars, UPRV_LENGTHOF(expected));
1126
1127 u_formatMessage("en_US", pattern, 6, result, UPRV_LENGTHOF(result), &status, arg);
1128 if (U_FAILURE(status)) {
1129 log_err("u_formatMessage method failed. Error: %s \n",u_errorName(status));
1130 }
1131 if (u_strcmp(result, expected) != 0) {
1132 log_err("u_formatMessage didn't return expected result\n");
1133 }
1134 }
1135
TestMessageWithUnusedArgNumber(void)1136 static void TestMessageWithUnusedArgNumber(void) {
1137 UErrorCode errorCode = U_ZERO_ERROR;
1138 U_STRING_DECL(pattern, "abc {1} def", 11);
1139 UChar x[2] = { 0x78, 0 }; // "x"
1140 UChar y[2] = { 0x79, 0 }; // "y"
1141 U_STRING_DECL(expected, "abc y def", 9);
1142 UChar result[20];
1143 int32_t length;
1144
1145 U_STRING_INIT(pattern, "abc {1} def", 11);
1146 U_STRING_INIT(expected, "abc y def", 9);
1147 length = u_formatMessage("en", pattern, -1, result, UPRV_LENGTHOF(result), &errorCode, x, y);
1148 if (U_FAILURE(errorCode) || length != u_strlen(expected) || u_strcmp(result, expected) != 0) {
1149 log_err("u_formatMessage(pattern with only {1}, 2 args) failed: result length %d, UErrorCode %s \n",
1150 (int)length, u_errorName(errorCode));
1151 }
1152 }
1153
TestErrorChaining(void)1154 static void TestErrorChaining(void) {
1155 UErrorCode status = U_USELESS_COLLATOR_ERROR;
1156
1157 umsg_open(NULL, 0, NULL, NULL, &status);
1158 umsg_applyPattern(NULL, NULL, 0, NULL, &status);
1159 umsg_toPattern(NULL, NULL, 0, &status);
1160 umsg_clone(NULL, &status);
1161 umsg_format(NULL, NULL, 0, &status);
1162 umsg_parse(NULL, NULL, 0, NULL, &status);
1163 umsg_close(NULL);
1164
1165 /* All of this code should have done nothing. */
1166 if (status != U_USELESS_COLLATOR_ERROR) {
1167 log_err("Status got changed to %s\n", u_errorName(status));
1168 }
1169
1170 status = U_ZERO_ERROR;
1171 umsg_open(NULL, 0, NULL, NULL, &status);
1172 if (status != U_ILLEGAL_ARGUMENT_ERROR) {
1173 log_err("Status should be U_ILLEGAL_ARGUMENT_ERROR instead of %s\n", u_errorName(status));
1174 }
1175 status = U_ZERO_ERROR;
1176 umsg_applyPattern(NULL, NULL, 0, NULL, &status);
1177 if (status != U_ILLEGAL_ARGUMENT_ERROR) {
1178 log_err("Status should be U_ILLEGAL_ARGUMENT_ERROR instead of %s\n", u_errorName(status));
1179 }
1180 status = U_ZERO_ERROR;
1181 umsg_toPattern(NULL, NULL, 0, &status);
1182 if (status != U_ILLEGAL_ARGUMENT_ERROR) {
1183 log_err("Status should be U_ILLEGAL_ARGUMENT_ERROR instead of %s\n", u_errorName(status));
1184 }
1185 status = U_ZERO_ERROR;
1186 umsg_clone(NULL, &status);
1187 if (status != U_ILLEGAL_ARGUMENT_ERROR) {
1188 log_err("Status should be U_ILLEGAL_ARGUMENT_ERROR instead of %s\n", u_errorName(status));
1189 }
1190 }
1191
1192 void addMsgForTest(TestNode** root);
1193
addMsgForTest(TestNode ** root)1194 void addMsgForTest(TestNode** root)
1195 {
1196 addTest(root, &OpenMessageFormatTest, "tsformat/cmsgtst/OpenMessageFormatTest");
1197 addTest(root, &MessageFormatTest, "tsformat/cmsgtst/MessageFormatTest");
1198 addTest(root, &TestSampleMessageFormat, "tsformat/cmsgtst/TestSampleMessageFormat");
1199 addTest(root, &TestSampleFormatAndParse, "tsformat/cmsgtst/TestSampleFormatAndParse");
1200 addTest(root, &TestSampleFormatAndParseWithError, "tsformat/cmsgtst/TestSampleFormatAndParseWithError");
1201 addTest(root, &TestNewFormatAndParseAPI, "tsformat/cmsgtst/TestNewFormatAndParseAPI");
1202 addTest(root, &TestMsgFormatChoice, "tsformat/cmsgtst/TestMsgFormatChoice");
1203 addTest(root, &TestParseMessage, "tsformat/cmsgtst/TestParseMessage");
1204 addTest(root, &TestMessageFormatWithValist, "tsformat/cmsgtst/TestMessageFormatWithValist");
1205 addTest(root, &TestParseMessageWithValist, "tsformat/cmsgtst/TestParseMessageWithValist");
1206 addTest(root, &TestJ904, "tsformat/cmsgtst/TestJ904");
1207 addTest(root, &MessageLength, "tsformat/cmsgtst/MessageLength");
1208 addTest(root, &TestMessageWithUnusedArgNumber, "tsformat/cmsgtst/TestMessageWithUnusedArgNumber");
1209 addTest(root, &TestErrorChaining, "tsformat/cmsgtst/TestErrorChaining");
1210 addTest(root, &TestMsgFormatSelect, "tsformat/cmsgtst/TestMsgFormatSelect");
1211 }
1212
1213 #endif /* #if !UCONFIG_NO_FORMATTING */
1214