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