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 */ 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 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. */ 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() */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 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. */ 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 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 */ 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 */ 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 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 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 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 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 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