| OLD | NEW |
| (Empty) |
| 1 /******************************************************************** | |
| 2 * COPYRIGHT: | |
| 3 * Copyright (c) 1997-2015, International Business Machines Corporation and | |
| 4 * others. All Rights Reserved. | |
| 5 ******************************************************************** | |
| 6 * File TMSGFMT.CPP | |
| 7 * | |
| 8 * Modification History: | |
| 9 * | |
| 10 * Date Name Description | |
| 11 * 03/24/97 helena Converted from Java. | |
| 12 * 07/11/97 helena Updated to work on AIX. | |
| 13 * 08/04/97 jfitz Updated to intltest | |
| 14 *******************************************************************/ | |
| 15 | |
| 16 #include "unicode/utypes.h" | |
| 17 | |
| 18 #if !UCONFIG_NO_FORMATTING | |
| 19 | |
| 20 #include "tmsgfmt.h" | |
| 21 #include "cmemory.h" | |
| 22 | |
| 23 #include "unicode/format.h" | |
| 24 #include "unicode/decimfmt.h" | |
| 25 #include "unicode/localpointer.h" | |
| 26 #include "unicode/locid.h" | |
| 27 #include "unicode/msgfmt.h" | |
| 28 #include "unicode/numfmt.h" | |
| 29 #include "unicode/choicfmt.h" | |
| 30 #include "unicode/messagepattern.h" | |
| 31 #include "unicode/selfmt.h" | |
| 32 #include "unicode/gregocal.h" | |
| 33 #include <stdio.h> | |
| 34 | |
| 35 void | |
| 36 TestMessageFormat::runIndexedTest(int32_t index, UBool exec, | |
| 37 const char* &name, char* /*par*/) { | |
| 38 TESTCASE_AUTO_BEGIN; | |
| 39 TESTCASE_AUTO(testBug1); | |
| 40 TESTCASE_AUTO(testBug2); | |
| 41 TESTCASE_AUTO(sample); | |
| 42 TESTCASE_AUTO(PatternTest); | |
| 43 TESTCASE_AUTO(testStaticFormat); | |
| 44 TESTCASE_AUTO(testSimpleFormat); | |
| 45 TESTCASE_AUTO(testMsgFormatChoice); | |
| 46 TESTCASE_AUTO(testCopyConstructor); | |
| 47 TESTCASE_AUTO(testAssignment); | |
| 48 TESTCASE_AUTO(testClone); | |
| 49 TESTCASE_AUTO(testEquals); | |
| 50 TESTCASE_AUTO(testNotEquals); | |
| 51 TESTCASE_AUTO(testSetLocale); | |
| 52 TESTCASE_AUTO(testFormat); | |
| 53 TESTCASE_AUTO(testParse); | |
| 54 TESTCASE_AUTO(testAdopt); | |
| 55 TESTCASE_AUTO(testCopyConstructor2); | |
| 56 TESTCASE_AUTO(TestUnlimitedArgsAndSubformats); | |
| 57 TESTCASE_AUTO(TestRBNF); | |
| 58 TESTCASE_AUTO(TestTurkishCasing); | |
| 59 TESTCASE_AUTO(testAutoQuoteApostrophe); | |
| 60 TESTCASE_AUTO(testMsgFormatPlural); | |
| 61 TESTCASE_AUTO(testMsgFormatSelect); | |
| 62 TESTCASE_AUTO(testApostropheInPluralAndSelect); | |
| 63 TESTCASE_AUTO(TestApostropheMode); | |
| 64 TESTCASE_AUTO(TestCompatibleApostrophe); | |
| 65 TESTCASE_AUTO(testCoverage); | |
| 66 TESTCASE_AUTO(testGetFormatNames); | |
| 67 TESTCASE_AUTO(TestTrimArgumentName); | |
| 68 TESTCASE_AUTO(TestSelectOrdinal); | |
| 69 TESTCASE_AUTO(TestDecimals); | |
| 70 TESTCASE_AUTO_END; | |
| 71 } | |
| 72 | |
| 73 void TestMessageFormat::testBug3() | |
| 74 { | |
| 75 double myNumber = -123456; | |
| 76 DecimalFormat *form = 0; | |
| 77 Locale locale[] = { | |
| 78 Locale("ar", "", ""), | |
| 79 Locale("be", "", ""), | |
| 80 Locale("bg", "", ""), | |
| 81 Locale("ca", "", ""), | |
| 82 Locale("cs", "", ""), | |
| 83 Locale("da", "", ""), | |
| 84 Locale("de", "", ""), | |
| 85 Locale("de", "AT", ""), | |
| 86 Locale("de", "CH", ""), | |
| 87 Locale("el", "", ""), // 10 | |
| 88 Locale("en", "CA", ""), | |
| 89 Locale("en", "GB", ""), | |
| 90 Locale("en", "IE", ""), | |
| 91 Locale("en", "US", ""), | |
| 92 Locale("es", "", ""), | |
| 93 Locale("et", "", ""), | |
| 94 Locale("fi", "", ""), | |
| 95 Locale("fr", "", ""), | |
| 96 Locale("fr", "BE", ""), | |
| 97 Locale("fr", "CA", ""), // 20 | |
| 98 Locale("fr", "CH", ""), | |
| 99 Locale("he", "", ""), | |
| 100 Locale("hr", "", ""), | |
| 101 Locale("hu", "", ""), | |
| 102 Locale("is", "", ""), | |
| 103 Locale("it", "", ""), | |
| 104 Locale("it", "CH", ""), | |
| 105 Locale("ja", "", ""), | |
| 106 Locale("ko", "", ""), | |
| 107 Locale("lt", "", ""), // 30 | |
| 108 Locale("lv", "", ""), | |
| 109 Locale("mk", "", ""), | |
| 110 Locale("nl", "", ""), | |
| 111 Locale("nl", "BE", ""), | |
| 112 Locale("no", "", ""), | |
| 113 Locale("pl", "", ""), | |
| 114 Locale("pt", "", ""), | |
| 115 Locale("ro", "", ""), | |
| 116 Locale("ru", "", ""), | |
| 117 Locale("sh", "", ""), // 40 | |
| 118 Locale("sk", "", ""), | |
| 119 Locale("sl", "", ""), | |
| 120 Locale("sq", "", ""), | |
| 121 Locale("sr", "", ""), | |
| 122 Locale("sv", "", ""), | |
| 123 Locale("tr", "", ""), | |
| 124 Locale("uk", "", ""), | |
| 125 Locale("zh", "", ""), | |
| 126 Locale("zh", "TW", "") // 49 | |
| 127 }; | |
| 128 int32_t i; | |
| 129 for (i= 0; i < 49; i++) { | |
| 130 UnicodeString buffer; | |
| 131 logln(locale[i].getDisplayName(buffer)); | |
| 132 UErrorCode success = U_ZERO_ERROR; | |
| 133 // form = (DecimalFormat*)NumberFormat::createCurrencyInstance(locale[i],
success); | |
| 134 form = (DecimalFormat*)NumberFormat::createInstance(locale[i], success); | |
| 135 if (U_FAILURE(success)) { | |
| 136 errln("Err: Number Format "); | |
| 137 logln("Number format creation failed."); | |
| 138 continue; | |
| 139 } | |
| 140 Formattable result; | |
| 141 FieldPosition pos(0); | |
| 142 buffer.remove(); | |
| 143 form->format(myNumber, buffer, pos); | |
| 144 success = U_ZERO_ERROR; | |
| 145 ParsePosition parsePos; | |
| 146 form->parse(buffer, result, parsePos); | |
| 147 logln(UnicodeString(" -> ") /* + << dec*/ + toString(result) + UnicodeSt
ring("[supposed output for result]")); | |
| 148 if (U_FAILURE(success)) { | |
| 149 errln("Err: Number Format parse"); | |
| 150 logln("Number format parse failed."); | |
| 151 } | |
| 152 delete form; | |
| 153 } | |
| 154 } | |
| 155 | |
| 156 void TestMessageFormat::testBug1() | |
| 157 { | |
| 158 const double limit[] = {0.0, 1.0, 2.0}; | |
| 159 const UnicodeString formats[] = {"0.0<=Arg<1.0", | |
| 160 "1.0<=Arg<2.0", | |
| 161 "2.0<-Arg"}; | |
| 162 ChoiceFormat *cf = new ChoiceFormat(limit, formats, 3); | |
| 163 FieldPosition status(0); | |
| 164 UnicodeString toAppendTo; | |
| 165 cf->format((int32_t)1, toAppendTo, status); | |
| 166 if (toAppendTo != "1.0<=Arg<2.0") { | |
| 167 errln("ChoiceFormat cmp in testBug1"); | |
| 168 } | |
| 169 logln(toAppendTo); | |
| 170 delete cf; | |
| 171 } | |
| 172 | |
| 173 void TestMessageFormat::testBug2() | |
| 174 { | |
| 175 UErrorCode status = U_ZERO_ERROR; | |
| 176 UnicodeString result; | |
| 177 // {sfb} use double format in pattern, so result will match (not strictly ne
cessary) | |
| 178 const UnicodeString pattern = "There {0,choice,0#are no files|1#is one file|
1<are {0, number} files} on disk {1}. "; | |
| 179 logln("The input pattern : " + pattern); | |
| 180 MessageFormat *fmt = new MessageFormat(pattern, status); | |
| 181 if (U_FAILURE(status)) { | |
| 182 dataerrln("MessageFormat pattern creation failed. - %s", u_errorName(sta
tus)); | |
| 183 return; | |
| 184 } | |
| 185 logln("The output pattern is : " + fmt->toPattern(result)); | |
| 186 if (pattern != result) { | |
| 187 errln("MessageFormat::toPattern() failed."); | |
| 188 } | |
| 189 delete fmt; | |
| 190 } | |
| 191 | |
| 192 #if 0 | |
| 193 #if defined(_DEBUG) && U_IOSTREAM_SOURCE >= 199711 | |
| 194 //---------------------------------------------------- | |
| 195 // console I/O | |
| 196 //---------------------------------------------------- | |
| 197 | |
| 198 #include <iostream> | |
| 199 std::ostream& operator<<(std::ostream& stream, const Formattable& obj); | |
| 200 | |
| 201 #include "unicode/datefmt.h" | |
| 202 #include <stdlib.h> | |
| 203 #include <string.h> | |
| 204 | |
| 205 IntlTest& | |
| 206 operator<<( IntlTest& stream, | |
| 207 const Formattable& obj) | |
| 208 { | |
| 209 static DateFormat *defDateFormat = 0; | |
| 210 | |
| 211 UnicodeString buffer; | |
| 212 switch(obj.getType()) { | |
| 213 case Formattable::kDate : | |
| 214 if (defDateFormat == 0) { | |
| 215 defDateFormat = DateFormat::createInstance(); | |
| 216 } | |
| 217 defDateFormat->format(obj.getDate(), buffer); | |
| 218 stream << buffer; | |
| 219 break; | |
| 220 case Formattable::kDouble : | |
| 221 char convert[20]; | |
| 222 sprintf( convert, "%lf", obj.getDouble() ); | |
| 223 stream << convert << "D"; | |
| 224 break; | |
| 225 case Formattable::kLong : | |
| 226 stream << obj.getLong() << "L"; | |
| 227 break; | |
| 228 case Formattable::kString: | |
| 229 stream << "\"" << obj.getString(buffer) << "\""; | |
| 230 break; | |
| 231 case Formattable::kArray: | |
| 232 int32_t i, count; | |
| 233 const Formattable* array; | |
| 234 array = obj.getArray(count); | |
| 235 stream << "["; | |
| 236 for (i=0; i<count; ++i) stream << array[i] << ( (i==(count-1)) ? ""
: ", " ); | |
| 237 stream << "]"; | |
| 238 break; | |
| 239 default: | |
| 240 stream << "INVALID_Formattable"; | |
| 241 } | |
| 242 return stream; | |
| 243 } | |
| 244 #endif /* defined(_DEBUG) && U_IOSTREAM_SOURCE >= 199711 */ | |
| 245 #endif | |
| 246 | |
| 247 void TestMessageFormat::PatternTest() | |
| 248 { | |
| 249 Formattable testArgs[] = { | |
| 250 Formattable(double(1)), Formattable(double(3456)), | |
| 251 Formattable("Disk"), Formattable(UDate((int32_t)1000000000L), Format
table::kIsDate) | |
| 252 }; | |
| 253 UnicodeString testCases[] = { | |
| 254 "Quotes '', '{', 'a' {0} '{0}'", | |
| 255 "Quotes '', '{', 'a' {0,number} '{0}'", | |
| 256 "'{'1,number,'#',##} {1,number,'#',##}", | |
| 257 "There are {1} files on {2} at {3}.", | |
| 258 "On {2}, there are {1} files, with {0,number,currency}.", | |
| 259 "'{1,number,percent}', {1,number,percent},", | |
| 260 "'{1,date,full}', {1,date,full},", | |
| 261 "'{3,date,full}', {3,date,full},", | |
| 262 "'{1,number,#,##}' {1,number,#,##}", | |
| 263 }; | |
| 264 | |
| 265 // ICU 4.8 returns the original pattern (testCases), | |
| 266 // rather than toPattern() reconstituting a new, equivalent pattern string (
testResultPatterns). | |
| 267 /*UnicodeString testResultPatterns[] = { | |
| 268 "Quotes '', '{', a {0} '{'0}", | |
| 269 "Quotes '', '{', a {0,number} '{'0}", | |
| 270 "'{'1,number,#,##} {1,number,'#'#,##}", | |
| 271 "There are {1} files on {2} at {3}.", | |
| 272 "On {2}, there are {1} files, with {0,number,currency}.", | |
| 273 "'{'1,number,percent}, {1,number,percent},", | |
| 274 "'{'1,date,full}, {1,date,full},", | |
| 275 "'{'3,date,full}, {3,date,full},", | |
| 276 "'{'1,number,#,##} {1,number,#,##}" | |
| 277 };*/ | |
| 278 | |
| 279 UnicodeString testResultStrings[] = { | |
| 280 "Quotes ', {, 'a' 1 {0}", | |
| 281 "Quotes ', {, 'a' 1 {0}", | |
| 282 "{1,number,'#',##} #34,56", | |
| 283 "There are 3,456 files on Disk at 1/12/70, 5:46 AM.", | |
| 284 "On Disk, there are 3,456 files, with $1.00.", | |
| 285 "{1,number,percent}, 345,600%,", | |
| 286 "{1,date,full}, Wednesday, December 31, 1969,", | |
| 287 "{3,date,full}, Monday, January 12, 1970,", | |
| 288 "{1,number,#,##} 34,56" | |
| 289 }; | |
| 290 | |
| 291 | |
| 292 for (int32_t i = 0; i < 9; ++i) { | |
| 293 //it_out << "\nPat in: " << testCases[i]); | |
| 294 | |
| 295 MessageFormat *form = 0; | |
| 296 UErrorCode success = U_ZERO_ERROR; | |
| 297 UnicodeString buffer; | |
| 298 form = new MessageFormat(testCases[i], Locale::getUS(), success); | |
| 299 if (U_FAILURE(success)) { | |
| 300 dataerrln("MessageFormat creation failed.#1 - %s", u_errorName(succe
ss)); | |
| 301 logln(((UnicodeString)"MessageFormat for ") + testCases[i] + " creat
ion failed.\n"); | |
| 302 continue; | |
| 303 } | |
| 304 // ICU 4.8 returns the original pattern (testCases), | |
| 305 // rather than toPattern() reconstituting a new, equivalent pattern stri
ng (testResultPatterns). | |
| 306 if (form->toPattern(buffer) != testCases[i]) { | |
| 307 // Note: An alternative test would be to build MessagePattern object
s for | |
| 308 // both the input and output patterns and compare them, taking SKIP_
SYNTAX etc. | |
| 309 // into account. | |
| 310 // (Too much trouble...) | |
| 311 errln(UnicodeString("TestMessageFormat::PatternTest failed test #2,
i = ") + i); | |
| 312 //form->toPattern(buffer); | |
| 313 errln(((UnicodeString)" Orig: ") + testCases[i]); | |
| 314 errln(((UnicodeString)" Exp: ") + testCases[i]); | |
| 315 errln(((UnicodeString)" Got: ") + buffer); | |
| 316 } | |
| 317 | |
| 318 //it_out << "Pat out: " << form->toPattern(buffer)); | |
| 319 UnicodeString result; | |
| 320 int32_t count = 4; | |
| 321 FieldPosition fieldpos(0); | |
| 322 form->format(testArgs, count, result, fieldpos, success); | |
| 323 if (U_FAILURE(success)) { | |
| 324 dataerrln("MessageFormat failed test #3 - %s", u_errorName(success))
; | |
| 325 logln("TestMessageFormat::PatternTest failed test #3"); | |
| 326 continue; | |
| 327 } | |
| 328 if (result != testResultStrings[i]) { | |
| 329 errln("TestMessageFormat::PatternTest failed test #4"); | |
| 330 logln("TestMessageFormat::PatternTest failed #4."); | |
| 331 logln(UnicodeString(" Result: ") + result ); | |
| 332 logln(UnicodeString(" Expected: ") + testResultStrings[i] ); | |
| 333 } | |
| 334 | |
| 335 | |
| 336 //it_out << "Result: " << result); | |
| 337 #if 0 | |
| 338 /* TODO: Look at this test and see if this is still a valid test */ | |
| 339 logln("---------------- test parse ----------------"); | |
| 340 | |
| 341 form->toPattern(buffer); | |
| 342 logln("MSG pattern for parse: " + buffer); | |
| 343 | |
| 344 int32_t parseCount = 0; | |
| 345 Formattable* values = form->parse(result, parseCount, success); | |
| 346 if (U_FAILURE(success)) { | |
| 347 errln("MessageFormat failed test #5"); | |
| 348 logln(UnicodeString("MessageFormat failed test #5 with error code ")
+(int32_t)success); | |
| 349 } else if (parseCount != count) { | |
| 350 errln("MSG count not %d as expected. Got %d", count, parseCount); | |
| 351 } | |
| 352 UBool failed = FALSE; | |
| 353 for (int32_t j = 0; j < parseCount; ++j) { | |
| 354 if (values == 0 || testArgs[j] != values[j]) { | |
| 355 errln(((UnicodeString)"MSG testargs[") + j + "]: " + toString(te
stArgs[j])); | |
| 356 errln(((UnicodeString)"MSG values[") + j + "] : " + toString(va
lues[j])); | |
| 357 failed = TRUE; | |
| 358 } | |
| 359 } | |
| 360 if (failed) | |
| 361 errln("MessageFormat failed test #6"); | |
| 362 #endif | |
| 363 delete form; | |
| 364 } | |
| 365 } | |
| 366 | |
| 367 void TestMessageFormat::sample() | |
| 368 { | |
| 369 MessageFormat *form = 0; | |
| 370 UnicodeString buffer1, buffer2; | |
| 371 UErrorCode success = U_ZERO_ERROR; | |
| 372 form = new MessageFormat("There are {0} files on {1}", success); | |
| 373 if (U_FAILURE(success)) { | |
| 374 errln("Err: Message format creation failed"); | |
| 375 logln("Sample message format creation failed."); | |
| 376 return; | |
| 377 } | |
| 378 UnicodeString abc("abc"); | |
| 379 UnicodeString def("def"); | |
| 380 Formattable testArgs1[] = { abc, def }; | |
| 381 FieldPosition fieldpos(0); | |
| 382 assertEquals("format", | |
| 383 "There are abc files on def", | |
| 384 form->format(testArgs1, 2, buffer2, fieldpos, success)); | |
| 385 assertSuccess("format", success); | |
| 386 delete form; | |
| 387 } | |
| 388 | |
| 389 void TestMessageFormat::testStaticFormat() | |
| 390 { | |
| 391 UErrorCode err = U_ZERO_ERROR; | |
| 392 Formattable arguments[] = { | |
| 393 (int32_t)7, | |
| 394 Formattable(UDate(8.71068e+011), Formattable::kIsDate), | |
| 395 "a disturbance in the Force" | |
| 396 }; | |
| 397 | |
| 398 UnicodeString result; | |
| 399 result = MessageFormat::format( | |
| 400 "At {1,time} on {1,date}, there was {2} on planet {0,number,integer}.", | |
| 401 arguments, | |
| 402 3, | |
| 403 result, | |
| 404 err); | |
| 405 | |
| 406 if (U_FAILURE(err)) { | |
| 407 dataerrln("TestMessageFormat::testStaticFormat #1 - %s", u_errorName(err
)); | |
| 408 logln(UnicodeString("TestMessageFormat::testStaticFormat failed test #1
with error code ")+(int32_t)err); | |
| 409 return; | |
| 410 } | |
| 411 | |
| 412 const UnicodeString expected( | |
| 413 "At 12:20:00 PM on Aug 8, 1997, there was a disturbance in the Force
on planet 7.", ""); | |
| 414 if (result != expected) { | |
| 415 errln("TestMessageFormat::testStaticFormat failed on test"); | |
| 416 logln( UnicodeString(" Result: ") + result ); | |
| 417 logln( UnicodeString(" Expected: ") + expected ); | |
| 418 } | |
| 419 } | |
| 420 | |
| 421 /* When the default locale is tr, make sure that the pattern can still be parsed
. */ | |
| 422 void TestMessageFormat::TestTurkishCasing() | |
| 423 { | |
| 424 UErrorCode err = U_ZERO_ERROR; | |
| 425 Locale saveDefaultLocale; | |
| 426 Locale::setDefault( Locale("tr"), err ); | |
| 427 | |
| 428 Formattable arguments[] = { | |
| 429 (int32_t)7, | |
| 430 Formattable(UDate(8.71068e+011), Formattable::kIsDate), | |
| 431 "a disturbance in the Force" | |
| 432 }; | |
| 433 | |
| 434 UnicodeString result; | |
| 435 result = MessageFormat::format( | |
| 436 "At {1,TIME} on {1,DATE,SHORT}, there was {2} on planet {0,NUMBER,INTEGE
R}.", | |
| 437 arguments, | |
| 438 3, | |
| 439 result, | |
| 440 err); | |
| 441 | |
| 442 if (U_FAILURE(err)) { | |
| 443 dataerrln("TestTurkishCasing #1 with error code %s", u_errorName(err)); | |
| 444 return; | |
| 445 } | |
| 446 | |
| 447 const UnicodeString expected( | |
| 448 "At 12:20:00 on 8.08.1997, there was a disturbance in the Force on p
lanet 7.", ""); | |
| 449 if (result != expected) { | |
| 450 errln("TestTurkishCasing failed on test"); | |
| 451 errln( UnicodeString(" Result: ") + result ); | |
| 452 errln( UnicodeString(" Expected: ") + expected ); | |
| 453 } | |
| 454 Locale::setDefault( saveDefaultLocale, err ); | |
| 455 } | |
| 456 | |
| 457 void TestMessageFormat::testSimpleFormat(/* char* par */) | |
| 458 { | |
| 459 logln("running TestMessageFormat::testSimpleFormat"); | |
| 460 | |
| 461 UErrorCode err = U_ZERO_ERROR; | |
| 462 | |
| 463 Formattable testArgs1[] = {(int32_t)0, "MyDisk"}; | |
| 464 Formattable testArgs2[] = {(int32_t)1, "MyDisk"}; | |
| 465 Formattable testArgs3[] = {(int32_t)12, "MyDisk"}; | |
| 466 | |
| 467 MessageFormat* form = new MessageFormat( | |
| 468 "The disk \"{1}\" contains {0} file(s).", err); | |
| 469 | |
| 470 UnicodeString string; | |
| 471 FieldPosition ignore(FieldPosition::DONT_CARE); | |
| 472 form->format(testArgs1, 2, string, ignore, err); | |
| 473 if (U_FAILURE(err) || string != "The disk \"MyDisk\" contains 0 file(s).") { | |
| 474 dataerrln(UnicodeString("TestMessageFormat::testSimpleFormat failed on t
est #1 - ") + u_errorName(err)); | |
| 475 } | |
| 476 | |
| 477 ignore.setField(FieldPosition::DONT_CARE); | |
| 478 string.remove(); | |
| 479 form->format(testArgs2, 2, string, ignore, err); | |
| 480 if (U_FAILURE(err) || string != "The disk \"MyDisk\" contains 1 file(s).") { | |
| 481 logln(string); | |
| 482 dataerrln(UnicodeString("TestMessageFormat::testSimpleFormat failed on t
est #2")+string + " - " + u_errorName(err)); | |
| 483 } | |
| 484 | |
| 485 ignore.setField(FieldPosition::DONT_CARE); | |
| 486 string.remove(); | |
| 487 form->format(testArgs3, 2, string, ignore, err); | |
| 488 if (U_FAILURE(err) || string != "The disk \"MyDisk\" contains 12 file(s).")
{ | |
| 489 dataerrln(UnicodeString("TestMessageFormat::testSimpleFormat failed on t
est #3")+string + " - " + u_errorName(err)); | |
| 490 } | |
| 491 | |
| 492 delete form; | |
| 493 } | |
| 494 | |
| 495 void TestMessageFormat::testMsgFormatChoice(/* char* par */) | |
| 496 { | |
| 497 logln("running TestMessageFormat::testMsgFormatChoice"); | |
| 498 | |
| 499 UErrorCode err = U_ZERO_ERROR; | |
| 500 | |
| 501 MessageFormat* form = new MessageFormat("The disk \"{1}\" contains {0}.", er
r); | |
| 502 double filelimits[] = {0,1,2}; | |
| 503 UnicodeString filepart[] = {"no files","one file","{0,number} files"}; | |
| 504 ChoiceFormat* fileform = new ChoiceFormat(filelimits, filepart, 3); | |
| 505 form->setFormat(1,*fileform); // NOT zero, see below | |
| 506 //is the format adopted? | |
| 507 | |
| 508 FieldPosition ignore(FieldPosition::DONT_CARE); | |
| 509 UnicodeString string; | |
| 510 Formattable testArgs1[] = {(int32_t)0, "MyDisk"}; | |
| 511 form->format(testArgs1, 2, string, ignore, err); | |
| 512 if (string != "The disk \"MyDisk\" contains no files.") { | |
| 513 errln("TestMessageFormat::testMsgFormatChoice failed on test #1"); | |
| 514 } | |
| 515 | |
| 516 ignore.setField(FieldPosition::DONT_CARE); | |
| 517 string.remove(); | |
| 518 Formattable testArgs2[] = {(int32_t)1, "MyDisk"}; | |
| 519 form->format(testArgs2, 2, string, ignore, err); | |
| 520 if (string != "The disk \"MyDisk\" contains one file.") { | |
| 521 errln("TestMessageFormat::testMsgFormatChoice failed on test #2"); | |
| 522 } | |
| 523 | |
| 524 ignore.setField(FieldPosition::DONT_CARE); | |
| 525 string.remove(); | |
| 526 Formattable testArgs3[] = {(int32_t)1273, "MyDisk"}; | |
| 527 form->format(testArgs3, 2, string, ignore, err); | |
| 528 if (string != "The disk \"MyDisk\" contains 1,273 files.") { | |
| 529 dataerrln("TestMessageFormat::testMsgFormatChoice failed on test #3 - %s
", u_errorName(err)); | |
| 530 } | |
| 531 | |
| 532 delete form; | |
| 533 delete fileform; | |
| 534 } | |
| 535 | |
| 536 | |
| 537 void TestMessageFormat::testMsgFormatPlural(/* char* par */) | |
| 538 { | |
| 539 logln("running TestMessageFormat::testMsgFormatPlural"); | |
| 540 | |
| 541 UErrorCode err = U_ZERO_ERROR; | |
| 542 UnicodeString t1("{0, plural, one{C''est # fichier} other{Ce sont # fichiers
}} dans la liste."); | |
| 543 UnicodeString t2("{argument, plural, one{C''est # fichier} other {Ce sont #
fichiers}} dans la liste."); | |
| 544 UnicodeString t3("There {0, plural, one{is # zavod}few{are {0, number,###.0}
zavoda} other{are # zavodov}} in the directory."); | |
| 545 UnicodeString t4("There {argument, plural, one{is # zavod}few{are {argument,
number,###.0} zavoda} other{are #zavodov}} in the directory."); | |
| 546 UnicodeString t5("{0, plural, one {{0, number,C''est #,##0.0# fichier}} othe
r {Ce sont # fichiers}} dans la liste."); | |
| 547 MessageFormat* mfNum = new MessageFormat(t1, Locale("fr"), err); | |
| 548 if (U_FAILURE(err)) { | |
| 549 dataerrln("TestMessageFormat::testMsgFormatPlural #1 - argumentIndex - %
s", u_errorName(err)); | |
| 550 logln(UnicodeString("TestMessageFormat::testMsgFormatPlural #1 with erro
r code ")+(int32_t)err); | |
| 551 return; | |
| 552 } | |
| 553 Formattable testArgs1((int32_t)0); | |
| 554 FieldPosition ignore(FieldPosition::DONT_CARE); | |
| 555 UnicodeString numResult1; | |
| 556 mfNum->format(&testArgs1, 1, numResult1, ignore, err); | |
| 557 | |
| 558 MessageFormat* mfAlpha = new MessageFormat(t2, Locale("fr"), err); | |
| 559 UnicodeString argName[] = {UnicodeString("argument")}; | |
| 560 UnicodeString argNameResult; | |
| 561 mfAlpha->format(argName, &testArgs1, 1, argNameResult, err); | |
| 562 if (U_FAILURE(err)) { | |
| 563 dataerrln("TestMessageFormat::testMsgFormatPlural #1 - argumentName - %s
", u_errorName(err)); | |
| 564 logln(UnicodeString("TestMessageFormat::testMsgFormatPlural #1 with erro
r code ")+(int32_t)err); | |
| 565 delete mfNum; | |
| 566 return; | |
| 567 } | |
| 568 if ( numResult1 != argNameResult){ | |
| 569 errln("TestMessageFormat::testMsgFormatPlural #1"); | |
| 570 logln(UnicodeString("The results of argumentName and argumentIndex are n
ot the same.")); | |
| 571 } | |
| 572 if ( numResult1 != UnicodeString("C\'est 0 fichier dans la liste.")) { | |
| 573 errln("TestMessageFormat::testMsgFormatPlural #1"); | |
| 574 logln(UnicodeString("The results of argumentName and argumentIndex are n
ot the same.")); | |
| 575 } | |
| 576 err = U_ZERO_ERROR; | |
| 577 | |
| 578 delete mfNum; | |
| 579 delete mfAlpha; | |
| 580 | |
| 581 MessageFormat* mfNum2 = new MessageFormat(t3, Locale("uk"), err); | |
| 582 numResult1.remove(); | |
| 583 Formattable testArgs2((int32_t)4); | |
| 584 mfNum2->format(&testArgs2, 1, numResult1, ignore, err); | |
| 585 MessageFormat* mfAlpha2 = new MessageFormat(t4, Locale("uk"), err); | |
| 586 argNameResult.remove(); | |
| 587 mfAlpha2->format(argName, &testArgs2, 1, argNameResult, err); | |
| 588 | |
| 589 if (U_FAILURE(err)) { | |
| 590 errln("TestMessageFormat::testMsgFormatPlural #2 - argumentName"); | |
| 591 logln(UnicodeString("TestMessageFormat::testMsgFormatPlural #2 with erro
r code ")+(int32_t)err); | |
| 592 delete mfNum2; | |
| 593 return; | |
| 594 } | |
| 595 if ( numResult1 != argNameResult){ | |
| 596 errln("TestMessageFormat::testMsgFormatPlural #2"); | |
| 597 logln(UnicodeString("The results of argumentName and argumentIndex are n
ot the same.")); | |
| 598 } | |
| 599 if ( numResult1 != UnicodeString("There are 4,0 zavoda in the directory."))
{ | |
| 600 errln("TestMessageFormat::testMsgFormatPlural #2"); | |
| 601 logln(UnicodeString("The results of argumentName and argumentIndex are n
ot the same.")); | |
| 602 } | |
| 603 | |
| 604 delete mfNum2; | |
| 605 delete mfAlpha2; | |
| 606 | |
| 607 // nested formats | |
| 608 err = U_ZERO_ERROR; | |
| 609 MessageFormat* msgFmt = new MessageFormat(t5, Locale("fr"), err); | |
| 610 if (U_FAILURE(err)) { | |
| 611 errln("TestMessageFormat::test nested PluralFormat with argumentName"); | |
| 612 logln(UnicodeString("TestMessageFormat::test nested PluralFormat with er
ror code ")+(int32_t)err); | |
| 613 delete msgFmt; | |
| 614 return; | |
| 615 } | |
| 616 Formattable testArgs3((int32_t)0); | |
| 617 argNameResult.remove(); | |
| 618 msgFmt->format(&testArgs3, 1, argNameResult, ignore, err); | |
| 619 if (U_FAILURE(err)) { | |
| 620 errln("TestMessageFormat::test nested PluralFormat with argumentName"); | |
| 621 } | |
| 622 if ( argNameResult!= UnicodeString("C'est 0,0 fichier dans la liste.")) { | |
| 623 errln(UnicodeString("TestMessageFormat::test nested named PluralFormat:
") + argNameResult); | |
| 624 logln(UnicodeString("The unexpected nested named PluralFormat.")); | |
| 625 } | |
| 626 delete msgFmt; | |
| 627 } | |
| 628 | |
| 629 void TestMessageFormat::testApostropheInPluralAndSelect() { | |
| 630 UErrorCode errorCode = U_ZERO_ERROR; | |
| 631 MessageFormat msgFmt(UNICODE_STRING_SIMPLE( | |
| 632 "abc_{0,plural,other{#'#'#'{'#''}}_def_{1,select,other{sel'}'ect''}}_xyz
"), | |
| 633 Locale::getEnglish(), | |
| 634 errorCode); | |
| 635 if (U_FAILURE(errorCode)) { | |
| 636 errln("MessageFormat constructor failed - %s\n", u_errorName(errorCode))
; | |
| 637 return; | |
| 638 } | |
| 639 UnicodeString expected = UNICODE_STRING_SIMPLE("abc_3#3{3'_def_sel}ect'_xyz"
); | |
| 640 Formattable args[] = { (int32_t)3, UNICODE_STRING_SIMPLE("x") }; | |
| 641 internalFormat( | |
| 642 &msgFmt, args, 2, expected, | |
| 643 "MessageFormat with apostrophes in plural/select arguments failed:\n"); | |
| 644 } | |
| 645 | |
| 646 void TestMessageFormat::internalFormat(MessageFormat* msgFmt , | |
| 647 Formattable* args , int32_t numOfArgs , | |
| 648 UnicodeString expected, const char* errMsg) | |
| 649 { | |
| 650 UnicodeString result; | |
| 651 FieldPosition ignore(FieldPosition::DONT_CARE); | |
| 652 UErrorCode status = U_ZERO_ERROR; | |
| 653 | |
| 654 //Format with passed arguments | |
| 655 msgFmt->format( args , numOfArgs , result, ignore, status); | |
| 656 if (U_FAILURE(status)) { | |
| 657 dataerrln( "%s error while formatting with ErrorCode as %s" ,errMsg,
u_errorName(status) ); | |
| 658 } | |
| 659 //Compare expected with obtained result | |
| 660 if ( result!= expected ) { | |
| 661 UnicodeString err = UnicodeString(errMsg); | |
| 662 err+= UnicodeString(":Unexpected Result \n Expected: " + expected +
"\n Obtained: " + result + "\n"); | |
| 663 dataerrln(err); | |
| 664 } | |
| 665 } | |
| 666 | |
| 667 MessageFormat* TestMessageFormat::internalCreate( | |
| 668 UnicodeString pattern ,Locale locale ,UErrorCode &status , char* errMsg
) | |
| 669 { | |
| 670 //Create the MessageFormat with simple SelectFormat | |
| 671 MessageFormat* msgFmt = new MessageFormat(pattern, locale, status); | |
| 672 if (U_FAILURE(status)) { | |
| 673 dataerrln( "%s error while constructing with ErrorCode as %s" ,errMsg, u
_errorName(status) ); | |
| 674 logln(UnicodeString("TestMessageFormat::testMsgFormatSelect #1 with erro
r code ")+(int32_t)status); | |
| 675 return NULL; | |
| 676 } | |
| 677 return msgFmt; | |
| 678 } | |
| 679 | |
| 680 void TestMessageFormat::testMsgFormatSelect(/* char* par */) | |
| 681 { | |
| 682 logln("running TestMessageFormat::testMsgFormatSelect"); | |
| 683 | |
| 684 UErrorCode err = U_ZERO_ERROR; | |
| 685 //French Pattern | |
| 686 UnicodeString t1("{0} est {1, select, female {all\\u00E9e} other {all\\u00E9
}} \\u00E0 Paris."); | |
| 687 | |
| 688 err = U_ZERO_ERROR; | |
| 689 //Create the MessageFormat with simple French pattern | |
| 690 MessageFormat* msgFmt1 = internalCreate(t1.unescape(), Locale("fr"),err,(cha
r*)"From TestMessageFormat::TestSelectFormat create t1"); | |
| 691 if (!U_FAILURE(err)) { | |
| 692 //Arguments | |
| 693 Formattable testArgs10[] = {"Kirti","female"}; | |
| 694 Formattable testArgs11[] = {"Victor","other"}; | |
| 695 Formattable testArgs12[] = {"Ash","unknown"}; | |
| 696 Formattable* testArgs[] = {testArgs10,testArgs11,testArgs12}; | |
| 697 UnicodeString exp[] = { | |
| 698 "Kirti est all\\u00E9e \\u00E0 Paris." , | |
| 699 "Victor est all\\u00E9 \\u00E0 Paris.", | |
| 700 "Ash est all\\u00E9 \\u00E0 Paris."}; | |
| 701 //Format | |
| 702 for( int i=0; i< 3; i++){ | |
| 703 internalFormat( msgFmt1 , testArgs[i], 2, exp[i].unescape() ,(char*)
"From TestMessageFormat::testSelectFormat format t1"); | |
| 704 } | |
| 705 } | |
| 706 delete msgFmt1; | |
| 707 | |
| 708 //Quoted French Pattern | |
| 709 UnicodeString t2("{0} est {1, select, female {all\\u00E9e c''est} other {all
\\u00E9 c''est}} \\u00E0 Paris."); | |
| 710 err = U_ZERO_ERROR; | |
| 711 //Create the MessageFormat with Quoted French pattern | |
| 712 MessageFormat* msgFmt2 = internalCreate(t2.unescape(), Locale("fr"),err,(cha
r*)"From TestMessageFormat::TestSelectFormat create t2"); | |
| 713 if (!U_FAILURE(err)) { | |
| 714 //Arguments | |
| 715 Formattable testArgs10[] = {"Kirti","female"}; | |
| 716 Formattable testArgs11[] = {"Victor","other"}; | |
| 717 Formattable testArgs12[] = {"Ash","male"}; | |
| 718 Formattable* testArgs[] = {testArgs10,testArgs11,testArgs12}; | |
| 719 UnicodeString exp[] = { | |
| 720 "Kirti est all\\u00E9e c'est \\u00E0 Paris." , | |
| 721 "Victor est all\\u00E9 c'est \\u00E0 Paris.", | |
| 722 "Ash est all\\u00E9 c'est \\u00E0 Paris."}; | |
| 723 //Format | |
| 724 for( int i=0; i< 3; i++){ | |
| 725 internalFormat( msgFmt2 , testArgs[i], 2, exp[i].unescape() ,(char*)
"From TestMessageFormat::testSelectFormat format t2"); | |
| 726 } | |
| 727 } | |
| 728 delete msgFmt2; | |
| 729 | |
| 730 //English Pattern | |
| 731 UnicodeString t3("{0, select , male {MALE FR company} female {FEMALE FR comp
any} other {FR otherValue}} published new books."); | |
| 732 err = U_ZERO_ERROR; | |
| 733 //Create the MessageFormat with English pattern | |
| 734 MessageFormat* msgFmt3 = internalCreate(t3, Locale("en"),err,(char*)"From Te
stMessageFormat::TestSelectFormat create t3"); | |
| 735 if (!U_FAILURE(err)) { | |
| 736 //Arguments | |
| 737 Formattable testArgs10[] = {"female"}; | |
| 738 Formattable testArgs11[] = {"other"}; | |
| 739 Formattable testArgs12[] = {"male"}; | |
| 740 Formattable* testArgs[] = {testArgs10,testArgs11,testArgs12}; | |
| 741 UnicodeString exp[] = { | |
| 742 "FEMALE FR company published new books." , | |
| 743 "FR otherValue published new books.", | |
| 744 "MALE FR company published new books."}; | |
| 745 //Format | |
| 746 for( int i=0; i< 3; i++){ | |
| 747 internalFormat( msgFmt3 , testArgs[i], 1, exp[i] ,(char*)"From TestM
essageFormat::testSelectFormat format t3"); | |
| 748 } | |
| 749 } | |
| 750 delete msgFmt3; | |
| 751 | |
| 752 //Nested patterns with plural, number ,choice ,select format etc. | |
| 753 //Select Format with embedded number format | |
| 754 UnicodeString t4("{0} est {1, select, female {{2,number,integer} all\\u00E9e
} other {all\\u00E9}} \\u00E0 Paris."); | |
| 755 err = U_ZERO_ERROR; | |
| 756 //Create the MessageFormat with Select Format with embedded number format (n
ested pattern) | |
| 757 MessageFormat* msgFmt4 = internalCreate(t4.unescape(), Locale("fr"),err,(cha
r*)"From TestMessageFormat::TestSelectFormat create t4"); | |
| 758 if (!U_FAILURE(err)) { | |
| 759 //Arguments | |
| 760 Formattable testArgs10[] = {"Kirti","female",(int32_t)6}; | |
| 761 Formattable testArgs11[] = {"Kirti","female",100.100}; | |
| 762 Formattable testArgs12[] = {"Kirti","other",(int32_t)6}; | |
| 763 Formattable* testArgs[] = {testArgs10,testArgs11,testArgs12}; | |
| 764 UnicodeString exp[] = { | |
| 765 "Kirti est 6 all\\u00E9e \\u00E0 Paris." , | |
| 766 "Kirti est 100 all\\u00E9e \\u00E0 Paris.", | |
| 767 "Kirti est all\\u00E9 \\u00E0 Paris."}; | |
| 768 //Format | |
| 769 for( int i=0; i< 3; i++){ | |
| 770 internalFormat( msgFmt4 , testArgs[i], 3, exp[i].unescape() ,(char*)
"From TestMessageFormat::testSelectFormat format t4"); | |
| 771 } | |
| 772 } | |
| 773 delete msgFmt4; | |
| 774 | |
| 775 //Plural format with embedded select format | |
| 776 UnicodeString t5("{0} {1, plural, one {est {2, select, female {all\\u00E9e}
other {all\\u00E9}}} other {sont {2, select, female {all\\u00E9es} other {all\\u
00E9s}}}} \\u00E0 Paris."); | |
| 777 err = U_ZERO_ERROR; | |
| 778 //Create the MessageFormat with Plural format with embedded select format(ne
sted pattern) | |
| 779 MessageFormat* msgFmt5 = internalCreate(t5.unescape(), Locale("fr"),err,(cha
r*)"From TestMessageFormat::TestSelectFormat create t5"); | |
| 780 if (!U_FAILURE(err)) { | |
| 781 //Arguments | |
| 782 Formattable testArgs10[] = {"Kirti",(int32_t)6,"female"}; | |
| 783 Formattable testArgs11[] = {"Kirti",(int32_t)1,"female"}; | |
| 784 Formattable testArgs12[] = {"Ash",(int32_t)1,"other"}; | |
| 785 Formattable testArgs13[] = {"Ash",(int32_t)5,"other"}; | |
| 786 Formattable* testArgs[] = {testArgs10,testArgs11,testArgs12,testArgs13}; | |
| 787 UnicodeString exp[] = { | |
| 788 "Kirti sont all\\u00E9es \\u00E0 Paris." , | |
| 789 "Kirti est all\\u00E9e \\u00E0 Paris.", | |
| 790 "Ash est all\\u00E9 \\u00E0 Paris.", | |
| 791 "Ash sont all\\u00E9s \\u00E0 Paris."}; | |
| 792 //Format | |
| 793 for( int i=0; i< 4; i++){ | |
| 794 internalFormat( msgFmt5 , testArgs[i], 3, exp[i].unescape() ,(char*)
"From TestMessageFormat::testSelectFormat format t5"); | |
| 795 } | |
| 796 } | |
| 797 delete msgFmt5; | |
| 798 | |
| 799 err = U_ZERO_ERROR; | |
| 800 //Select, plural, and number formats heavily nested | |
| 801 UnicodeString t6("{0} und {1, select, female {{2, plural, one {{3, select, f
emale {ihre Freundin} other {ihr Freund}} } other {ihre {2, number, integer} {3,
select, female {Freundinnen} other {Freunde}} } }} other{{2, plural, one {{3, s
elect, female {seine Freundin} other {sein Freund}}} other {seine {2, number, in
teger} {3, select, female {Freundinnen} other {Freunde}}}}} } gingen nach Paris.
"); | |
| 802 //Create the MessageFormat with Select, plural, and number formats heavily n
ested | |
| 803 MessageFormat* msgFmt6 = internalCreate(t6, Locale("de"),err,(char*)"From Te
stMessageFormat::TestSelectFormat create t6"); | |
| 804 if (!U_FAILURE(err)) { | |
| 805 //Arguments | |
| 806 Formattable testArgs10[] = {"Kirti","other",(int32_t)1,"other"}; | |
| 807 Formattable testArgs11[] = {"Kirti","other",(int32_t)6,"other"}; | |
| 808 Formattable testArgs12[] = {"Kirti","other",(int32_t)1,"female"}; | |
| 809 Formattable testArgs13[] = {"Kirti","other",(int32_t)3,"female"}; | |
| 810 Formattable testArgs14[] = {"Kirti","female",(int32_t)1,"female"}; | |
| 811 Formattable testArgs15[] = {"Kirti","female",(int32_t)5,"female"}; | |
| 812 Formattable testArgs16[] = {"Kirti","female",(int32_t)1,"other"}; | |
| 813 Formattable testArgs17[] = {"Kirti","female",(int32_t)5,"other"}; | |
| 814 Formattable testArgs18[] = {"Kirti","mixed",(int32_t)1,"mixed"}; | |
| 815 Formattable testArgs19[] = {"Kirti","mixed",(int32_t)1,"other"}; | |
| 816 Formattable testArgs20[] = {"Kirti","female",(int32_t)1,"mixed"}; | |
| 817 Formattable testArgs21[] = {"Kirti","mixed",(int32_t)5,"mixed"}; | |
| 818 Formattable testArgs22[] = {"Kirti","mixed",(int32_t)5,"other"}; | |
| 819 Formattable testArgs23[] = {"Kirti","female",(int32_t)5,"mixed"}; | |
| 820 Formattable* testArgs[] = {testArgs10,testArgs11,testArgs12,testArgs13, | |
| 821 testArgs14,testArgs15,testArgs16,testArgs17, | |
| 822 testArgs18,testArgs19,testArgs20,testArgs21, | |
| 823 testArgs22,testArgs23 }; | |
| 824 UnicodeString exp[] = { | |
| 825 "Kirti und sein Freund gingen nach Paris." , | |
| 826 "Kirti und seine 6 Freunde gingen nach Paris." , | |
| 827 "Kirti und seine Freundin gingen nach Paris.", | |
| 828 "Kirti und seine 3 Freundinnen gingen nach Paris.", | |
| 829 "Kirti und ihre Freundin gingen nach Paris.", | |
| 830 "Kirti und ihre 5 Freundinnen gingen nach Paris.", | |
| 831 "Kirti und ihr Freund gingen nach Paris.", | |
| 832 "Kirti und ihre 5 Freunde gingen nach Paris.", | |
| 833 "Kirti und sein Freund gingen nach Paris.", | |
| 834 "Kirti und sein Freund gingen nach Paris.", | |
| 835 "Kirti und ihr Freund gingen nach Paris.", | |
| 836 "Kirti und seine 5 Freunde gingen nach Paris." , | |
| 837 "Kirti und seine 5 Freunde gingen nach Paris." , | |
| 838 "Kirti und ihre 5 Freunde gingen nach Paris." | |
| 839 }; | |
| 840 //Format | |
| 841 for( int i=0; i< 14; i++){ | |
| 842 internalFormat( msgFmt6 , testArgs[i], 4, exp[i] ,(char*)"From TestM
essageFormat::testSelectFormat format t6"); | |
| 843 } | |
| 844 } | |
| 845 delete msgFmt6; | |
| 846 } | |
| 847 | |
| 848 //--------------------------------- | |
| 849 // API Tests | |
| 850 //--------------------------------- | |
| 851 | |
| 852 void TestMessageFormat::testCopyConstructor() | |
| 853 { | |
| 854 UErrorCode success = U_ZERO_ERROR; | |
| 855 MessageFormat *x = new MessageFormat("There are {0} files on {1}", success); | |
| 856 MessageFormat *z = new MessageFormat("There are {0} files on {1} created", s
uccess); | |
| 857 MessageFormat *y = 0; | |
| 858 y = new MessageFormat(*x); | |
| 859 if ( (*x == *y) && | |
| 860 (*x != *z) && | |
| 861 (*y != *z) ) | |
| 862 logln("First test (operator ==): Passed!"); | |
| 863 else { | |
| 864 errln("TestMessageFormat::testCopyConstructor failed #1"); | |
| 865 logln("First test (operator ==): Failed!"); | |
| 866 } | |
| 867 if ( ((*x == *y) && (*y == *x)) && | |
| 868 ((*x != *z) && (*z != *x)) && | |
| 869 ((*y != *z) && (*z != *y)) ) | |
| 870 logln("Second test (equals): Passed!"); | |
| 871 else { | |
| 872 errln("TestMessageFormat::testCopyConstructor failed #2"); | |
| 873 logln("Second test (equals): Failed!"); | |
| 874 } | |
| 875 | |
| 876 delete x; | |
| 877 delete y; | |
| 878 delete z; | |
| 879 } | |
| 880 | |
| 881 | |
| 882 void TestMessageFormat::testAssignment() | |
| 883 { | |
| 884 UErrorCode success = U_ZERO_ERROR; | |
| 885 MessageFormat *x = new MessageFormat("There are {0} files on {1}", success); | |
| 886 MessageFormat *z = new MessageFormat("There are {0} files on {1} created", s
uccess); | |
| 887 MessageFormat *y = new MessageFormat("There are {0} files on {1} created", s
uccess); | |
| 888 *y = *x; | |
| 889 if ( (*x == *y) && | |
| 890 (*x != *z) && | |
| 891 (*y != *z) ) | |
| 892 logln("First test (operator ==): Passed!"); | |
| 893 else { | |
| 894 errln( "TestMessageFormat::testAssignment failed #1"); | |
| 895 logln("First test (operator ==): Failed!"); | |
| 896 } | |
| 897 if ( ((*x == *y) && (*y == *x)) && | |
| 898 ((*x != *z) && (*z != *x)) && | |
| 899 ((*y != *z) && (*z != *y)) ) | |
| 900 logln("Second test (equals): Passed!"); | |
| 901 else { | |
| 902 errln("TestMessageFormat::testAssignment failed #2"); | |
| 903 logln("Second test (equals): Failed!"); | |
| 904 } | |
| 905 | |
| 906 delete x; | |
| 907 delete y; | |
| 908 delete z; | |
| 909 } | |
| 910 | |
| 911 void TestMessageFormat::testClone() | |
| 912 { | |
| 913 UErrorCode success = U_ZERO_ERROR; | |
| 914 MessageFormat *x = new MessageFormat("There are {0} files on {1}", success); | |
| 915 MessageFormat *z = new MessageFormat("There are {0} files on {1} created", s
uccess); | |
| 916 MessageFormat *y = 0; | |
| 917 y = (MessageFormat*)x->clone(); | |
| 918 if ( (*x == *y) && | |
| 919 (*x != *z) && | |
| 920 (*y != *z) ) | |
| 921 logln("First test (operator ==): Passed!"); | |
| 922 else { | |
| 923 errln("TestMessageFormat::testClone failed #1"); | |
| 924 logln("First test (operator ==): Failed!"); | |
| 925 } | |
| 926 if ( ((*x == *y) && (*y == *x)) && | |
| 927 ((*x != *z) && (*z != *x)) && | |
| 928 ((*y != *z) && (*z != *y)) ) | |
| 929 logln("Second test (equals): Passed!"); | |
| 930 else { | |
| 931 errln("TestMessageFormat::testClone failed #2"); | |
| 932 logln("Second test (equals): Failed!"); | |
| 933 } | |
| 934 | |
| 935 delete x; | |
| 936 delete y; | |
| 937 delete z; | |
| 938 } | |
| 939 | |
| 940 void TestMessageFormat::testEquals() | |
| 941 { | |
| 942 UErrorCode success = U_ZERO_ERROR; | |
| 943 MessageFormat x("There are {0} files on {1}", success); | |
| 944 MessageFormat y("There are {0} files on {1}", success); | |
| 945 if (!(x == y)) { | |
| 946 errln( "TestMessageFormat::testEquals failed #1"); | |
| 947 logln("First test (operator ==): Failed!"); | |
| 948 } | |
| 949 | |
| 950 } | |
| 951 | |
| 952 void TestMessageFormat::testNotEquals() | |
| 953 { | |
| 954 UErrorCode success = U_ZERO_ERROR; | |
| 955 MessageFormat x("There are {0} files on {1}", success); | |
| 956 MessageFormat y(x); | |
| 957 y.setLocale(Locale("fr")); | |
| 958 if (!(x != y)) { | |
| 959 errln( "TestMessageFormat::testEquals failed #1"); | |
| 960 logln("First test (operator !=): Failed!"); | |
| 961 } | |
| 962 y = x; | |
| 963 y.applyPattern("There are {0} files on {1} the disk", success); | |
| 964 if (!(x != y)) { | |
| 965 errln( "TestMessageFormat::testEquals failed #1"); | |
| 966 logln("Second test (operator !=): Failed!"); | |
| 967 } | |
| 968 } | |
| 969 | |
| 970 | |
| 971 void TestMessageFormat::testSetLocale() | |
| 972 { | |
| 973 UErrorCode err = U_ZERO_ERROR; | |
| 974 GregorianCalendar cal(err); | |
| 975 Formattable arguments[] = { | |
| 976 456.83, | |
| 977 Formattable(UDate(8.71068e+011), Formattable::kIsDate), | |
| 978 "deposit" | |
| 979 }; | |
| 980 | |
| 981 UnicodeString result; | |
| 982 | |
| 983 //UnicodeString formatStr = "At {1,time} on {1,date}, you made a {2} of {0,n
umber,currency}."; | |
| 984 UnicodeString formatStr = "At <time> on {1,date}, you made a {2} of {0,numbe
r,currency}."; | |
| 985 // {sfb} to get $, would need Locale::US, not Locale::ENGLISH | |
| 986 // Just use unlocalized currency symbol. | |
| 987 //UnicodeString compareStrEng = "At <time> on Aug 8, 1997, you made a deposi
t of $456.83."; | |
| 988 UnicodeString compareStrEng = "At <time> on Aug 8, 1997, you made a deposit
of "; | |
| 989 compareStrEng += (UChar) 0x00a4; | |
| 990 compareStrEng += "456.83."; | |
| 991 // {sfb} to get DM, would need Locale::GERMANY, not Locale::GERMAN | |
| 992 // Just use unlocalized currency symbol. | |
| 993 //UnicodeString compareStrGer = "At <time> on 08.08.1997, you made a deposit
of 456,83 DM."; | |
| 994 UnicodeString compareStrGer = "At <time> on 08.08.1997, you made a deposit o
f "; | |
| 995 compareStrGer += "456,83"; | |
| 996 compareStrGer += (UChar) 0x00a0; | |
| 997 compareStrGer += (UChar) 0x00a4; | |
| 998 compareStrGer += "."; | |
| 999 | |
| 1000 MessageFormat msg( formatStr, err); | |
| 1001 result = ""; | |
| 1002 FieldPosition pos(0); | |
| 1003 result = msg.format( | |
| 1004 arguments, | |
| 1005 3, | |
| 1006 result, | |
| 1007 pos, | |
| 1008 err); | |
| 1009 | |
| 1010 logln(result); | |
| 1011 if (result != compareStrEng) { | |
| 1012 dataerrln("*** MSG format err. - %s", u_errorName(err)); | |
| 1013 } | |
| 1014 | |
| 1015 msg.setLocale(Locale::getEnglish()); | |
| 1016 UBool getLocale_ok = TRUE; | |
| 1017 if (msg.getLocale() != Locale::getEnglish()) { | |
| 1018 errln("*** MSG getLocal err."); | |
| 1019 getLocale_ok = FALSE; | |
| 1020 } | |
| 1021 | |
| 1022 msg.setLocale(Locale::getGerman()); | |
| 1023 | |
| 1024 if (msg.getLocale() != Locale::getGerman()) { | |
| 1025 errln("*** MSG getLocal err."); | |
| 1026 getLocale_ok = FALSE; | |
| 1027 } | |
| 1028 | |
| 1029 msg.applyPattern( formatStr, err); | |
| 1030 | |
| 1031 pos.setField(0); | |
| 1032 result = ""; | |
| 1033 result = msg.format( | |
| 1034 arguments, | |
| 1035 3, | |
| 1036 result, | |
| 1037 pos, | |
| 1038 err); | |
| 1039 | |
| 1040 logln(result); | |
| 1041 if (result == compareStrGer) { | |
| 1042 logln("MSG setLocale tested."); | |
| 1043 }else{ | |
| 1044 dataerrln( "*** MSG setLocale err. - %s", u_errorName(err)); | |
| 1045 } | |
| 1046 | |
| 1047 if (getLocale_ok) { | |
| 1048 logln("MSG getLocale tested."); | |
| 1049 } | |
| 1050 } | |
| 1051 | |
| 1052 void TestMessageFormat::testFormat() | |
| 1053 { | |
| 1054 UErrorCode err = U_ZERO_ERROR; | |
| 1055 GregorianCalendar cal(err); | |
| 1056 | |
| 1057 const Formattable ftarray[] = | |
| 1058 { | |
| 1059 Formattable( UDate(8.71068e+011), Formattable::kIsDate ) | |
| 1060 }; | |
| 1061 const int32_t ft_cnt = sizeof(ftarray) / sizeof(Formattable); | |
| 1062 Formattable ft_arr( ftarray, ft_cnt ); | |
| 1063 | |
| 1064 Formattable* fmt = new Formattable(UDate(8.71068e+011), Formattable::kIsDate
); | |
| 1065 | |
| 1066 UnicodeString result; | |
| 1067 | |
| 1068 //UnicodeString formatStr = "At {1,time} on {1,date}, you made a {2} of {0,n
umber,currency}."; | |
| 1069 UnicodeString formatStr = "On {0,date}, it began."; | |
| 1070 UnicodeString compareStr = "On Aug 8, 1997, it began."; | |
| 1071 | |
| 1072 err = U_ZERO_ERROR; | |
| 1073 MessageFormat msg( formatStr, err); | |
| 1074 FieldPosition fp(0); | |
| 1075 | |
| 1076 result = ""; | |
| 1077 fp = 0; | |
| 1078 result = msg.format( | |
| 1079 *fmt, | |
| 1080 result, | |
| 1081 //FieldPosition(0), | |
| 1082 fp, | |
| 1083 err); | |
| 1084 | |
| 1085 if (err != U_ILLEGAL_ARGUMENT_ERROR) { | |
| 1086 dataerrln("*** MSG format without expected error code. - %s", u_errorNam
e(err)); | |
| 1087 } | |
| 1088 err = U_ZERO_ERROR; | |
| 1089 | |
| 1090 result = ""; | |
| 1091 fp = 0; | |
| 1092 result = msg.format( | |
| 1093 ft_arr, | |
| 1094 result, | |
| 1095 //FieldPosition(0), | |
| 1096 fp, | |
| 1097 err); | |
| 1098 | |
| 1099 logln("MSG format( Formattable&, ... ) expected:" + compareStr); | |
| 1100 logln("MSG format( Formattable&, ... ) result:" + result); | |
| 1101 if (result != compareStr) { | |
| 1102 dataerrln("*** MSG format( Formattable&, .... ) err. - %s", u_errorName
(err)); | |
| 1103 }else{ | |
| 1104 logln("MSG format( Formattable&, ... ) tested."); | |
| 1105 } | |
| 1106 | |
| 1107 delete fmt; | |
| 1108 | |
| 1109 } | |
| 1110 | |
| 1111 void TestMessageFormat::testParse() | |
| 1112 { | |
| 1113 UErrorCode err = U_ZERO_ERROR; | |
| 1114 int32_t count; | |
| 1115 UnicodeString msgFormatString = "{0} =sep= {1}"; | |
| 1116 MessageFormat msg( msgFormatString, err); | |
| 1117 UnicodeString source = "abc =sep= def"; | |
| 1118 UnicodeString tmp1, tmp2; | |
| 1119 | |
| 1120 Formattable* fmt_arr = msg.parse( source, count, err ); | |
| 1121 if (U_FAILURE(err) || (!fmt_arr)) { | |
| 1122 errln("*** MSG parse (ustring, count, err) error."); | |
| 1123 }else{ | |
| 1124 logln("MSG parse -- count: %d", count); | |
| 1125 if (count != 2) { | |
| 1126 errln("*** MSG parse (ustring, count, err) count err."); | |
| 1127 }else{ | |
| 1128 if ((fmt_arr[0].getType() == Formattable::kString) | |
| 1129 && (fmt_arr[1].getType() == Formattable::kString) | |
| 1130 && (fmt_arr[0].getString(tmp1) == "abc") | |
| 1131 && (fmt_arr[1].getString(tmp2) == "def")) { | |
| 1132 logln("MSG parse (ustring, count, err) tested."); | |
| 1133 }else{ | |
| 1134 errln("*** MSG parse (ustring, count, err) result err."); | |
| 1135 } | |
| 1136 } | |
| 1137 } | |
| 1138 delete[] fmt_arr; | |
| 1139 | |
| 1140 ParsePosition pp(0); | |
| 1141 | |
| 1142 fmt_arr = msg.parse( source, pp, count ); | |
| 1143 if ((pp == 0) || (!fmt_arr)) { | |
| 1144 errln("*** MSG parse (ustring, parsepos., count) error."); | |
| 1145 }else{ | |
| 1146 logln("MSG parse -- count: %d", count); | |
| 1147 if (count != 2) { | |
| 1148 errln("*** MSG parse (ustring, parsepos., count) count err."); | |
| 1149 }else{ | |
| 1150 if ((fmt_arr[0].getType() == Formattable::kString) | |
| 1151 && (fmt_arr[1].getType() == Formattable::kString) | |
| 1152 && (fmt_arr[0].getString(tmp1) == "abc") | |
| 1153 && (fmt_arr[1].getString(tmp2) == "def")) { | |
| 1154 logln("MSG parse (ustring, parsepos., count) tested."); | |
| 1155 }else{ | |
| 1156 errln("*** MSG parse (ustring, parsepos., count) result err."); | |
| 1157 } | |
| 1158 } | |
| 1159 } | |
| 1160 delete[] fmt_arr; | |
| 1161 | |
| 1162 pp = 0; | |
| 1163 Formattable fmta; | |
| 1164 | |
| 1165 msg.parseObject( source, fmta, pp ); | |
| 1166 if (pp == 0) { | |
| 1167 errln("*** MSG parse (ustring, Formattable, parsepos ) error."); | |
| 1168 }else{ | |
| 1169 logln("MSG parse -- count: %d", count); | |
| 1170 fmta.getArray(count); | |
| 1171 if (count != 2) { | |
| 1172 errln("*** MSG parse (ustring, Formattable, parsepos ) count err."); | |
| 1173 }else{ | |
| 1174 if ((fmta[0].getType() == Formattable::kString) | |
| 1175 && (fmta[1].getType() == Formattable::kString) | |
| 1176 && (fmta[0].getString(tmp1) == "abc") | |
| 1177 && (fmta[1].getString(tmp2) == "def")) { | |
| 1178 logln("MSG parse (ustring, Formattable, parsepos ) tested."); | |
| 1179 }else{ | |
| 1180 errln("*** MSG parse (ustring, Formattable, parsepos ) result er
r."); | |
| 1181 } | |
| 1182 } | |
| 1183 } | |
| 1184 } | |
| 1185 | |
| 1186 | |
| 1187 void TestMessageFormat::testAdopt() | |
| 1188 { | |
| 1189 UErrorCode err = U_ZERO_ERROR; | |
| 1190 | |
| 1191 UnicodeString formatStr("{0,date},{1},{2,number}", ""); | |
| 1192 UnicodeString formatStrChange("{0,number},{1,number},{2,date}", ""); | |
| 1193 err = U_ZERO_ERROR; | |
| 1194 MessageFormat msg( formatStr, err); | |
| 1195 MessageFormat msgCmp( formatStr, err); | |
| 1196 if (U_FAILURE(err)) { | |
| 1197 dataerrln("Unable to instantiate MessageFormat - %s", u_errorName(err)); | |
| 1198 return; | |
| 1199 } | |
| 1200 int32_t count, countCmp; | |
| 1201 const Format** formats = msg.getFormats(count); | |
| 1202 const Format** formatsCmp = msgCmp.getFormats(countCmp); | |
| 1203 const Format** formatsChg = 0; | |
| 1204 const Format** formatsAct = 0; | |
| 1205 int32_t countAct; | |
| 1206 const Format* a; | |
| 1207 const Format* b; | |
| 1208 UnicodeString patCmp; | |
| 1209 UnicodeString patAct; | |
| 1210 Format** formatsToAdopt; | |
| 1211 | |
| 1212 if (!formats || !formatsCmp || (count <= 0) || (count != countCmp)) { | |
| 1213 dataerrln("Error getting Formats"); | |
| 1214 return; | |
| 1215 } | |
| 1216 | |
| 1217 int32_t i; | |
| 1218 | |
| 1219 for (i = 0; i < count; i++) { | |
| 1220 a = formats[i]; | |
| 1221 b = formatsCmp[i]; | |
| 1222 if ((a != NULL) && (b != NULL)) { | |
| 1223 if (*a != *b) { | |
| 1224 errln("a != b"); | |
| 1225 return; | |
| 1226 } | |
| 1227 }else if ((a != NULL) || (b != NULL)) { | |
| 1228 errln("(a != NULL) || (b != NULL)"); | |
| 1229 return; | |
| 1230 } | |
| 1231 } | |
| 1232 | |
| 1233 msg.applyPattern( formatStrChange, err ); //set msg formats to something dif
ferent | |
| 1234 int32_t countChg; | |
| 1235 formatsChg = msg.getFormats(countChg); // tested function | |
| 1236 if (!formatsChg || (countChg != count)) { | |
| 1237 errln("Error getting Formats"); | |
| 1238 return; | |
| 1239 } | |
| 1240 | |
| 1241 UBool diff; | |
| 1242 diff = TRUE; | |
| 1243 for (i = 0; i < count; i++) { | |
| 1244 a = formatsChg[i]; | |
| 1245 b = formatsCmp[i]; | |
| 1246 if ((a != NULL) && (b != NULL)) { | |
| 1247 if (*a == *b) { | |
| 1248 logln("formatsChg == formatsCmp at index %d", i); | |
| 1249 diff = FALSE; | |
| 1250 } | |
| 1251 } | |
| 1252 } | |
| 1253 if (!diff) { | |
| 1254 errln("*** MSG getFormats diff err."); | |
| 1255 return; | |
| 1256 } | |
| 1257 | |
| 1258 logln("MSG getFormats tested."); | |
| 1259 | |
| 1260 msg.setFormats( formatsCmp, countCmp ); //tested function | |
| 1261 | |
| 1262 formatsAct = msg.getFormats(countAct); | |
| 1263 if (!formatsAct || (countAct <=0) || (countAct != countCmp)) { | |
| 1264 errln("Error getting Formats"); | |
| 1265 return; | |
| 1266 } | |
| 1267 | |
| 1268 assertEquals("msgCmp.toPattern()", formatStr, msgCmp.toPattern(patCmp.remove
())); | |
| 1269 // ICU 4.8 does not support toPattern() when there are custom formats (from
setFormat() etc.). | |
| 1270 // assertEquals("msg.toPattern()", formatStr, msg.toPattern(patAct.remove())
); | |
| 1271 msg.toPattern(patCmp.remove()); | |
| 1272 if (!patCmp.isBogus()) { | |
| 1273 errln("msg.setFormat().toPattern() succeeds."); | |
| 1274 } | |
| 1275 | |
| 1276 for (i = 0; i < countAct; i++) { | |
| 1277 a = formatsAct[i]; | |
| 1278 b = formatsCmp[i]; | |
| 1279 if ((a != NULL) && (b != NULL)) { | |
| 1280 if (*a != *b) { | |
| 1281 logln("formatsAct != formatsCmp at index %d", i); | |
| 1282 errln("a != b"); | |
| 1283 return; | |
| 1284 } | |
| 1285 }else if ((a != NULL) || (b != NULL)) { | |
| 1286 errln("(a != NULL) || (b != NULL)"); | |
| 1287 return; | |
| 1288 } | |
| 1289 } | |
| 1290 logln("MSG setFormats tested."); | |
| 1291 | |
| 1292 //---- | |
| 1293 | |
| 1294 msg.applyPattern( formatStrChange, err ); //set msg formats to something dif
ferent | |
| 1295 | |
| 1296 formatsToAdopt = new Format* [countCmp]; | |
| 1297 if (!formatsToAdopt) { | |
| 1298 errln("memory allocation error"); | |
| 1299 return; | |
| 1300 } | |
| 1301 | |
| 1302 for (i = 0; i < countCmp; i++) { | |
| 1303 if (formatsCmp[i] == NULL) { | |
| 1304 formatsToAdopt[i] = NULL; | |
| 1305 }else{ | |
| 1306 formatsToAdopt[i] = formatsCmp[i]->clone(); | |
| 1307 if (!formatsToAdopt[i]) { | |
| 1308 errln("Can't clone format at index %d", i); | |
| 1309 return; | |
| 1310 } | |
| 1311 } | |
| 1312 } | |
| 1313 msg.adoptFormats( formatsToAdopt, countCmp ); // function to test | |
| 1314 delete[] formatsToAdopt; | |
| 1315 | |
| 1316 assertEquals("msgCmp.toPattern()", formatStr, msgCmp.toPattern(patCmp.remove
())); | |
| 1317 // ICU 4.8 does not support toPattern() when there are custom formats (from
setFormat() etc.). | |
| 1318 // assertEquals("msg.toPattern()", formatStr, msg.toPattern(patAct.remove())
); | |
| 1319 | |
| 1320 formatsAct = msg.getFormats(countAct); | |
| 1321 if (!formatsAct || (countAct <=0) || (countAct != countCmp)) { | |
| 1322 errln("Error getting Formats"); | |
| 1323 return; | |
| 1324 } | |
| 1325 | |
| 1326 for (i = 0; i < countAct; i++) { | |
| 1327 a = formatsAct[i]; | |
| 1328 b = formatsCmp[i]; | |
| 1329 if ((a != NULL) && (b != NULL)) { | |
| 1330 if (*a != *b) { | |
| 1331 errln("a != b"); | |
| 1332 return; | |
| 1333 } | |
| 1334 }else if ((a != NULL) || (b != NULL)) { | |
| 1335 errln("(a != NULL) || (b != NULL)"); | |
| 1336 return; | |
| 1337 } | |
| 1338 } | |
| 1339 logln("MSG adoptFormats tested."); | |
| 1340 | |
| 1341 //---- adoptFormat | |
| 1342 | |
| 1343 msg.applyPattern( formatStrChange, err ); //set msg formats to something dif
ferent | |
| 1344 | |
| 1345 formatsToAdopt = new Format* [countCmp]; | |
| 1346 if (!formatsToAdopt) { | |
| 1347 errln("memory allocation error"); | |
| 1348 return; | |
| 1349 } | |
| 1350 | |
| 1351 for (i = 0; i < countCmp; i++) { | |
| 1352 if (formatsCmp[i] == NULL) { | |
| 1353 formatsToAdopt[i] = NULL; | |
| 1354 }else{ | |
| 1355 formatsToAdopt[i] = formatsCmp[i]->clone(); | |
| 1356 if (!formatsToAdopt[i]) { | |
| 1357 errln("Can't clone format at index %d", i); | |
| 1358 return; | |
| 1359 } | |
| 1360 } | |
| 1361 } | |
| 1362 | |
| 1363 for ( i = 0; i < countCmp; i++ ) { | |
| 1364 msg.adoptFormat( i, formatsToAdopt[i] ); // function to test | |
| 1365 } | |
| 1366 delete[] formatsToAdopt; // array itself not needed in this case; | |
| 1367 | |
| 1368 assertEquals("msgCmp.toPattern()", formatStr, msgCmp.toPattern(patCmp.remove
())); | |
| 1369 // ICU 4.8 does not support toPattern() when there are custom formats (from
setFormat() etc.). | |
| 1370 // assertEquals("msg.toPattern()", formatStr, msg.toPattern(patAct.remove())
); | |
| 1371 | |
| 1372 formatsAct = msg.getFormats(countAct); | |
| 1373 if (!formatsAct || (countAct <=0) || (countAct != countCmp)) { | |
| 1374 errln("Error getting Formats"); | |
| 1375 return; | |
| 1376 } | |
| 1377 | |
| 1378 for (i = 0; i < countAct; i++) { | |
| 1379 a = formatsAct[i]; | |
| 1380 b = formatsCmp[i]; | |
| 1381 if ((a != NULL) && (b != NULL)) { | |
| 1382 if (*a != *b) { | |
| 1383 errln("a != b"); | |
| 1384 return; | |
| 1385 } | |
| 1386 }else if ((a != NULL) || (b != NULL)) { | |
| 1387 errln("(a != NULL) || (b != NULL)"); | |
| 1388 return; | |
| 1389 } | |
| 1390 } | |
| 1391 logln("MSG adoptFormat tested."); | |
| 1392 } | |
| 1393 | |
| 1394 // This test is a regression test for a fixed bug in the copy constructor. | |
| 1395 // It is kept as a global function rather than as a method since the test depend
s on memory values. | |
| 1396 // (At least before the bug was fixed, whether it showed up or not depended on m
emory contents, | |
| 1397 // which is probably why it didn't show up in the regular test for the copy cons
tructor.) | |
| 1398 // For this reason, the test isn't changed even though it contains function call
s whose results are | |
| 1399 // not tested and had no problems. Actually, the test failed by *crashing*. | |
| 1400 static void _testCopyConstructor2() | |
| 1401 { | |
| 1402 UErrorCode status = U_ZERO_ERROR; | |
| 1403 UnicodeString formatStr("Hello World on {0,date,full}", ""); | |
| 1404 UnicodeString resultStr(" ", ""); | |
| 1405 UnicodeString result; | |
| 1406 FieldPosition fp(0); | |
| 1407 UDate d = Calendar::getNow(); | |
| 1408 const Formattable fargs( d, Formattable::kIsDate ); | |
| 1409 | |
| 1410 MessageFormat* fmt1 = new MessageFormat( formatStr, status ); | |
| 1411 MessageFormat* fmt2 = NULL; | |
| 1412 MessageFormat* fmt3 = NULL; | |
| 1413 MessageFormat* fmt4 = NULL; | |
| 1414 | |
| 1415 if (fmt1 == NULL) { | |
| 1416 it_err("testCopyConstructor2: (fmt1 != NULL)"); | |
| 1417 goto cleanup; | |
| 1418 } | |
| 1419 | |
| 1420 fmt2 = new MessageFormat( *fmt1 ); | |
| 1421 result = fmt1->format( &fargs, 1, resultStr, fp, status ); | |
| 1422 | |
| 1423 if (fmt2 == NULL) { | |
| 1424 it_err("testCopyConstructor2: (fmt2 != NULL)"); | |
| 1425 goto cleanup; | |
| 1426 } | |
| 1427 | |
| 1428 fmt3 = (MessageFormat*) fmt1->clone(); | |
| 1429 fmt4 = (MessageFormat*) fmt2->clone(); | |
| 1430 | |
| 1431 if (fmt3 == NULL) { | |
| 1432 it_err("testCopyConstructor2: (fmt3 != NULL)"); | |
| 1433 goto cleanup; | |
| 1434 } | |
| 1435 if (fmt4 == NULL) { | |
| 1436 it_err("testCopyConstructor2: (fmt4 != NULL)"); | |
| 1437 goto cleanup; | |
| 1438 } | |
| 1439 | |
| 1440 result = fmt1->format( &fargs, 1, resultStr, fp, status ); | |
| 1441 result = fmt2->format( &fargs, 1, resultStr, fp, status ); | |
| 1442 result = fmt3->format( &fargs, 1, resultStr, fp, status ); | |
| 1443 result = fmt4->format( &fargs, 1, resultStr, fp, status ); | |
| 1444 | |
| 1445 cleanup: | |
| 1446 delete fmt1; | |
| 1447 delete fmt2; | |
| 1448 delete fmt3; | |
| 1449 delete fmt4; | |
| 1450 } | |
| 1451 | |
| 1452 void TestMessageFormat::testCopyConstructor2() { | |
| 1453 _testCopyConstructor2(); | |
| 1454 } | |
| 1455 | |
| 1456 /** | |
| 1457 * Verify that MessageFormat accomodates more than 10 arguments and | |
| 1458 * more than 10 subformats. | |
| 1459 */ | |
| 1460 void TestMessageFormat::TestUnlimitedArgsAndSubformats() { | |
| 1461 UErrorCode ec = U_ZERO_ERROR; | |
| 1462 const UnicodeString pattern = | |
| 1463 "On {0,date} (aka {0,date,short}, aka {0,date,long}) " | |
| 1464 "at {0,time} (aka {0,time,short}, aka {0,time,long}) " | |
| 1465 "there were {1,number} werjes " | |
| 1466 "(a {3,number,percent} increase over {2,number}) " | |
| 1467 "despite the {4}''s efforts " | |
| 1468 "and to delight of {5}, {6}, {7}, {8}, {9}, and {10} {11}."; | |
| 1469 MessageFormat msg(pattern, ec); | |
| 1470 if (U_FAILURE(ec)) { | |
| 1471 dataerrln("FAIL: constructor failed - %s", u_errorName(ec)); | |
| 1472 return; | |
| 1473 } | |
| 1474 | |
| 1475 const Formattable ARGS[] = { | |
| 1476 Formattable(UDate(1e13), Formattable::kIsDate), | |
| 1477 Formattable((int32_t)1303), | |
| 1478 Formattable((int32_t)1202), | |
| 1479 Formattable(1303.0/1202 - 1), | |
| 1480 Formattable("Glimmung"), | |
| 1481 Formattable("the printers"), | |
| 1482 Formattable("Nick"), | |
| 1483 Formattable("his father"), | |
| 1484 Formattable("his mother"), | |
| 1485 Formattable("the spiddles"), | |
| 1486 Formattable("of course"), | |
| 1487 Formattable("Horace"), | |
| 1488 }; | |
| 1489 const int32_t ARGS_LENGTH = sizeof(ARGS) / sizeof(ARGS[0]); | |
| 1490 Formattable ARGS_OBJ(ARGS, ARGS_LENGTH); | |
| 1491 | |
| 1492 UnicodeString expected = | |
| 1493 "On Nov 20, 2286 (aka 11/20/86, aka November 20, 2286) " | |
| 1494 "at 9:46:40 AM (aka 9:46 AM, aka 9:46:40 AM PST) " | |
| 1495 "there were 1,303 werjes " | |
| 1496 "(a 8% increase over 1,202) " | |
| 1497 "despite the Glimmung's efforts " | |
| 1498 "and to delight of the printers, Nick, his father, " | |
| 1499 "his mother, the spiddles, and of course Horace."; | |
| 1500 UnicodeString result; | |
| 1501 msg.format(ARGS_OBJ, result, ec); | |
| 1502 if (result == expected) { | |
| 1503 logln(result); | |
| 1504 } else { | |
| 1505 errln((UnicodeString)"FAIL: Got " + result + | |
| 1506 ", expected " + expected); | |
| 1507 } | |
| 1508 } | |
| 1509 | |
| 1510 // test RBNF extensions to message format | |
| 1511 void TestMessageFormat::TestRBNF(void) { | |
| 1512 // WARNING: this depends on the RBNF formats for en_US | |
| 1513 Locale locale("en", "US", ""); | |
| 1514 | |
| 1515 UErrorCode ec = U_ZERO_ERROR; | |
| 1516 | |
| 1517 UnicodeString values[] = { | |
| 1518 // decimal values do not format completely for ordinal or duration, and | |
| 1519 // do not always parse, so do not include them | |
| 1520 "0", "1", "12", "100", "123", "1001", "123,456", "-17", | |
| 1521 }; | |
| 1522 int32_t values_count = sizeof(values)/sizeof(values[0]); | |
| 1523 | |
| 1524 UnicodeString formats[] = { | |
| 1525 "There are {0,spellout} files to search.", | |
| 1526 "There are {0,spellout,%simplified} files to search.", | |
| 1527 "The bogus spellout {0,spellout,%BOGUS} files behaves like the default."
, | |
| 1528 "This is the {0,ordinal} file to search.", | |
| 1529 "Searching this file will take {0,duration} to complete.", | |
| 1530 "Searching this file will take {0,duration,%with-words} to complete.", | |
| 1531 }; | |
| 1532 int32_t formats_count = sizeof(formats)/sizeof(formats[0]); | |
| 1533 | |
| 1534 Formattable args[1]; | |
| 1535 | |
| 1536 NumberFormat* numFmt = NumberFormat::createInstance(locale, ec); | |
| 1537 if (U_FAILURE(ec)) { | |
| 1538 dataerrln("Error calling NumberFormat::createInstance()"); | |
| 1539 return; | |
| 1540 } | |
| 1541 | |
| 1542 for (int i = 0; i < formats_count; ++i) { | |
| 1543 MessageFormat* fmt = new MessageFormat(formats[i], locale, ec); | |
| 1544 logln((UnicodeString)"Testing format pattern: '" + formats[i] + "'"); | |
| 1545 | |
| 1546 for (int j = 0; j < values_count; ++j) { | |
| 1547 ec = U_ZERO_ERROR; | |
| 1548 numFmt->parse(values[j], args[0], ec); | |
| 1549 if (U_FAILURE(ec)) { | |
| 1550 errln((UnicodeString)"Failed to parse test argument " + values[j
]); | |
| 1551 } else { | |
| 1552 FieldPosition fp(0); | |
| 1553 UnicodeString result; | |
| 1554 fmt->format(args, 1, result, fp, ec); | |
| 1555 logln((UnicodeString)"value: " + toString(args[0]) + " --> " + r
esult + UnicodeString(" ec: ") + u_errorName(ec)); | |
| 1556 | |
| 1557 int32_t count = 0; | |
| 1558 Formattable* parseResult = fmt->parse(result, count, ec); | |
| 1559 if (count != 1) { | |
| 1560 errln((UnicodeString)"parse returned " + count + " args"); | |
| 1561 } else if (parseResult[0] != args[0]) { | |
| 1562 errln((UnicodeString)"parsed argument " + toString(parseResu
lt[0]) + " != " + toString(args[0])); | |
| 1563 } | |
| 1564 delete []parseResult; | |
| 1565 } | |
| 1566 } | |
| 1567 delete fmt; | |
| 1568 } | |
| 1569 delete numFmt; | |
| 1570 } | |
| 1571 | |
| 1572 UnicodeString TestMessageFormat::GetPatternAndSkipSyntax(const MessagePattern& p
attern) { | |
| 1573 UnicodeString us(pattern.getPatternString()); | |
| 1574 int count = pattern.countParts(); | |
| 1575 for (int i = count; i > 0;) { | |
| 1576 const MessagePattern::Part& part = pattern.getPart(--i); | |
| 1577 if (part.getType() == UMSGPAT_PART_TYPE_SKIP_SYNTAX) { | |
| 1578 us.remove(part.getIndex(), part.getLimit() - part.getIndex()); | |
| 1579 } | |
| 1580 } | |
| 1581 return us; | |
| 1582 } | |
| 1583 | |
| 1584 void TestMessageFormat::TestApostropheMode() { | |
| 1585 UErrorCode status = U_ZERO_ERROR; | |
| 1586 MessagePattern *ado_mp = new MessagePattern(UMSGPAT_APOS_DOUBLE_OPTIONAL, st
atus); | |
| 1587 MessagePattern *adr_mp = new MessagePattern(UMSGPAT_APOS_DOUBLE_REQUIRED, st
atus); | |
| 1588 if (ado_mp->getApostropheMode() != UMSGPAT_APOS_DOUBLE_OPTIONAL) { | |
| 1589 errln("wrong value from ado_mp->getApostropheMode()."); | |
| 1590 } | |
| 1591 if (adr_mp->getApostropheMode() != UMSGPAT_APOS_DOUBLE_REQUIRED) { | |
| 1592 errln("wrong value from adr_mp->getApostropheMode()."); | |
| 1593 } | |
| 1594 | |
| 1595 | |
| 1596 UnicodeString tuples[] = { | |
| 1597 // Desired output | |
| 1598 // DOUBLE_OPTIONAL pattern | |
| 1599 // DOUBLE_REQUIRED pattern (empty=same as DOUBLE_OPTIONAL) | |
| 1600 "I see {many}", "I see '{many}'", "", | |
| 1601 "I said {'Wow!'}", "I said '{''Wow!''}'", "", | |
| 1602 "I dont know", "I dont know", "I don't know", | |
| 1603 "I don't know", "I don't know", "I don''t know", | |
| 1604 "I don't know", "I don''t know", "I don''t know" | |
| 1605 }; | |
| 1606 int32_t tuples_count = UPRV_LENGTHOF(tuples); | |
| 1607 | |
| 1608 for (int i = 0; i < tuples_count; i += 3) { | |
| 1609 UnicodeString& desired = tuples[i]; | |
| 1610 UnicodeString& ado_pattern = tuples[i + 1]; | |
| 1611 UErrorCode status = U_ZERO_ERROR; | |
| 1612 assertEquals("DOUBLE_OPTIONAL failure", | |
| 1613 desired, | |
| 1614 GetPatternAndSkipSyntax(ado_mp->parse(ado_pattern, NULL, stat
us))); | |
| 1615 UnicodeString& adr_pattern = tuples[i + 2].isEmpty() ? ado_pattern : tuple
s[i + 2]; | |
| 1616 assertEquals("DOUBLE_REQUIRED failure", desired, | |
| 1617 GetPatternAndSkipSyntax(adr_mp->parse(adr_pattern, NULL, status))); | |
| 1618 } | |
| 1619 delete adr_mp; | |
| 1620 delete ado_mp; | |
| 1621 } | |
| 1622 | |
| 1623 | |
| 1624 // Compare behavior of DOUBLE_OPTIONAL (new default) and DOUBLE_REQUIRED JDK-com
patibility mode. | |
| 1625 void TestMessageFormat::TestCompatibleApostrophe() { | |
| 1626 // Message with choice argument which does not contain another argument. | |
| 1627 // The JDK performs only one apostrophe-quoting pass on this pattern. | |
| 1628 UnicodeString pattern = "ab{0,choice,0#1'2''3'''4''''.}yz"; | |
| 1629 | |
| 1630 UErrorCode ec = U_ZERO_ERROR; | |
| 1631 MessageFormat compMsg("", Locale::getUS(), ec); | |
| 1632 compMsg.applyPattern(pattern, UMSGPAT_APOS_DOUBLE_REQUIRED, NULL, ec); | |
| 1633 if (compMsg.getApostropheMode() != UMSGPAT_APOS_DOUBLE_REQUIRED) { | |
| 1634 errln("wrong value from compMsg.getApostropheMode()."); | |
| 1635 } | |
| 1636 | |
| 1637 MessageFormat icuMsg("", Locale::getUS(), ec); | |
| 1638 icuMsg.applyPattern(pattern, UMSGPAT_APOS_DOUBLE_OPTIONAL, NULL, ec); | |
| 1639 if (icuMsg.getApostropheMode() != UMSGPAT_APOS_DOUBLE_OPTIONAL) { | |
| 1640 errln("wrong value from icuMsg.getApostropheMode()."); | |
| 1641 } | |
| 1642 | |
| 1643 Formattable zero0[] = { (int32_t)0 }; | |
| 1644 FieldPosition fieldpos(0); | |
| 1645 UnicodeString buffer1, buffer2; | |
| 1646 assertEquals("incompatible ICU MessageFormat compatibility-apostrophe behavi
or", | |
| 1647 "ab12'3'4''.yz", | |
| 1648 compMsg.format(zero0, 1, buffer1, fieldpos, ec)); | |
| 1649 assertEquals("unexpected ICU MessageFormat double-apostrophe-optional behavi
or", | |
| 1650 "ab1'2'3''4''.yz", | |
| 1651 icuMsg.format(zero0, 1, buffer2, fieldpos, ec)); | |
| 1652 | |
| 1653 // Message with choice argument which contains a nested simple argument. | |
| 1654 // The DOUBLE_REQUIRED version performs two apostrophe-quoting passes. | |
| 1655 buffer1.remove(); | |
| 1656 buffer2.remove(); | |
| 1657 pattern = "ab{0,choice,0#1'2''3'''4''''.{0,number,'#x'}}yz"; | |
| 1658 compMsg.applyPattern(pattern, ec); | |
| 1659 icuMsg.applyPattern(pattern, ec); | |
| 1660 if (U_FAILURE(ec)) { | |
| 1661 dataerrln("Unable to applyPattern - %s", u_errorName(ec)); | |
| 1662 } else { | |
| 1663 assertEquals("incompatible ICU MessageFormat compatibility-apostrophe be
havior", | |
| 1664 "ab1234'.0xyz", | |
| 1665 compMsg.format(zero0, 1, buffer1, fieldpos, ec)); | |
| 1666 assertEquals("unexpected ICU MessageFormat double-apostrophe-optional be
havior", | |
| 1667 "ab1'2'3''4''.#x0yz", | |
| 1668 icuMsg.format(zero0, 1, buffer2, fieldpos, ec)); | |
| 1669 } | |
| 1670 | |
| 1671 // This part is copied over from Java tests but cannot be properly tested he
re | |
| 1672 // because we do not have a live reference implementation with JDK behavior. | |
| 1673 // The JDK ChoiceFormat itself always performs one apostrophe-quoting pass. | |
| 1674 /* | |
| 1675 ChoiceFormat choice = new ChoiceFormat("0#1'2''3'''4''''."); | |
| 1676 assertEquals("unexpected JDK ChoiceFormat apostrophe behavior", | |
| 1677 "12'3'4''.", | |
| 1678 choice.format(0)); | |
| 1679 choice.applyPattern("0#1'2''3'''4''''.{0,number,'#x'}"); | |
| 1680 assertEquals("unexpected JDK ChoiceFormat apostrophe behavior", | |
| 1681 "12'3'4''.{0,number,#x}", | |
| 1682 choice.format(0)); | |
| 1683 */ | |
| 1684 } | |
| 1685 | |
| 1686 void TestMessageFormat::testAutoQuoteApostrophe(void) { | |
| 1687 const char* patterns[] = { // pattern, expected pattern | |
| 1688 "'", "''", | |
| 1689 "''", "''", | |
| 1690 "'{", "'{'", | |
| 1691 "' {", "'' {", | |
| 1692 "'a", "''a", | |
| 1693 "'{'a", "'{'a", | |
| 1694 "'{a'", "'{a'", | |
| 1695 "'{}", "'{}'", | |
| 1696 "{'", "{'", | |
| 1697 "{'a", "{'a", | |
| 1698 "{'a{}'a}'a", "{'a{}'a}''a", | |
| 1699 "'}'", "'}'", | |
| 1700 "'} '{'}'", "'} '{'}''", | |
| 1701 "'} {{{''", "'} {{{'''", | |
| 1702 }; | |
| 1703 int32_t pattern_count = sizeof(patterns)/sizeof(patterns[0]); | |
| 1704 | |
| 1705 for (int i = 0; i < pattern_count; i += 2) { | |
| 1706 UErrorCode status = U_ZERO_ERROR; | |
| 1707 UnicodeString result = MessageFormat::autoQuoteApostrophe(patterns[i], s
tatus); | |
| 1708 UnicodeString target(patterns[i+1]); | |
| 1709 if (target != result) { | |
| 1710 const int BUF2_LEN = 64; | |
| 1711 char buf[256]; | |
| 1712 char buf2[BUF2_LEN]; | |
| 1713 int32_t len = result.extract(0, result.length(), buf2, BUF2_LEN); | |
| 1714 if (len >= BUF2_LEN) { | |
| 1715 buf2[BUF2_LEN-1] = 0; | |
| 1716 } | |
| 1717 sprintf(buf, "[%2d] test \"%s\": target (\"%s\") != result (\"%s\")\
n", i/2, patterns[i], patterns[i+1], buf2); | |
| 1718 errln(buf); | |
| 1719 } | |
| 1720 } | |
| 1721 } | |
| 1722 | |
| 1723 void TestMessageFormat::testCoverage(void) { | |
| 1724 UErrorCode status = U_ZERO_ERROR; | |
| 1725 UnicodeString testformat("{argument, plural, one{C''est # fichier} other {Ce
sont # fichiers}} dans la liste."); | |
| 1726 MessageFormat *msgfmt = new MessageFormat(testformat, Locale("fr"), status); | |
| 1727 if (msgfmt == NULL || U_FAILURE(status)) { | |
| 1728 dataerrln("FAIL: Unable to create MessageFormat.: %s", u_errorName(statu
s)); | |
| 1729 return; | |
| 1730 } | |
| 1731 if (!msgfmt->usesNamedArguments()) { | |
| 1732 errln("FAIL: Unable to detect usage of named arguments."); | |
| 1733 } | |
| 1734 const double limit[] = {0.0, 1.0, 2.0}; | |
| 1735 const UnicodeString formats[] = {"0.0<=Arg<1.0", | |
| 1736 "1.0<=Arg<2.0", | |
| 1737 "2.0<-Arg"}; | |
| 1738 ChoiceFormat cf(limit, formats, 3); | |
| 1739 | |
| 1740 msgfmt->setFormat("set", cf, status); | |
| 1741 | |
| 1742 StringEnumeration *en = msgfmt->getFormatNames(status); | |
| 1743 if (en == NULL || U_FAILURE(status)) { | |
| 1744 errln("FAIL: Unable to get format names enumeration."); | |
| 1745 } else { | |
| 1746 int32_t count = 0; | |
| 1747 en->reset(status); | |
| 1748 count = en->count(status); | |
| 1749 if (U_FAILURE(status)) { | |
| 1750 errln("FAIL: Unable to get format name enumeration count."); | |
| 1751 } else { | |
| 1752 for (int32_t i = 0; i < count; i++) { | |
| 1753 en->snext(status); | |
| 1754 if (U_FAILURE(status)) { | |
| 1755 errln("FAIL: Error enumerating through names."); | |
| 1756 break; | |
| 1757 } | |
| 1758 } | |
| 1759 } | |
| 1760 } | |
| 1761 | |
| 1762 // adoptFormat() takes ownership of the input Format object. | |
| 1763 // We need to clone the stack-allocated cf so that we do not attempt to dele
te cf. | |
| 1764 Format *cfClone = cf.clone(); | |
| 1765 msgfmt->adoptFormat("adopt", cfClone, status); | |
| 1766 | |
| 1767 delete en; | |
| 1768 delete msgfmt; | |
| 1769 | |
| 1770 msgfmt = new MessageFormat("'", status); | |
| 1771 if (msgfmt == NULL || U_FAILURE(status)) { | |
| 1772 errln("FAIL: Unable to create MessageFormat."); | |
| 1773 return; | |
| 1774 } | |
| 1775 if (msgfmt->usesNamedArguments()) { | |
| 1776 errln("FAIL: Unable to detect usage of named arguments."); | |
| 1777 } | |
| 1778 | |
| 1779 // Starting with ICU 4.8, we support setFormat(name, ...) and getFormatNames
() | |
| 1780 // on a MessageFormat without named arguments. | |
| 1781 msgfmt->setFormat("formatName", cf, status); | |
| 1782 if (U_FAILURE(status)) { | |
| 1783 errln("FAIL: Should work to setFormat(name, ...) regardless of pattern."
); | |
| 1784 } | |
| 1785 status = U_ZERO_ERROR; | |
| 1786 en = msgfmt->getFormatNames(status); | |
| 1787 if (U_FAILURE(status)) { | |
| 1788 errln("FAIL: Should work to get format names enumeration regardless of p
attern."); | |
| 1789 } | |
| 1790 | |
| 1791 delete en; | |
| 1792 delete msgfmt; | |
| 1793 } | |
| 1794 | |
| 1795 void TestMessageFormat::testGetFormatNames() { | |
| 1796 IcuTestErrorCode errorCode(*this, "testGetFormatNames"); | |
| 1797 MessageFormat msgfmt("Hello, {alice,number} {oops,date,full} {zip,spellout}
World.", Locale::getRoot(), errorCode); | |
| 1798 if(errorCode.logDataIfFailureAndReset("MessageFormat() failed")) { | |
| 1799 return; | |
| 1800 } | |
| 1801 LocalPointer<StringEnumeration> names(msgfmt.getFormatNames(errorCode)); | |
| 1802 if(errorCode.logIfFailureAndReset("msgfmt.getFormatNames() failed")) { | |
| 1803 return; | |
| 1804 } | |
| 1805 const UnicodeString *name; | |
| 1806 name = names->snext(errorCode); | |
| 1807 if (name == NULL || errorCode.isFailure()) { | |
| 1808 errln("msgfmt.getFormatNames()[0] failed: %s", errorCode.errorName()); | |
| 1809 errorCode.reset(); | |
| 1810 return; | |
| 1811 } | |
| 1812 if (!assertEquals("msgfmt.getFormatNames()[0]", UNICODE_STRING_SIMPLE("alice
"), *name)) { | |
| 1813 return; | |
| 1814 } | |
| 1815 name = names->snext(errorCode); | |
| 1816 if (name == NULL || errorCode.isFailure()) { | |
| 1817 errln("msgfmt.getFormatNames()[1] failed: %s", errorCode.errorName()); | |
| 1818 errorCode.reset(); | |
| 1819 return; | |
| 1820 } | |
| 1821 if (!assertEquals("msgfmt.getFormatNames()[1]", UNICODE_STRING_SIMPLE("oops"
), *name)) { | |
| 1822 return; | |
| 1823 } | |
| 1824 name = names->snext(errorCode); | |
| 1825 if (name == NULL || errorCode.isFailure()) { | |
| 1826 errln("msgfmt.getFormatNames()[2] failed: %s", errorCode.errorName()); | |
| 1827 errorCode.reset(); | |
| 1828 return; | |
| 1829 } | |
| 1830 if (!assertEquals("msgfmt.getFormatNames()[2]", UNICODE_STRING_SIMPLE("zip")
, *name)) { | |
| 1831 return; | |
| 1832 } | |
| 1833 name = names->snext(errorCode); | |
| 1834 if (name != NULL) { | |
| 1835 errln(UnicodeString("msgfmt.getFormatNames()[3] should be NULL but is: "
) + *name); | |
| 1836 return; | |
| 1837 } | |
| 1838 } | |
| 1839 | |
| 1840 void TestMessageFormat::TestTrimArgumentName() { | |
| 1841 // ICU 4.8 allows and ignores white space around argument names and numbers. | |
| 1842 IcuTestErrorCode errorCode(*this, "TestTrimArgumentName"); | |
| 1843 MessageFormat m("a { 0 , number , '#,#'#.0 } z", Locale::getEnglish(), error
Code); | |
| 1844 if (errorCode.logDataIfFailureAndReset("Unable to instantiate MessageFormat"
)) { | |
| 1845 return; | |
| 1846 } | |
| 1847 Formattable args[1] = { (int32_t)2 }; | |
| 1848 FieldPosition ignore(0); | |
| 1849 UnicodeString result; | |
| 1850 assertEquals("trim-numbered-arg format() failed", "a #,#2.0 z", | |
| 1851 m.format(args, 1, result, ignore, errorCode)); | |
| 1852 | |
| 1853 m.applyPattern("x { _oOo_ , number , integer } y", errorCode); | |
| 1854 UnicodeString argName = UNICODE_STRING_SIMPLE("_oOo_"); | |
| 1855 args[0].setLong(3); | |
| 1856 result.remove(); | |
| 1857 assertEquals("trim-named-arg format() failed", "x 3 y", | |
| 1858 m.format(&argName, args, 1, result, errorCode)); | |
| 1859 } | |
| 1860 | |
| 1861 void TestMessageFormat::TestSelectOrdinal() { | |
| 1862 IcuTestErrorCode errorCode(*this, "TestSelectOrdinal"); | |
| 1863 // Test plural & ordinal together, | |
| 1864 // to make sure that we get the correct cached PluralSelector for each. | |
| 1865 MessageFormat m( | |
| 1866 "{0,plural,one{1 file}other{# files}}, " | |
| 1867 "{0,selectordinal,one{#st file}two{#nd file}few{#rd file}other{#th file}
}", | |
| 1868 Locale::getEnglish(), errorCode); | |
| 1869 if (errorCode.logDataIfFailureAndReset("Unable to instantiate MessageFormat"
)) { | |
| 1870 return; | |
| 1871 } | |
| 1872 Formattable args[1] = { (int32_t)21 }; | |
| 1873 FieldPosition ignore(0); | |
| 1874 UnicodeString result; | |
| 1875 assertEquals("plural-and-ordinal format(21) failed", "21 files, 21st file", | |
| 1876 m.format(args, 1, result, ignore, errorCode), TRUE); | |
| 1877 | |
| 1878 args[0].setLong(2); | |
| 1879 assertEquals("plural-and-ordinal format(2) failed", "2 files, 2nd file", | |
| 1880 m.format(args, 1, result.remove(), ignore, errorCode), TRUE); | |
| 1881 | |
| 1882 args[0].setLong(1); | |
| 1883 assertEquals("plural-and-ordinal format(1) failed", "1 file, 1st file", | |
| 1884 m.format(args, 1, result.remove(), ignore, errorCode), TRUE); | |
| 1885 | |
| 1886 args[0].setLong(3); | |
| 1887 assertEquals("plural-and-ordinal format(3) failed", "3 files, 3rd file", | |
| 1888 m.format(args, 1, result.remove(), ignore, errorCode), TRUE); | |
| 1889 | |
| 1890 errorCode.logDataIfFailureAndReset(""); | |
| 1891 } | |
| 1892 | |
| 1893 void TestMessageFormat::TestDecimals() { | |
| 1894 IcuTestErrorCode errorCode(*this, "TestDecimals"); | |
| 1895 // Simple number replacement. | |
| 1896 MessageFormat m( | |
| 1897 "{0,plural,one{one meter}other{# meters}}", | |
| 1898 Locale::getEnglish(), errorCode); | |
| 1899 Formattable args[1] = { (int32_t)1 }; | |
| 1900 FieldPosition ignore; | |
| 1901 UnicodeString result; | |
| 1902 assertEquals("simple format(1)", "one meter", | |
| 1903 m.format(args, 1, result, ignore, errorCode), TRUE); | |
| 1904 | |
| 1905 args[0] = (double)1.5; | |
| 1906 result.remove(); | |
| 1907 assertEquals("simple format(1.5)", "1.5 meters", | |
| 1908 m.format(args, 1, result, ignore, errorCode), TRUE); | |
| 1909 | |
| 1910 // Simple but explicit. | |
| 1911 MessageFormat m0( | |
| 1912 "{0,plural,one{one meter}other{{0} meters}}", | |
| 1913 Locale::getEnglish(), errorCode); | |
| 1914 args[0] = (int32_t)1; | |
| 1915 result.remove(); | |
| 1916 assertEquals("explicit format(1)", "one meter", | |
| 1917 m0.format(args, 1, result, ignore, errorCode), TRUE); | |
| 1918 | |
| 1919 args[0] = (double)1.5; | |
| 1920 result.remove(); | |
| 1921 assertEquals("explicit format(1.5)", "1.5 meters", | |
| 1922 m0.format(args, 1, result, ignore, errorCode), TRUE); | |
| 1923 | |
| 1924 // With offset and specific simple format with optional decimals. | |
| 1925 MessageFormat m1( | |
| 1926 "{0,plural,offset:1 one{another meter}other{{0,number,00.#} meters}}
", | |
| 1927 Locale::getEnglish(), errorCode); | |
| 1928 args[0] = (int32_t)1; | |
| 1929 result.remove(); | |
| 1930 assertEquals("offset format(1)", "01 meters", | |
| 1931 m1.format(args, 1, result, ignore, errorCode), TRUE); | |
| 1932 | |
| 1933 args[0] = (int32_t)2; | |
| 1934 result.remove(); | |
| 1935 assertEquals("offset format(1)", "another meter", | |
| 1936 m1.format(args, 1, result, ignore, errorCode), TRUE); | |
| 1937 | |
| 1938 args[0] = (double)2.5; | |
| 1939 result.remove(); | |
| 1940 assertEquals("offset format(1)", "02.5 meters", | |
| 1941 m1.format(args, 1, result, ignore, errorCode), TRUE); | |
| 1942 | |
| 1943 // With offset and specific simple format with forced decimals. | |
| 1944 MessageFormat m2( | |
| 1945 "{0,plural,offset:1 one{another meter}other{{0,number,0.0} meters}}"
, | |
| 1946 Locale::getEnglish(), errorCode); | |
| 1947 args[0] = (int32_t)1; | |
| 1948 result.remove(); | |
| 1949 assertEquals("offset-decimals format(1)", "1.0 meters", | |
| 1950 m2.format(args, 1, result, ignore, errorCode), TRUE); | |
| 1951 | |
| 1952 args[0] = (int32_t)2; | |
| 1953 result.remove(); | |
| 1954 assertEquals("offset-decimals format(1)", "2.0 meters", | |
| 1955 m2.format(args, 1, result, ignore, errorCode), TRUE); | |
| 1956 | |
| 1957 args[0] = (double)2.5; | |
| 1958 result.remove(); | |
| 1959 assertEquals("offset-decimals format(1)", "2.5 meters", | |
| 1960 m2.format(args, 1, result, ignore, errorCode), TRUE); | |
| 1961 errorCode.reset(); | |
| 1962 } | |
| 1963 | |
| 1964 #endif /* #if !UCONFIG_NO_FORMATTING */ | |
| OLD | NEW |