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 35static 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 43static 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 51const int32_t cnt_testCases = 5; 52static UChar* testCasePatterns[5]; 53 54static UChar* testResultStrings[5]; 55 56static UBool strings_initialized = false; 57 58/* function used to create the test patterns for testing Message formatting */ 59static 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 79static 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. */ 98static 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() */ 109static 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 */ 279static 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 */ 379static 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 } 470cleanup: 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 */ 481static 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 } 569cleanup: 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 */ 581static 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 */ 678static 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 */ 749static 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 */ 842static 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 884static 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. */ 896static 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 944static 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 */ 954static 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 */ 998static 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 1038static 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 1114static 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 1136static 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 1154static 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 1192void addMsgForTest(TestNode** root); 1193 1194void 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