1 /*********************************************************************** 2 * Copyright (c) 1997-2013, International Business Machines Corporation 3 * and others. All Rights Reserved. 4 ***********************************************************************/ 5 6 #include "unicode/utypes.h" 7 8 #if !UCONFIG_NO_FORMATTING 9 10 #include "numrgts.h" 11 12 #include <float.h> // DBL_MIN, DBL_MAX 13 #include <stdio.h> 14 15 #include "unicode/dcfmtsym.h" 16 #include "unicode/decimfmt.h" 17 #include "unicode/locid.h" 18 #include "unicode/resbund.h" 19 #include "unicode/calendar.h" 20 #include "unicode/datefmt.h" 21 #include "unicode/ucurr.h" 22 #include "putilimp.h" 23 24 class MyNumberFormatTest : public NumberFormat 25 { 26 public: 27 28 virtual UClassID getDynamicClassID(void) const; 29 30 virtual UnicodeString& format( double number, 31 UnicodeString& toAppendTo, 32 FieldPositionIterator* posIter, 33 UErrorCode& status) const 34 { 35 return NumberFormat::format(number, toAppendTo, posIter, status); 36 } 37 38 /* Just keep this here to make some of the compilers happy */ 39 virtual UnicodeString& format(const Formattable& obj, 40 UnicodeString& toAppendTo, 41 FieldPosition& pos, 42 UErrorCode& status) const 43 { 44 return NumberFormat::format(obj, toAppendTo, pos, status); 45 } 46 47 /* Just use one of the format functions */ 48 virtual UnicodeString& format( double /* number */, 49 UnicodeString& toAppendTo, 50 FieldPosition& /* pos */) const 51 { 52 toAppendTo = ""; 53 return toAppendTo; 54 } 55 56 /* 57 public Number parse(String text, ParsePosition parsePosition) 58 { return new Integer(0); } 59 */ 60 61 /* Just use one of the parse functions */ 62 virtual void parse( const UnicodeString& /* text */, 63 Formattable& result, 64 ParsePosition& /* parsePosition */) const 65 { 66 result.setLong((int32_t)0); 67 } 68 69 virtual void parse( const UnicodeString& text, 70 Formattable& result, 71 UErrorCode& status) const 72 { 73 NumberFormat::parse(text, result, status); 74 } 75 virtual Format* clone() const 76 { return NULL; } 77 78 virtual UnicodeString& format(int32_t, 79 UnicodeString& foo, 80 FieldPosition&) const 81 { return foo.remove(); } 82 83 virtual UnicodeString& format(int64_t, 84 UnicodeString& foo, 85 FieldPosition&) const 86 { return foo.remove(); } 87 88 virtual void applyPattern(const UnicodeString&, UParseError&, UErrorCode&){ 89 } 90 }; 91 92 int32_t gMyNumberFormatTestClassID; 93 UClassID MyNumberFormatTest::getDynamicClassID() const 94 { 95 return (UClassID)&gMyNumberFormatTestClassID; 96 } 97 98 99 // ***************************************************************************** 100 // class NumberFormatRegressionTest 101 // ***************************************************************************** 102 103 #define CASE(id,test) case id: name = #test; if (exec) { logln(#test "---"); logln((UnicodeString)""); test(); } break 104 105 void 106 NumberFormatRegressionTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ ) 107 { 108 // if (exec) logln((UnicodeString)"TestSuite NumberFormatRegressionTest"); 109 switch (index) { 110 CASE(0,Test4075713); 111 CASE(1,Test4074620); 112 CASE(2,Test4088161); 113 CASE(3,Test4087245); 114 CASE(4,Test4087535); 115 CASE(5,Test4088503); 116 CASE(6,Test4066646); 117 CASE(7,Test4059870); 118 CASE(8,Test4083018); 119 CASE(9,Test4071492); 120 CASE(10,Test4086575); 121 CASE(11,Test4068693); 122 CASE(12,Test4069754); 123 CASE(13,Test4087251); 124 CASE(14,Test4090489); 125 CASE(15,Test4090504); 126 CASE(16,Test4095713); 127 CASE(17,Test4092561); 128 CASE(18,Test4092480); 129 CASE(19,Test4087244); 130 CASE(20,Test4070798); 131 CASE(21,Test4071005); 132 CASE(22,Test4071014); 133 CASE(23,Test4071859); 134 CASE(24,Test4093610); 135 CASE(25,Test4098741); 136 CASE(26,Test4074454); 137 CASE(27,Test4099404); 138 CASE(28,Test4101481); 139 CASE(29,Test4052223); 140 CASE(30,Test4061302); 141 CASE(31,Test4062486); 142 CASE(32,Test4108738); 143 CASE(33,Test4106658); 144 CASE(34,Test4106662); 145 CASE(35,Test4114639); 146 CASE(36,Test4106664); 147 CASE(37,Test4106667); 148 CASE(38,Test4110936); 149 CASE(39,Test4122840); 150 CASE(40,Test4125885); 151 CASE(41,Test4134034); 152 CASE(42,Test4134300); 153 CASE(43,Test4140009); 154 CASE(44,Test4141750); 155 CASE(45,Test4145457); 156 CASE(46,Test4147295); 157 CASE(47,Test4147706); 158 CASE(48,Test4162198); 159 CASE(49,Test4162852); 160 CASE(50,Test4167494); 161 CASE(51,Test4170798); 162 CASE(52,Test4176114); 163 CASE(53,Test4179818); 164 CASE(54,Test4212072); 165 CASE(55,Test4216742); 166 CASE(56,Test4217661); 167 CASE(57,Test4161100); 168 CASE(58,Test4243011); 169 CASE(59,Test4243108); 170 CASE(60,TestJ691); 171 CASE(61,Test8199); 172 CASE(62,Test9109); 173 CASE(63,Test9780); 174 CASE(64,Test9677); 175 CASE(65,Test10361); 176 177 default: name = ""; break; 178 } 179 } 180 181 UBool 182 NumberFormatRegressionTest::failure(UErrorCode status, const UnicodeString& msg, const Locale& l, UBool possibleDataError) 183 { 184 if(U_FAILURE(status)) { 185 if (possibleDataError) { 186 dataerrln(UnicodeString("FAIL: ", "") + msg 187 + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status), "") + UnicodeString(l.getName(),"")); 188 } else { 189 errcheckln(status, UnicodeString("FAIL: ", "") + msg 190 + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status), "") + UnicodeString(l.getName(),"")); 191 } 192 return TRUE; 193 } 194 195 return FALSE; 196 } 197 198 UBool 199 NumberFormatRegressionTest::failure(UErrorCode status, const UnicodeString& msg, const char *l, UBool possibleDataError) 200 { 201 if(U_FAILURE(status)) { 202 if (possibleDataError) { 203 dataerrln(UnicodeString("FAIL: ", "") + msg 204 + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status), "") + UnicodeString(l, "")); 205 } else { 206 errcheckln(status, UnicodeString("FAIL: ", "") + msg 207 + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status), "") + UnicodeString(l, "")); 208 } 209 return TRUE; 210 } 211 212 return FALSE; 213 } 214 215 UBool 216 NumberFormatRegressionTest::failure(UErrorCode status, const UnicodeString& msg, UBool possibleDataError) 217 { 218 if(U_FAILURE(status)) { 219 if (possibleDataError) { 220 dataerrln(UnicodeString("FAIL: ", "") + msg 221 + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status), "")); 222 } else { 223 errcheckln(status, UnicodeString("FAIL: ", "") + msg 224 + UnicodeString(" failed, error ", "") + UnicodeString(u_errorName(status), "")); 225 } 226 return TRUE; 227 } 228 229 return FALSE; 230 } 231 232 /** 233 * Convert Java-style strings with \u Unicode escapes into UnicodeString objects 234 */ 235 inline UnicodeString str(const char *input) 236 { 237 return CharsToUnicodeString(input); 238 } 239 240 /* @bug 4075713 241 * NumberFormat.equals comparing with null should always return false. 242 */ 243 // {sfb} kind of silly in C++, just checking for new success 244 void NumberFormatRegressionTest::Test4075713(void) 245 { 246 //try { 247 MyNumberFormatTest *tmp = new MyNumberFormatTest(); 248 if(tmp != NULL) 249 logln("NumberFormat.equals passed"); 250 /*} catch (NullPointerException e) { 251 errln("(new MyNumberFormatTest()).equals(null) throws unexpected exception"); 252 }*/ 253 254 delete tmp; 255 } 256 257 /* @bug 4074620 258 * NumberFormat.equals comparing two obj equal even the setGroupingUsed 259 * flag is different. 260 */ 261 void NumberFormatRegressionTest::Test4074620(void) 262 { 263 264 MyNumberFormatTest *nf1 = new MyNumberFormatTest(); 265 MyNumberFormatTest *nf2 = new MyNumberFormatTest(); 266 267 nf1->setGroupingUsed(FALSE); 268 nf2->setGroupingUsed(TRUE); 269 270 if(nf1 == nf2) 271 errln("Test for bug 4074620 failed"); 272 else 273 logln("Test for bug 4074620 passed."); 274 275 delete nf1; 276 delete nf2; 277 } 278 279 280 /* @bug 4088161 281 * DecimalFormat.format() incorrectly uses maxFractionDigits setting. 282 */ 283 284 void NumberFormatRegressionTest::Test4088161 (void) 285 { 286 UErrorCode status = U_ZERO_ERROR; 287 DecimalFormat *df = new DecimalFormat(status); 288 if (!failure(status, "new DecimalFormat", "")) { 289 double d = 100; 290 df->setMinimumFractionDigits(0); 291 df->setMaximumFractionDigits(16); 292 UnicodeString sBuf1; 293 FieldPosition fp1(0); 294 logln(UnicodeString("d = ") + d); 295 logln(UnicodeString("maxFractionDigits = ") + df->getMaximumFractionDigits()); 296 297 logln(" format(d) = '" + df->format(d, sBuf1, fp1) + "'"); 298 df->setMaximumFractionDigits(17); 299 UnicodeString sBuf2; 300 FieldPosition fp2(0); 301 logln(UnicodeString("maxFractionDigits = ") + df->getMaximumFractionDigits()); 302 sBuf2 = df->format(d, sBuf2, fp2); 303 if(sBuf2 != "100") 304 errln(" format(d) = '" + sBuf2 + "'"); 305 } 306 307 delete df; 308 } 309 310 /* @bug 4087245 311 * DecimalFormatSymbols should be cloned in the ctor DecimalFormat. 312 * DecimalFormat(String, DecimalFormatSymbols). 313 */ 314 void NumberFormatRegressionTest::Test4087245 (void) 315 { 316 UErrorCode status = U_ZERO_ERROR; 317 DecimalFormatSymbols *symbols = new DecimalFormatSymbols(status); 318 failure(status, "new DecimalFormatSymbols", ""); 319 // {sfb} One note about this test: if you pass in a pointer 320 // to the symbols, they are adopted and this test will fail, 321 // even though that is the correct behavior. To test the cloning 322 // of the symbols, it is necessary to pass in a reference to the symbols 323 DecimalFormat *df = new DecimalFormat("#,##0.0", *symbols, status); 324 failure(status, "new DecimalFormat with symbols", ""); 325 int32_t n = 123; 326 UnicodeString buf1; 327 UnicodeString buf2; 328 FieldPosition pos(FieldPosition::DONT_CARE); 329 logln(UnicodeString("format(") + n + ") = " + 330 df->format(n, buf1, pos)); 331 symbols->setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol, UnicodeString((UChar)0x70)); // change value of field 332 logln(UnicodeString("format(") + n + ") = " + 333 df->format(n, buf2, pos)); 334 if(buf1 != buf2) 335 errln("Test for bug 4087245 failed"); 336 337 delete df; 338 delete symbols; 339 } 340 341 /* @bug 4087535 342 * DecimalFormat.format() incorrectly formats 0.0 343 */ 344 void NumberFormatRegressionTest::Test4087535 (void) 345 { 346 UErrorCode status = U_ZERO_ERROR; 347 DecimalFormat *df = new DecimalFormat(status); 348 failure(status, "new DecimalFormat", ""); 349 df->setMinimumIntegerDigits(0); 350 351 double n = 0; 352 UnicodeString buffer; 353 FieldPosition pos(FieldPosition::DONT_CARE); 354 buffer = df->format(n, buffer, pos); 355 if (buffer.length() == 0) 356 errln(/*n + */": '" + buffer + "'"); 357 n = 0.1; 358 buffer = df->format(n, buffer, pos); 359 if (buffer.length() == 0) 360 errln(/*n + */": '" + buffer + "'"); 361 362 delete df; 363 } 364 365 /* @bug 4088503 366 * DecimalFormat.format fails when groupingSize is set to 0. 367 */ 368 // {sfb} how do I tell if this worked? --> FieldPosition doesn't change ?? 369 void NumberFormatRegressionTest::Test4088503 (void) 370 { 371 UErrorCode status = U_ZERO_ERROR; 372 DecimalFormat *df = new DecimalFormat(status); 373 failure(status, "new DecimalFormat", ""); 374 df->setGroupingSize(0); 375 UnicodeString sBuf; 376 FieldPosition fp(FieldPosition::DONT_CARE); 377 //try { 378 logln(df->format((int32_t)123, sBuf, fp)); 379 //if(fp == FieldPosition(0)) 380 // errln("Test for bug 4088503 failed."); 381 /*} catch (Exception foo) { 382 errln("Test for bug 4088503 failed."); 383 }*/ 384 delete df; 385 386 } 387 /* @bug 4066646 388 * NumberFormat.getCurrencyInstance is wrong. 389 */ 390 void NumberFormatRegressionTest::Test4066646 (void) 391 { 392 assignFloatValue(2.04f); 393 assignFloatValue(2.03f); 394 assignFloatValue(2.02f); 395 assignFloatValue(0.0f); 396 } 397 398 float 399 NumberFormatRegressionTest::assignFloatValue(float returnfloat) 400 { 401 logln(UnicodeString(" VALUE ") + returnfloat); 402 UErrorCode status = U_ZERO_ERROR; 403 NumberFormat *nfcommon = NumberFormat::createCurrencyInstance(Locale::getUS(), status); 404 if (failure(status, "NumberFormat::createCurrencyInstance", Locale::getUS(), TRUE)){ 405 delete nfcommon; 406 return returnfloat; 407 } 408 nfcommon->setGroupingUsed(FALSE); 409 410 UnicodeString stringValue; 411 stringValue = nfcommon->format(returnfloat, stringValue); 412 logln(" DISPLAYVALUE " + stringValue); 413 Formattable result; 414 nfcommon->parse(stringValue, result, status); 415 failure(status, "nfcommon->parse", Locale::getUS()); 416 float floatResult = (float) (result.getType() == Formattable::kDouble 417 ? result.getDouble() : result.getLong()); 418 if( uprv_fabs(floatResult - returnfloat) > 0.0001) 419 //String stringValue = nfcommon.format(returnfloat).substring(1); 420 //if (Float.valueOf(stringValue).floatValue() != returnfloat) 421 errln(UnicodeString("FAIL: expected ") + returnfloat + ", got " + floatResult + " (" + stringValue+")"); 422 423 delete nfcommon; 424 return returnfloat; 425 } // End Of assignFloatValue() 426 427 /* @bug 4059870 428 * DecimalFormat throws exception when parsing "0" 429 */ 430 void NumberFormatRegressionTest::Test4059870(void) 431 { 432 UErrorCode status = U_ZERO_ERROR; 433 DecimalFormat *format = new DecimalFormat("00", status); 434 failure(status, "new Decimalformat", Locale::getUS()); 435 //try { 436 Formattable result; 437 UnicodeString str; 438 format->parse(UnicodeString("0"), result, status); 439 failure(status, "format->parse", Locale::getUS()); 440 441 /*} 442 catch (Exception e) { 443 errln("Test for bug 4059870 failed : " + e); 444 }*/ 445 446 delete format; 447 } 448 /* @bug 4083018 449 * DecimalFormatSymbol.equals should always return false when 450 * comparing with null. 451 */ 452 // {sfb} this is silly in C++ 453 void NumberFormatRegressionTest::Test4083018 (void) 454 { 455 UErrorCode status = U_ZERO_ERROR; 456 DecimalFormatSymbols *dfs = new DecimalFormatSymbols(status); 457 failure(status, "new DecimalFormatSymbols", Locale::getUS()); 458 //try { 459 if (dfs != NULL) 460 logln("Test Passed!"); 461 else 462 errln("Test for bug 4083018 failed"); 463 /*} catch (Exception foo) { 464 errln("Test for bug 4083018 failed => Message : " + foo.getMessage()); 465 }*/ 466 467 delete dfs; 468 } 469 470 /* @bug 4071492 471 * DecimalFormat does not round up correctly. 472 */ 473 void NumberFormatRegressionTest::Test4071492 (void) 474 { 475 double x = 0.00159999; 476 UErrorCode status = U_ZERO_ERROR; 477 NumberFormat *nf = NumberFormat::createInstance(status); 478 if (failure(status, "NumberFormat::createInstance", Locale::getUS(), TRUE)) { 479 delete nf; 480 return; 481 } 482 nf->setMaximumFractionDigits(4); 483 UnicodeString out; 484 FieldPosition pos(FieldPosition::DONT_CARE); 485 out = nf->format(x, out, pos); 486 logln("0.00159999 formats with 4 fractional digits to " + out); 487 UnicodeString expected("0.0016"); 488 if (out != expected) 489 errln("FAIL: Expected " + expected); 490 491 delete nf; 492 } 493 494 /* @bug 4086575 495 * A space as a group separator for localized pattern causes 496 * wrong format. WorkAround : use non-breaking space. 497 */ 498 void NumberFormatRegressionTest::Test4086575(void) 499 { 500 UErrorCode status = U_ZERO_ERROR; 501 NumberFormat *nf1 = NumberFormat::createInstance(Locale::getFrance(), status); 502 503 // TODO: There is not a good way to find out that the creation of this number format has 504 // failed. Major rewiring of format construction proposed. 505 if(U_FAILURE(status)) { 506 dataerrln("Something is wrong with French number format - it should not fallback. Exitting - %s", u_errorName(status)); 507 delete nf1; 508 return; 509 } 510 failure(status, "NumberFormat::createInstance", Locale::getFrance()); 511 512 // C++ workaround to make sure cast works 513 DecimalFormat *nf = dynamic_cast<DecimalFormat *>(nf1); 514 if(nf == NULL) { 515 errln("NumberFormat::createInstance returned incorrect type."); 516 return; 517 } 518 519 UnicodeString temp; 520 logln("nf toPattern1: " + nf->toPattern(temp)); 521 logln("nf toLocPattern1: " + nf->toLocalizedPattern(temp)); 522 523 // No group separator 524 logln("...applyLocalizedPattern ###,00;(###,00) "); 525 nf->applyLocalizedPattern(UnicodeString("###,00;(###,00)"), status); 526 failure(status, "nf->applyLocalizedPattern", Locale::getFrance()); 527 logln("nf toPattern2: " + nf->toPattern(temp)); 528 logln("nf toLocPattern2: " + nf->toLocalizedPattern(temp)); 529 530 FieldPosition pos(FieldPosition::DONT_CARE); 531 logln("nf: " + nf->format((int32_t)1234, temp, pos)); // 1234,00 532 logln("nf: " + nf->format((int32_t)-1234, temp, pos)); // (1234,00) 533 534 // Space as group separator 535 536 logln("...applyLocalizedPattern # ###,00;(# ###,00) "); 537 // nbsp = \u00a0 538 //nf->applyLocalizedPattern("#\u00a0###,00;(#\u00a0###,00)"); 539 UChar patChars[] = { 540 0x23, 0x00a0, 0x23, 0x23, 0x23, 0x2c, 0x30, 0x30, 0x3b, 541 0x28, 0x23, 0x00a0, 0x23, 0x23, 0x23, 0x2c, 0x30, 0x30, 0x29 542 }; 543 UnicodeString pat(patChars, 19, 19); 544 nf->applyLocalizedPattern(pat, status); 545 failure(status, "nf->applyLocalizedPattern", Locale::getFrance()); 546 logln("nf toPattern2: " + nf->toPattern(temp)); 547 logln("nf toLocPattern2: " + nf->toLocalizedPattern(temp)); 548 UnicodeString buffer; 549 buffer = nf->format((int32_t)1234, buffer, pos); 550 //if (buffer != UnicodeString("1\u00a0234,00")) 551 UChar c[] = { 552 0x31, 0x00a0, 0x32, 0x33, 0x34, 0x2c, 0x30, 0x30 553 }; 554 UnicodeString cc(c, 8, 8); 555 if (buffer != cc) 556 errln("nf : " + buffer); // Expect 1 234,00 557 558 buffer.remove(); 559 buffer = nf->format((int32_t)-1234, buffer, pos); 560 UChar c1[] = { 561 0x28, 0x31, 0x00a0, 0x32, 0x33, 0x34, 0x2c, 0x30, 0x30, 0x29 562 }; 563 UnicodeString cc1(c1, 10, 10); 564 if (buffer != cc1) 565 errln("nf : " + buffer); // Expect (1 234,00) 566 567 // Erroneously prints: 568 // 1234,00 , 569 // (1234,00 ,) 570 571 delete nf1; 572 } 573 /* @bug 4068693 574 * DecimalFormat.parse returns wrong value 575 */ 576 // {sfb} slightly converted into a round-trip test, since in C++ 577 // there is no Double.toString() 578 void NumberFormatRegressionTest::Test4068693(void) 579 { 580 logln("----- Test Application -----"); 581 ParsePosition pos(0); 582 UErrorCode status = U_ZERO_ERROR; 583 DecimalFormat *df = new DecimalFormat(status); 584 if(U_FAILURE(status)) { 585 errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status)); 586 delete df; 587 return; 588 } 589 failure(status, "new DecimalFormat"); 590 Formattable d; 591 //Double d = (Double)df.parse("123.55456", pos=new ParsePosition(0)); 592 df->parse(UnicodeString("123.55456"), d, pos); 593 //if (!d.toString().equals("123.55456")) { 594 UnicodeString dstr; 595 df->setMaximumFractionDigits(999); 596 df->setMaximumIntegerDigits(999); 597 FieldPosition fp(FieldPosition::DONT_CARE); 598 dstr = df->format(d.getDouble(), dstr, fp); 599 if (dstr != UnicodeString("123.55456")) { 600 errln(UnicodeString("Result -> ") + d.getDouble()); 601 } 602 603 delete df; 604 } 605 606 /* @bug 4069754, 4067878 607 * null pointer thrown when accessing a deserialized DecimalFormat 608 * object. 609 */ 610 // {sfb} doesn't apply in C++ 611 void NumberFormatRegressionTest::Test4069754(void) 612 { 613 /* try { 614 myformat it = new myformat(); 615 logln(it.Now()); 616 FileOutputStream ostream = new FileOutputStream("t.tmp"); 617 ObjectOutputStream p = new ObjectOutputStream(ostream); 618 p.writeObject(it); 619 ostream.close(); 620 logln("Saved ok."); 621 622 FileInputStream istream = new FileInputStream("t.tmp"); 623 ObjectInputStream p2 = new ObjectInputStream(istream); 624 myformat it2 = (myformat)p2.readObject(); 625 logln(it2.Now()); 626 istream.close(); 627 logln("Loaded ok."); 628 } catch (Exception foo) { 629 errln("Test for bug 4069754 or 4057878 failed => Exception: " + foo.getMessage()); 630 } 631 */} 632 633 /* @bug 4087251 634 * DecimalFormat.applyPattern(String) allows illegal patterns 635 */ 636 void NumberFormatRegressionTest::Test4087251 (void) 637 { 638 UErrorCode status = U_ZERO_ERROR; 639 DecimalFormat *df = new DecimalFormat(status); 640 if(U_FAILURE(status)) { 641 errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status)); 642 delete df; 643 return; 644 } 645 failure(status, "new DecimalFormat"); 646 //try { 647 df->applyPattern(UnicodeString("#.#.#"), status); 648 if( ! U_FAILURE(status)) 649 errln("df->applyPattern with illegal pattern didn't fail"); 650 UnicodeString temp; 651 logln("toPattern() returns \"" + df->toPattern(temp) + "\""); 652 //errln("applyPattern(\"#.#.#\") doesn't throw IllegalArgumentException"); 653 /*} catch (IllegalArgumentException e) { 654 logln("Caught Illegal Argument Error !"); 655 }*/ 656 // Second test; added 5/11/98 when reported to fail on 1.2b3 657 //try { 658 df->applyPattern("#0.0#0#0", status); 659 if( ! U_FAILURE(status)) 660 errln("df->applyPattern with illegal pattern didn't fail"); 661 logln("toPattern() returns \"" + df->toPattern(temp) + "\""); 662 //errln("applyPattern(\"#0.0#0#0\") doesn't throw IllegalArgumentException"); 663 /*} catch (IllegalArgumentException e) { 664 logln("Ok - IllegalArgumentException for #0.0#0#0"); 665 }*/ 666 667 delete df; 668 } 669 670 /* @bug 4090489 671 * DecimalFormat.format() loses precision 672 */ 673 void NumberFormatRegressionTest::Test4090489 (void) 674 { 675 // {sfb} sprintf doesn't correctly handle the double, so there is nothing 676 // that NumberFormat can do. For some reason, it does not format the last 1. 677 678 /* UErrorCode status = U_ZERO_ERROR; 679 DecimalFormat *df = new DecimalFormat(status); 680 failure(status, "new DecimalFormat"); 681 df->setMinimumFractionDigits(10); 682 df->setMaximumFractionDigits(999); 683 df->setGroupingUsed(FALSE); 684 double d = 1.000000000000001E7; 685 //BigDecimal bd = new BigDecimal(d); 686 UnicodeString sb; 687 FieldPosition fp(0); 688 logln(UnicodeString("d = ") + d); 689 //logln("BigDecimal.toString(): " + bd.toString()); 690 df->format(d, sb, fp); 691 if (sb != "10000000.0000000100") { 692 errln("DecimalFormat.format(): " + sb); 693 } 694 */ 695 } 696 697 /* @bug 4090504 698 * DecimalFormat.format() loses precision 699 */ 700 void NumberFormatRegressionTest::Test4090504 (void) 701 { 702 double d = 1; 703 logln(UnicodeString("d = ") + d); 704 UErrorCode status = U_ZERO_ERROR; 705 DecimalFormat *df = new DecimalFormat(status); 706 if(U_FAILURE(status)) { 707 errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status)); 708 delete df; 709 return; 710 } 711 failure(status, "new DecimalFormat"); 712 UnicodeString sb; 713 FieldPosition fp(FieldPosition::DONT_CARE); 714 //try { 715 for (int i = 17; i <= 20; i++) { 716 df->setMaximumFractionDigits(i); 717 //sb = new StringBuffer(""); 718 fp.setField(0); 719 logln(UnicodeString(" getMaximumFractionDigits() = ") + i); 720 logln(UnicodeString(" formated: ") + df->format(d, sb, fp)); 721 } 722 /*} catch (Exception foo) { 723 errln("Bug 4090504 regression test failed. Message : " + foo.getMessage()); 724 }*/ 725 726 delete df; 727 } 728 /* @bug 4095713 729 * DecimalFormat.parse(String str, ParsePosition pp) loses precision 730 */ 731 void NumberFormatRegressionTest::Test4095713 (void) 732 { 733 UErrorCode status = U_ZERO_ERROR; 734 DecimalFormat *df = new DecimalFormat(status); 735 if(U_FAILURE(status)) { 736 errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status)); 737 delete df; 738 return; 739 } 740 failure(status, "new DecimalFormat"); 741 UnicodeString str("0.1234"); 742 double d1 = 0.1234; 743 //Double d1 = new Double(str); 744 //Double d2 = (Double) df.parse(str, new ParsePosition(0)); 745 Formattable d2; 746 ParsePosition pp(0); 747 df->parse(str, d2, pp); 748 logln(UnicodeString("") + d1); 749 if (d2.getDouble() != d1) 750 errln(UnicodeString("Bug 4095713 test failed, new double value : ") + d2.getDouble()); 751 delete df; 752 } 753 754 /* @bug 4092561 755 * DecimalFormat.parse() fails when multiplier is not set to 1 756 */ 757 // {sfb} not sure what to do with this one 758 void NumberFormatRegressionTest::Test4092561 (void) 759 { 760 UErrorCode status = U_ZERO_ERROR; 761 DecimalFormat *df = new DecimalFormat(status); 762 if(U_FAILURE(status)) { 763 errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status)); 764 delete df; 765 return; 766 } 767 failure(status, "new DecimalFormat"); 768 769 // {sfb} going to cheat here and use sprintf ?? 770 771 /*UnicodeString str = Long.toString(Long.MIN_VALUE); 772 logln("Long.MIN_VALUE : " + df.parse(str, new ParsePosition(0)).toString()); 773 df.setMultiplier(100); 774 Number num = df.parse(str, new ParsePosition(0)); 775 if (num.doubleValue() != -9.223372036854776E16) 776 errln("Bug 4092561 test failed when multiplier is set to not 1."); 777 */ 778 delete df; 779 } 780 781 /* @bug 4092480 782 * DecimalFormat: Negative format ignored. 783 */ 784 void NumberFormatRegressionTest::Test4092480 (void) 785 { 786 UErrorCode status = U_ZERO_ERROR; 787 DecimalFormat *dfFoo = new DecimalFormat(UnicodeString("000"), status); 788 if(U_FAILURE(status)) { 789 errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status)); 790 delete dfFoo; 791 return; 792 } 793 failure(status, "new DecimalFormat"); 794 795 //try { 796 dfFoo->applyPattern("0000;-000", status); 797 failure(status, "dfFoo->applyPattern"); 798 UnicodeString temp; 799 if (dfFoo->toPattern(temp) != UnicodeString("#0000")) 800 errln("dfFoo.toPattern : " + dfFoo->toPattern(temp)); 801 FieldPosition pos(FieldPosition::DONT_CARE); 802 logln(dfFoo->format((int32_t)42, temp, pos)); 803 logln(dfFoo->format((int32_t)-42, temp, pos)); 804 dfFoo->applyPattern("000;-000", status); 805 failure(status, "dfFoo->applyPattern"); 806 if (dfFoo->toPattern(temp) != UnicodeString("#000")) 807 errln("dfFoo.toPattern : " + dfFoo->toPattern(temp)); 808 logln(dfFoo->format((int32_t)42,temp, pos)); 809 logln(dfFoo->format((int32_t)-42, temp, pos)); 810 811 dfFoo->applyPattern("000;-0000", status); 812 failure(status, "dfFoo->applyPattern"); 813 if (dfFoo->toPattern(temp) != UnicodeString("#000")) 814 errln("dfFoo.toPattern : " + dfFoo->toPattern(temp)); 815 logln(dfFoo->format((int32_t)42, temp, pos)); 816 logln(dfFoo->format((int32_t)-42, temp, pos)); 817 818 dfFoo->applyPattern("0000;-000", status); 819 failure(status, "dfFoo->applyPattern"); 820 if (dfFoo->toPattern(temp) != UnicodeString("#0000")) 821 errln("dfFoo.toPattern : " + dfFoo->toPattern(temp)); 822 logln(dfFoo->format((int32_t)42, temp, pos)); 823 logln(dfFoo->format((int32_t)-42, temp, pos)); 824 /*} catch (Exception foo) { 825 errln("Message " + foo.getMessage()); 826 }*/ 827 828 delete dfFoo; 829 } 830 /* @bug 4087244 831 * NumberFormat.getCurrencyInstance() produces format that uses 832 * decimal separator instead of monetary decimal separator. 833 * 834 * Rewrote this test not to depend on the actual pattern. Pattern should 835 * never contain the monetary separator! Decimal separator in pattern is 836 * interpreted as monetary separator if currency symbol is seen! 837 */ 838 void NumberFormatRegressionTest::Test4087244 (void) { 839 UErrorCode status = U_ZERO_ERROR; 840 char loc[256] = {0}; 841 uloc_canonicalize("pt_PT_PREEURO", loc, 256, &status); 842 Locale *de = new Locale(loc); 843 NumberFormat *nf = NumberFormat::createCurrencyInstance(*de, status); 844 if(U_FAILURE(status)) { 845 dataerrln("Error creating DecimalFormat: %s", u_errorName(status)); 846 delete nf; 847 return; 848 } 849 DecimalFormat *df = dynamic_cast<DecimalFormat *>(nf); 850 if(df == NULL) { 851 errln("expected DecimalFormat!"); 852 return; 853 } 854 const DecimalFormatSymbols *sym = df->getDecimalFormatSymbols(); 855 UnicodeString decSep = sym->getSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol); 856 UnicodeString monSep = sym->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol); 857 if (decSep == monSep) { 858 errln("ERROR in test: want decimal sep != monetary sep"); 859 return; 860 } 861 df->setMinimumIntegerDigits(1); 862 df->setMinimumFractionDigits(2); 863 UnicodeString str; 864 FieldPosition pos; 865 df->format(1.23, str, pos); 866 UnicodeString monStr("1x23"); 867 monStr.replace((int32_t)1, 1, monSep); 868 UnicodeString decStr("1x23"); 869 decStr.replace((int32_t)1, 1, decSep); 870 if (str.indexOf(monStr) >= 0 && str.indexOf(decStr) < 0) { 871 logln(UnicodeString("OK: 1.23 -> \"") + str + "\" contains \"" + 872 monStr + "\" and not \"" + decStr + '"'); 873 } else { 874 errln(UnicodeString("FAIL: 1.23 -> \"") + str + "\", should contain \"" + 875 monStr + 876 "\" and not \"" + decStr + '"'); 877 } 878 delete de; 879 delete nf; 880 } 881 /* @bug 4070798 882 * Number format data rounding errors for locale FR 883 */ 884 void NumberFormatRegressionTest::Test4070798 (void) 885 { 886 NumberFormat *formatter; 887 UnicodeString tempString; 888 889 /* User error : 890 String expectedDefault = "-5\u00a0789,987"; 891 String expectedCurrency = "5\u00a0789,98\u00a0F"; 892 String expectedPercent = "-578\u00a0998%"; 893 */ 894 UChar chars1 [] = { 895 0x2d, 0x35, 0x00a0, 0x37, 0x38, 0x39, 0x2c, 0x39, 0x38, 0x38 896 }; 897 UChar chars2 [] = { 898 0x35, 0x00a0, 0x37, 0x38, 0x39, 0x2c, 0x39, 0x39, 0x00a0, 0x46 899 }; 900 UChar chars3 [] = { 901 0x2d, 0x35, 0x37, 0x38, 0x00a0, 0x39, 0x39, 0x39, 0x00a0, 0x25 902 }; 903 UnicodeString expectedDefault(chars1, 10, 10); 904 UnicodeString expectedCurrency(chars2, 10, 10); 905 UnicodeString expectedPercent(chars3, 10, 10); 906 907 UErrorCode status = U_ZERO_ERROR; 908 char loc[256]={0}; 909 int len = uloc_canonicalize("fr_FR_PREEURO", loc, 256, &status); 910 (void)len; // Suppress set but not used warning. 911 formatter = NumberFormat::createInstance(Locale(loc), status); 912 if(U_FAILURE(status)) { 913 dataerrln("Error creating DecimalFormat: %s", u_errorName(status)); 914 delete formatter; 915 return; 916 } 917 failure(status, "NumberFormat::createNumberInstance", loc); 918 tempString = formatter->format (-5789.9876, tempString); 919 920 if (tempString == expectedDefault) { 921 logln ("Bug 4070798 default test passed."); 922 } else { 923 errln(UnicodeString("Failed:") + 924 " Expected " + expectedDefault + 925 " Received " + tempString ); 926 } 927 delete formatter; 928 len = uloc_canonicalize("fr_FR_PREEURO", loc, 256, &status); 929 formatter = NumberFormat::createCurrencyInstance(loc, status); 930 failure(status, "NumberFormat::createCurrencyInstance", loc); 931 tempString.remove(); 932 tempString = formatter->format( 5789.9876, tempString ); 933 934 if (tempString == expectedCurrency) { 935 logln ("Bug 4070798 currency test passed."); 936 } else { 937 errln(UnicodeString("Failed:") + 938 " Expected " + expectedCurrency + 939 " Received " + tempString ); 940 } 941 delete formatter; 942 943 uloc_canonicalize("fr_FR_PREEURO", loc, 256, &status); 944 formatter = NumberFormat::createPercentInstance(Locale(loc), status); 945 failure(status, "NumberFormat::createPercentInstance", loc); 946 tempString.remove(); 947 tempString = formatter->format (-5789.9876, tempString); 948 949 if (tempString == expectedPercent) { 950 logln ("Bug 4070798 percentage test passed."); 951 } else { 952 errln(UnicodeString("Failed:") + 953 " Expected " + expectedPercent + 954 " Received " + tempString ); 955 } 956 957 delete formatter; 958 } 959 /* @bug 4071005 960 * Data rounding errors for French (Canada) locale 961 */ 962 void NumberFormatRegressionTest::Test4071005 (void) 963 { 964 NumberFormat *formatter; 965 UnicodeString tempString; 966 /* User error : 967 String expectedDefault = "-5\u00a0789,987"; 968 String expectedCurrency = "5\u00a0789,98\u00a0$"; 969 String expectedPercent = "-578\u00a0998%"; 970 */ 971 UChar chars1 [] = { 972 0x2d, 0x35, 0x00a0, 0x37, 0x38, 0x39, 0x2c, 0x39, 0x38, 0x38 973 }; 974 UChar chars2 [] = { 975 0x35, 0x00a0, 0x37, 0x38, 0x39, 0x2c, 0x39, 0x39, 0x00a0, 0x24 976 }; 977 UChar chars3 [] = { 978 0x2d, 0x35, 0x37, 0x38, 0x00a0, 0x39, 0x39, 0x39, 0x00a0, 0x25 979 }; 980 UnicodeString expectedDefault(chars1, 10, 10); 981 UnicodeString expectedCurrency(chars2, 10, 10); 982 UnicodeString expectedPercent(chars3, 10, 10); 983 984 UErrorCode status = U_ZERO_ERROR; 985 formatter = NumberFormat::createInstance(Locale::getCanadaFrench(), status); 986 if (failure(status, "NumberFormat::createNumberInstance", Locale::getCanadaFrench(), TRUE)){ 987 delete formatter; 988 return; 989 }; 990 tempString = formatter->format (-5789.9876, tempString); 991 992 if (tempString == expectedDefault) { 993 logln ("Bug 4071005 default test passed."); 994 } else { 995 errln(UnicodeString("Failed:") + 996 " Expected " + expectedDefault + 997 " Received " + tempString ); 998 } 999 delete formatter; 1000 1001 formatter = NumberFormat::createCurrencyInstance(Locale::getCanadaFrench(), status); 1002 failure(status, "NumberFormat::createCurrencyInstance", Locale::getCanadaFrench()); 1003 tempString.remove(); 1004 tempString = formatter->format( 5789.9876, tempString ); 1005 1006 if (tempString == expectedCurrency) { 1007 logln ("Bug 4071005 currency test assed."); 1008 } else { 1009 errln(UnicodeString("Failed:") + 1010 " Expected " + expectedCurrency + 1011 " Received " + tempString ); 1012 } 1013 delete formatter; 1014 1015 formatter = NumberFormat::createPercentInstance(Locale::getCanadaFrench(), status); 1016 failure(status, "NumberFormat::createPercentInstance", Locale::getCanadaFrench()); 1017 tempString.remove(); 1018 tempString = formatter->format (-5789.9876, tempString); 1019 1020 if (tempString == expectedPercent) { 1021 logln ("Bug 4071005 percentage test passed."); 1022 } else { 1023 errln(UnicodeString("Failed:") + 1024 " Expected " + expectedPercent + 1025 " Received " + tempString ); 1026 } 1027 1028 delete formatter; 1029 } 1030 1031 /* @bug 4071014 1032 * Data rounding errors for German (Germany) locale 1033 */ 1034 void NumberFormatRegressionTest::Test4071014 (void) 1035 { 1036 NumberFormat *formatter; 1037 UnicodeString tempString; 1038 /* user error : 1039 String expectedDefault = "-5.789,987"; 1040 String expectedCurrency = "5.789,98 DEM"; 1041 String expectedPercent = "-578.998%"; 1042 */ 1043 UnicodeString expectedDefault("-5.789,988"); 1044 UnicodeString expectedCurrency("5.789,99\\u00A0DEM"); 1045 UnicodeString expectedPercent("-578.999\\u00A0%"); 1046 1047 expectedCurrency = expectedCurrency.unescape(); 1048 expectedPercent = expectedPercent.unescape(); 1049 1050 UErrorCode status = U_ZERO_ERROR; 1051 char loc[256]={0}; 1052 uloc_canonicalize("de_DE_PREEURO", loc, 256, &status); 1053 formatter = NumberFormat::createInstance(Locale(loc), status); 1054 if (failure(status, "NumberFormat::createNumberInstance", loc, TRUE)){ 1055 delete formatter; 1056 return; 1057 } 1058 tempString.remove(); 1059 tempString = formatter->format (-5789.9876, tempString); 1060 1061 if (tempString == expectedDefault) { 1062 logln ("Bug 4071014 default test passed."); 1063 } else { 1064 errln(UnicodeString("Failed:") + 1065 " Expected " + expectedDefault + 1066 " Received " + tempString ); 1067 } 1068 delete formatter; 1069 uloc_canonicalize("de_DE_PREEURO", loc, 256, &status); 1070 formatter = NumberFormat::createCurrencyInstance(Locale(loc), status); 1071 failure(status, "NumberFormat::createCurrencyInstance", loc); 1072 tempString.remove(); 1073 tempString = formatter->format( 5789.9876, tempString ); 1074 1075 if (tempString == expectedCurrency) { 1076 logln ("Bug 4071014 currency test assed."); 1077 } else { 1078 errln(UnicodeString("Failed:") + 1079 " Expected " + expectedCurrency + 1080 " Received " + tempString ); 1081 } 1082 delete formatter; 1083 1084 formatter = NumberFormat::createPercentInstance(Locale::getGermany(), status); 1085 failure(status, "NumberFormat::createPercentInstance", Locale::getGermany()); 1086 tempString.remove(); 1087 tempString = formatter->format (-5789.9876, tempString); 1088 1089 if (tempString == expectedPercent) { 1090 logln ("Bug 4071014 percentage test passed."); 1091 } else { 1092 errln(UnicodeString("Failed:") + 1093 " Expected " + expectedPercent + 1094 " Received " + tempString ); 1095 } 1096 1097 delete formatter; 1098 } 1099 /* @bug 4071859 1100 * Data rounding errors for Italian locale number formats 1101 */ 1102 void NumberFormatRegressionTest::Test4071859 (void) 1103 { 1104 NumberFormat *formatter; 1105 UnicodeString tempString; 1106 /* user error : 1107 String expectedDefault = "-5.789,987"; 1108 String expectedCurrency = "-L.\\u00A05.789,98"; 1109 String expectedPercent = "-578.998%"; 1110 */ 1111 UnicodeString expectedDefault("-5.789,988"); 1112 UnicodeString expectedCurrency("-ITL\\u00A05.790", -1, US_INV); 1113 UnicodeString expectedPercent("-578.999%"); 1114 expectedCurrency = expectedCurrency.unescape(); 1115 1116 UErrorCode status = U_ZERO_ERROR; 1117 char loc[256]={0}; 1118 uloc_canonicalize("it_IT_PREEURO", loc, 256, &status); 1119 formatter = NumberFormat::createInstance(Locale(loc), status); 1120 if (failure(status, "NumberFormat::createNumberInstance", TRUE)){ 1121 delete formatter; 1122 return; 1123 }; 1124 tempString = formatter->format (-5789.9876, tempString); 1125 1126 if (tempString == expectedDefault) { 1127 logln ("Bug 4071859 default test passed."); 1128 } else { 1129 errln(UnicodeString("Failed:") + 1130 " Expected " + expectedDefault + 1131 " Received " + tempString ); 1132 } 1133 delete formatter; 1134 uloc_canonicalize("it_IT_PREEURO", loc, 256, &status); 1135 formatter = NumberFormat::createCurrencyInstance(Locale(loc), status); 1136 failure(status, "NumberFormat::createCurrencyInstance"); 1137 tempString.remove(); 1138 tempString = formatter->format( -5789.9876, tempString ); 1139 1140 if (tempString == expectedCurrency) { 1141 logln ("Bug 4071859 currency test assed."); 1142 } else { 1143 errln(UnicodeString("Failed:") + 1144 " Expected " + expectedCurrency + 1145 " Received " + tempString ); 1146 } 1147 delete formatter; 1148 uloc_canonicalize("it_IT_PREEURO", loc, 256, &status); 1149 formatter = NumberFormat::createPercentInstance(Locale(loc), status); 1150 failure(status, "NumberFormat::createPercentInstance"); 1151 tempString.remove(); 1152 tempString = formatter->format (-5789.9876, tempString); 1153 1154 if (tempString == expectedPercent) { 1155 logln ("Bug 4071859 percentage test passed."); 1156 } else { 1157 errln(UnicodeString("Failed:") + 1158 " Expected " + expectedPercent + 1159 " Received " + tempString ); 1160 } 1161 1162 delete formatter; 1163 } 1164 /* @bug 4071859 1165 * Test rounding for nearest even. 1166 */ 1167 void NumberFormatRegressionTest::Test4093610(void) 1168 { 1169 UErrorCode status = U_ZERO_ERROR; 1170 DecimalFormat *df = new DecimalFormat("#0.#", status); 1171 if (!failure(status, "new DecimalFormat")) { 1172 UnicodeString s("12.4"); 1173 roundingTest(df, 12.35, s); 1174 roundingTest(df, 12.45, s); 1175 s = "12.5"; 1176 roundingTest(df, 12.452,s); 1177 s = "12.6"; 1178 roundingTest(df, 12.55, s); 1179 roundingTest(df, 12.65, s); 1180 s = "12.7"; 1181 roundingTest(df, 12.652,s); 1182 s = "12.8"; 1183 roundingTest(df, 12.75, s); 1184 roundingTest(df, 12.752,s); 1185 roundingTest(df, 12.85, s); 1186 s = "12.9"; 1187 roundingTest(df, 12.852,s); 1188 s = "13"; 1189 roundingTest(df, 12.95, s); 1190 roundingTest(df, 12.952,s); 1191 } 1192 1193 delete df; 1194 } 1195 1196 void NumberFormatRegressionTest::roundingTest(DecimalFormat *df, double x, UnicodeString& expected) 1197 { 1198 UnicodeString out; 1199 FieldPosition pos(FieldPosition::DONT_CARE); 1200 out = df->format(x, out, pos); 1201 logln(UnicodeString("") + x + " formats with 1 fractional digits to " + out); 1202 if (out != expected) 1203 errln("FAIL: Expected " + expected); 1204 } 1205 /* @bug 4098741 1206 * Tests the setMaximumFractionDigits limit. 1207 */ 1208 void NumberFormatRegressionTest::Test4098741(void) 1209 { 1210 //try { 1211 UErrorCode status = U_ZERO_ERROR; 1212 NumberFormat *fmt = NumberFormat::createPercentInstance(status); 1213 if (U_FAILURE(status)) { 1214 dataerrln("Error calling NumberFormat::createPercentInstance"); 1215 delete fmt; 1216 return; 1217 } 1218 1219 fmt->setMaximumFractionDigits(20); 1220 UnicodeString temp; 1221 logln(fmt->format(.001, temp)); 1222 /*} catch (Exception foo) { 1223 errln("Bug 4098471 failed with exception thrown : " + foo.getMessage()); 1224 }*/ 1225 delete fmt; 1226 } 1227 /* @bug 4074454 1228 * Tests illegal pattern exception. 1229 * Fix comment : HShih A31 Part1 will not be fixed and javadoc needs to be updated. 1230 * Part2 has been fixed. 1231 */ 1232 void NumberFormatRegressionTest::Test4074454(void) 1233 { 1234 //try { 1235 UErrorCode status = U_ZERO_ERROR; 1236 DecimalFormat *fmt = new DecimalFormat("#,#00.00;-#.#", status); 1237 if(U_FAILURE(status)) { 1238 errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status)); 1239 delete fmt; 1240 return; 1241 } 1242 failure(status, "new DecimalFormat"); 1243 logln("Inconsistent negative pattern is fine."); 1244 DecimalFormat *newFmt = new DecimalFormat("#,#00.00 p''ieces;-#,#00.00 p''ieces", status); 1245 failure(status, "new DecimalFormat"); 1246 UnicodeString tempString; 1247 FieldPosition pos(FieldPosition::DONT_CARE); 1248 tempString = newFmt->format(3456.78, tempString, pos); 1249 if (tempString != UnicodeString("3,456.78 p'ieces")) 1250 dataerrln("Failed! 3456.78 p'ieces expected, but got : " + tempString); 1251 /*} catch (Exception foo) { 1252 errln("An exception was thrown for any inconsistent negative pattern."); 1253 }*/ 1254 1255 delete fmt; 1256 delete newFmt; 1257 } 1258 /* @bug 4099404 1259 * Tests all different comments. 1260 * Response to some comments : 1261 * [1] DecimalFormat.parse API documentation is more than just one line. 1262 * This is not a reproducable doc error in 116 source code. 1263 * [2] See updated javadoc. 1264 * [3] Fixed. 1265 * [4] NumberFormat.parse(String, ParsePosition) : If parsing fails, 1266 * a null object will be returned. The unchanged parse position also 1267 * reflects an error. 1268 * NumberFormat.parse(String) : If parsing fails, an ParseException 1269 * will be thrown. 1270 * See updated javadoc for more details. 1271 * [5] See updated javadoc. 1272 * [6] See updated javadoc. 1273 * [7] This is a correct behavior if the DateFormat object is linient. 1274 * Otherwise, an IllegalArgumentException will be thrown when formatting 1275 * "January 35". See GregorianCalendar class javadoc for more details. 1276 */ 1277 void NumberFormatRegressionTest::Test4099404(void) 1278 { 1279 //try { 1280 UErrorCode status = U_ZERO_ERROR; 1281 DecimalFormat *fmt = new DecimalFormat(UnicodeString("000.0#0"), status); 1282 if(! U_FAILURE(status)) 1283 errln(UnicodeString("Bug 4099404 failed applying illegal pattern \"000.0#0\"")); 1284 /*} catch (Exception foo) { 1285 logln("Bug 4099404 pattern \"000.0#0\" passed"); 1286 }*/ 1287 delete fmt; 1288 fmt = 0; 1289 //try { 1290 fmt = new DecimalFormat(UnicodeString("0#0.000"), status); 1291 if( !U_FAILURE(status)) 1292 errln("Bug 4099404 failed applying illegal pattern \"0#0.000\""); 1293 /*} catch (Exception foo) { 1294 logln("Bug 4099404 pattern \"0#0.000\" passed"); 1295 }*/ 1296 1297 delete fmt; 1298 } 1299 /* @bug 4101481 1300 * DecimalFormat.applyPattern doesn't set minimum integer digits 1301 */ 1302 void NumberFormatRegressionTest::Test4101481(void) 1303 { 1304 UErrorCode status = U_ZERO_ERROR; 1305 DecimalFormat *sdf = new DecimalFormat(UnicodeString("#,##0"), status); 1306 if(U_FAILURE(status)) { 1307 errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status)); 1308 delete sdf; 1309 return; 1310 } 1311 failure(status, "new DecimalFormat"); 1312 if (sdf->getMinimumIntegerDigits() != 1) 1313 errln(UnicodeString("Minimum integer digits : ") + sdf->getMinimumIntegerDigits()); 1314 delete sdf; 1315 } 1316 /* @bug 4052223 (API addition request A27) 1317 * Tests ParsePosition.setErrorPosition() and ParsePosition.getErrorPosition(). 1318 */ 1319 void NumberFormatRegressionTest::Test4052223(void) 1320 { 1321 //try { 1322 UErrorCode status = U_ZERO_ERROR; 1323 DecimalFormat *fmt = new DecimalFormat(UnicodeString("#,#00.00"), status); 1324 if(U_FAILURE(status)) { 1325 errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status)); 1326 delete fmt; 1327 return; 1328 } 1329 failure(status, "new DecimalFormat"); 1330 Formattable num; 1331 fmt->parse(UnicodeString("abc3"), num, status); 1332 if(! U_FAILURE(status)) 1333 errln(UnicodeString("Bug 4052223 failed : can't parse string \"a\". Got ") /*+ num*/); 1334 /*} catch (ParseException foo) { 1335 logln("Caught expected ParseException : " + foo.getMessage() + " at index : " + foo.getErrorOffset()); 1336 }*/ 1337 delete fmt; 1338 } 1339 /* @bug 4061302 1340 * API tests for API addition request A9. 1341 */ 1342 void NumberFormatRegressionTest::Test4061302(void) 1343 { 1344 UErrorCode status = U_ZERO_ERROR; 1345 DecimalFormatSymbols *fmt = new DecimalFormatSymbols(status); 1346 failure(status, "new DecimalFormatSymbols"); 1347 UnicodeString currency(fmt->getSymbol(DecimalFormatSymbols::kCurrencySymbol)); 1348 UnicodeString intlCurrency(fmt->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol)); 1349 UnicodeString monDecSeparator(fmt->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol)); 1350 if (currency == UnicodeString("") || 1351 intlCurrency == UnicodeString("") || 1352 monDecSeparator == UnicodeString("")) 1353 { 1354 errln("getCurrencySymbols failed, got empty string."); 1355 } 1356 UnicodeString monDecSeparatorStr; 1357 monDecSeparatorStr.append(monDecSeparator); 1358 logln((UnicodeString)"Before set ==> Currency : " + currency +(UnicodeString)" Intl Currency : " + intlCurrency + (UnicodeString)" Monetary Decimal Separator : " + monDecSeparatorStr); 1359 fmt->setSymbol(DecimalFormatSymbols::kCurrencySymbol, UnicodeString("XYZ")); 1360 fmt->setSymbol(DecimalFormatSymbols::kIntlCurrencySymbol, UnicodeString("ABC")); 1361 fmt->setSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol, UnicodeString((UChar)0x002A/*'*'*/)); 1362 currency = fmt->getSymbol(DecimalFormatSymbols::kCurrencySymbol); 1363 intlCurrency = fmt->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol); 1364 monDecSeparator = fmt->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol); 1365 if (currency != UnicodeString("XYZ") || 1366 intlCurrency != UnicodeString("ABC") || 1367 monDecSeparator != UnicodeString((UChar)0x002A/*'*'*/)) { 1368 errln("setCurrencySymbols failed."); 1369 } 1370 monDecSeparatorStr.remove(); 1371 monDecSeparatorStr.append(monDecSeparator); 1372 logln("After set ==> Currency : " + currency + " Intl Currency : " + intlCurrency + " Monetary Decimal Separator : " + monDecSeparatorStr); 1373 1374 delete fmt; 1375 } 1376 /* @bug 4062486 1377 * API tests for API addition request A23. FieldPosition.getBeginIndex and 1378 * FieldPosition.getEndIndex. 1379 */ 1380 void NumberFormatRegressionTest::Test4062486(void) 1381 { 1382 UErrorCode status = U_ZERO_ERROR; 1383 DecimalFormat *fmt = new DecimalFormat(UnicodeString("#,##0.00"), status); 1384 failure(status, "new DecimalFormat"); 1385 UnicodeString formatted; 1386 FieldPosition field(0); 1387 double num = 1234.5; 1388 fmt->format(num, formatted, field); 1389 if (field.getBeginIndex() != 0 && field.getEndIndex() != 5) 1390 errln(UnicodeString("Format 1234.5 failed. Begin index: ") /*+ field.getBeginIndex() + " End index: " + field.getEndIndex()*/); 1391 field.setBeginIndex(7); 1392 field.setEndIndex(4); 1393 if (field.getBeginIndex() != 7 && field.getEndIndex() != 4) 1394 errln("Set begin/end field indexes failed. Begin index: " /*+ field.getBeginIndex() + " End index: " + field.getEndIndex()*/); 1395 1396 delete fmt; 1397 } 1398 1399 /* @bug 4108738 1400 * DecimalFormat.parse incorrectly works with a group separator. 1401 */ 1402 void NumberFormatRegressionTest::Test4108738(void) 1403 { 1404 UErrorCode status = U_ZERO_ERROR; 1405 DecimalFormatSymbols *syms = new DecimalFormatSymbols(Locale::getUS(), status); 1406 failure(status, "new DecimalFormatSymbols"); 1407 DecimalFormat *df = new DecimalFormat("#,##0.###", syms, status); 1408 if(U_FAILURE(status)) { 1409 errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status)); 1410 delete df; 1411 return; 1412 } 1413 failure(status, "new DecimalFormat"); 1414 UnicodeString text("1.222,111"); 1415 Formattable num; 1416 ParsePosition pp(0); 1417 df->parse(text, num, pp); 1418 1419 // {sfb} how to do this (again) ? 1420 // shouldn't just be another round-trip test, should it? 1421 UnicodeString temp; 1422 FieldPosition pos(FieldPosition::DONT_CARE); 1423 temp = df->format(num.getDouble(), temp, pos); 1424 //if (!num.toString().equals("1.222")) 1425 if (temp != UnicodeString("1.222")) 1426 //errln("\"" + text + "\" is parsed as " + num); 1427 errln("\"" + text + "\" is parsed as " + temp); 1428 text = UnicodeString("1.222x111"); 1429 pp = ParsePosition(0); 1430 df->parse(text, num, pp); 1431 temp.remove(); 1432 temp = df->format(num.getDouble(), temp, pos); 1433 //if (!num.toString().equals("1.222")) 1434 if (temp != UnicodeString("1.222")) 1435 errln("\"" + text + "\" is parsed as " + temp); 1436 1437 delete df; 1438 } 1439 1440 /* @bug 4106658 1441 * DecimalFormat.format() incorrectly formats negative doubles. 1442 */ 1443 void NumberFormatRegressionTest::Test4106658(void) 1444 { 1445 UErrorCode status = U_ZERO_ERROR; 1446 DecimalFormat *df = new DecimalFormat(status); // Corrected; see 4147706 1447 if(U_FAILURE(status)) { 1448 errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status)); 1449 delete df; 1450 return; 1451 } 1452 failure(status, "new DecimalFormat"); 1453 volatile double d1 = 0.0; // volatile to prevent code optimization 1454 double d2 = -0.0001; 1455 UnicodeString buffer; 1456 UnicodeString temp; 1457 FieldPosition pos(FieldPosition::DONT_CARE); 1458 1459 #if U_PLATFORM == U_PF_HPUX 1460 d1 = 0.0 * -1.0; // old HPUX compiler ignores volatile keyword 1461 #else 1462 d1 *= -1.0; // Some compilers have a problem with defining -0.0 1463 #endif 1464 logln("pattern: \"" + df->toPattern(temp) + "\""); 1465 df->format(d1, buffer, pos); 1466 if (buffer != UnicodeString("-0")) // Corrected; see 4147706 1467 errln(UnicodeString("") + d1 + " is formatted as " + buffer); 1468 buffer.remove(); 1469 df->format(d2, buffer, pos); 1470 if (buffer != UnicodeString("-0")) // Corrected; see 4147706 1471 errln(UnicodeString("") + d2 + " is formatted as " + buffer); 1472 1473 delete df; 1474 } 1475 1476 /* @bug 4106662 1477 * DecimalFormat.parse returns 0 if string parameter is incorrect. 1478 */ 1479 void NumberFormatRegressionTest::Test4106662(void) 1480 { 1481 UErrorCode status = U_ZERO_ERROR; 1482 DecimalFormat *df = new DecimalFormat(status); 1483 if(U_FAILURE(status)) { 1484 errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status)); 1485 delete df; 1486 return; 1487 } 1488 failure(status, "new DecimalFormat"); 1489 UnicodeString text("x"); 1490 ParsePosition pos1(0), pos2(0); 1491 1492 UnicodeString temp; 1493 logln("pattern: \"" + df->toPattern(temp) + "\""); 1494 Formattable num; 1495 df->parse(text, num, pos1); 1496 if (pos1 == ParsePosition(0)/*num != null*/) { 1497 errln(UnicodeString("Test Failed: \"") + text + "\" is parsed as " /*+ num*/); 1498 } 1499 delete df; 1500 df = new DecimalFormat(UnicodeString("$###.00"), status); 1501 failure(status, "new DecimalFormat"); 1502 df->parse(UnicodeString("$"), num, pos2); 1503 if (pos2 == ParsePosition(0) /*num != null*/){ 1504 errln(UnicodeString("Test Failed: \"$\" is parsed as ") /*+ num*/); 1505 } 1506 1507 delete df; 1508 } 1509 1510 /* @bug 4114639 (duplicate of 4106662) 1511 * NumberFormat.parse doesn't return null 1512 */ 1513 void NumberFormatRegressionTest::Test4114639(void) 1514 { 1515 UErrorCode status = U_ZERO_ERROR; 1516 NumberFormat *format = NumberFormat::createInstance(status); 1517 if(U_FAILURE(status)) { 1518 dataerrln("Error creating DecimalFormat: %s", u_errorName(status)); 1519 delete format; 1520 return; 1521 } 1522 failure(status, "NumberFormat::createInstance"); 1523 UnicodeString text("time 10:x"); 1524 ParsePosition pos(8); 1525 Formattable result; 1526 format->parse(text, result, pos); 1527 if (/*result != null*/pos.getErrorIndex() != 8) 1528 errln(UnicodeString("Should return null but got : ") /*+ result*/); // Should be null; it isn't 1529 1530 delete format; 1531 } 1532 1533 /* @bug 4106664 1534 * TODO: this test does not work because we need to use a 64 bit number and a 1535 * a double only MAY only have 52 bits of precision. 1536 * DecimalFormat.format(long n) fails if n * multiplier > MAX_LONG. 1537 */ 1538 void NumberFormatRegressionTest::Test4106664(void) 1539 { 1540 UErrorCode status = U_ZERO_ERROR; 1541 DecimalFormat *df = new DecimalFormat(status); 1542 if(U_FAILURE(status)) { 1543 errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status)); 1544 delete df; 1545 return; 1546 } 1547 failure(status, "new DecimalFormat"); 1548 // {sfb} long in java is 64 bits 1549 /*long*/double n = 1234567890123456.0; 1550 /*int*/int32_t m = 12345678; 1551 // {sfb} will this work? 1552 //BigInteger bigN = BigInteger.valueOf(n); 1553 //bigN = bigN.multiply(BigInteger.valueOf(m)); 1554 double bigN = n * m; 1555 df->setMultiplier(m); 1556 df->setGroupingUsed(FALSE); 1557 UnicodeString temp; 1558 FieldPosition pos(FieldPosition::DONT_CARE); 1559 logln("formated: " + 1560 df->format(n, temp, pos)); 1561 1562 char buf [128]; 1563 sprintf(buf, "%g", bigN); 1564 //logln("expected: " + bigN.toString()); 1565 logln(UnicodeString("expected: ") + buf); 1566 1567 delete df; 1568 } 1569 /* @bug 4106667 (duplicate of 4106658) 1570 * DecimalFormat.format incorrectly formats -0.0. 1571 */ 1572 void NumberFormatRegressionTest::Test4106667(void) 1573 { 1574 UErrorCode status = U_ZERO_ERROR; 1575 DecimalFormat *df = new DecimalFormat(status); 1576 if(U_FAILURE(status)) { 1577 errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status)); 1578 delete df; 1579 return; 1580 } 1581 failure(status, "new DecimalFormat"); 1582 UChar foo [] = { 0x002B }; 1583 UnicodeString bar(foo, 1, 1); 1584 volatile double d = 0.0; // volatile to prevent code optimization 1585 UnicodeString temp; 1586 UnicodeString buffer; 1587 FieldPosition pos(FieldPosition::DONT_CARE); 1588 1589 logln("pattern: \"" + df->toPattern(temp) + "\""); 1590 #if U_PLATFORM == U_PF_HPUX 1591 d = 0.0 * -1.0; // old HPUX compiler ignores volatile keyword 1592 #else 1593 d *= -1.0; // Some compilers have a problem with defining -0.0 1594 #endif 1595 df->setPositivePrefix(/*"+"*/bar); 1596 df->format(d, buffer, pos); 1597 if (buffer != UnicodeString("-0")) // Corrected; see 4147706 1598 errln(/*d + */UnicodeString(" is formatted as ") + buffer); 1599 1600 delete df; 1601 } 1602 1603 /* @bug 4110936 1604 * DecimalFormat.setMaximumIntegerDigits() works incorrectly. 1605 */ 1606 #if U_PLATFORM == U_PF_OS390 1607 # define MAX_INT_DIGITS 70 1608 #else 1609 # define MAX_INT_DIGITS 128 1610 #endif 1611 1612 void NumberFormatRegressionTest::Test4110936(void) 1613 { 1614 UErrorCode status = U_ZERO_ERROR; 1615 NumberFormat *nf = NumberFormat::createInstance(status); 1616 if(U_FAILURE(status)) { 1617 dataerrln("Error creating DecimalFormat: %s", u_errorName(status)); 1618 delete nf; 1619 return; 1620 } 1621 failure(status, "NumberFormat::createInstance"); 1622 nf->setMaximumIntegerDigits(MAX_INT_DIGITS); 1623 logln("setMaximumIntegerDigits(MAX_INT_DIGITS)"); 1624 if (nf->getMaximumIntegerDigits() != MAX_INT_DIGITS) 1625 errln(UnicodeString("getMaximumIntegerDigits() returns ") + 1626 nf->getMaximumIntegerDigits()); 1627 1628 delete nf; 1629 } 1630 1631 /* @bug 4122840 1632 * Locale data should use generic currency symbol 1633 * 1634 * 1) Make sure that all currency formats use the generic currency symbol. 1635 * 2) Make sure we get the same results using the generic symbol or a 1636 * hard-coded one. 1637 */ 1638 void NumberFormatRegressionTest::Test4122840(void) 1639 { 1640 int32_t count = 0; 1641 const Locale *locales = Locale::getAvailableLocales(count); 1642 1643 for (int i = 0; i < count; i++) { 1644 UErrorCode status = U_ZERO_ERROR; 1645 ResourceBundle *rb = new ResourceBundle( 1646 NULL/*"java.text.resources.LocaleElements"*/, 1647 locales[i], status); 1648 failure(status, "new ResourceBundle"); 1649 ResourceBundle numPat = rb->getWithFallback("NumberElements", status); 1650 failure(status, "rb.get(NumberElements)"); 1651 numPat = numPat.getWithFallback("latn",status); 1652 failure(status, "rb.get(latn)"); 1653 numPat = numPat.getWithFallback("patterns",status); 1654 failure(status, "rb.get(patterns)"); 1655 numPat = numPat.getWithFallback("currencyFormat",status); 1656 failure(status, "rb.get(currencyFormat)"); 1657 // 1658 // Get the currency pattern for this locale. We have to fish it 1659 // out of the ResourceBundle directly, since DecimalFormat.toPattern 1660 // will return the localized symbol, not \00a4 1661 // 1662 UnicodeString pattern = numPat.getString(status); 1663 failure(status, "rb->getString()"); 1664 1665 UChar fo[] = { 0x00A4 }; 1666 UnicodeString foo(fo, 1, 1); 1667 1668 //if (pattern.indexOf("\u00A4") == -1 ) { 1669 if (pattern.indexOf(foo) == -1 ) { 1670 errln(UnicodeString("Currency format for ") + UnicodeString(locales[i].getName()) + 1671 " does not contain generic currency symbol:" + 1672 pattern ); 1673 } 1674 1675 // Create a DecimalFormat using the pattern we got and format a number 1676 DecimalFormatSymbols *symbols = new DecimalFormatSymbols(locales[i], status); 1677 failure(status, "new DecimalFormatSymbols"); 1678 DecimalFormat *fmt1 = new DecimalFormat(pattern, *symbols, status); 1679 failure(status, "new DecimalFormat"); 1680 1681 UnicodeString result1; 1682 FieldPosition pos(FieldPosition::DONT_CARE); 1683 result1 = fmt1->format(1.111, result1, pos); 1684 1685 // 1686 // Now substitute in the locale's currency symbol and create another 1687 // pattern. We have to skip locales where the currency symbol 1688 // contains decimal separators, because that confuses things 1689 // 1690 UChar ba[] = { 0x002E/*'.'*/ }; 1691 UnicodeString bar(ba, 1, 1); 1692 1693 if (symbols->getSymbol(DecimalFormatSymbols::kCurrencySymbol).indexOf(bar) == -1) { 1694 // {sfb} Also, switch the decimal separator to the monetary decimal 1695 // separator to mimic the behavior of a currency format 1696 symbols->setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol, 1697 symbols->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol)); 1698 1699 UnicodeString buf(pattern); 1700 for (int j = 0; j < buf.length(); j++) { 1701 if (buf[j] == 0x00a4 ) { 1702 if(buf[j + 1] == 0x00a4) { 1703 // {sfb} added to support double currency marker (intl currency sign) 1704 buf.replace(j, /*j+*/2, symbols->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol)); 1705 j += symbols->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol).length(); 1706 } 1707 else { 1708 buf.replace(j, /*j+*/1, symbols->getSymbol(DecimalFormatSymbols::kCurrencySymbol)); 1709 j += symbols->getSymbol(DecimalFormatSymbols::kCurrencySymbol).length() - 1; 1710 } 1711 } 1712 } 1713 1714 DecimalFormat *fmt2 = new DecimalFormat(buf, *symbols, status); 1715 failure(status, "new DecimalFormat"); 1716 1717 // Get the currency (if there is one) so we can set the rounding and fraction 1718 const UChar *currency = fmt1->getCurrency(); 1719 if (*currency != 0) { 1720 double rounding = ucurr_getRoundingIncrement(currency, &status); 1721 int32_t frac = ucurr_getDefaultFractionDigits(currency, &status); 1722 if (U_SUCCESS(status)) { 1723 fmt2->setRoundingIncrement(rounding); 1724 fmt2->setMinimumFractionDigits(frac); 1725 fmt2->setMaximumFractionDigits(frac); 1726 } 1727 else { 1728 failure(status, "Fetching currency rounding/fractions"); 1729 } 1730 } 1731 1732 UnicodeString result2; 1733 fmt2->format(1.111, result2, pos); 1734 1735 if (result1 != result2) { 1736 errln("Results for " + (UnicodeString)(locales[i].getName()) + " differ: " + 1737 result1 + " vs " + result2); 1738 } 1739 1740 delete fmt2; 1741 } 1742 1743 delete rb; 1744 delete fmt1; 1745 delete symbols; 1746 } 1747 } 1748 1749 /* @bug 4125885 1750 * DecimalFormat.format() delivers wrong string. 1751 */ 1752 void NumberFormatRegressionTest::Test4125885(void) 1753 { 1754 UErrorCode status = U_ZERO_ERROR; 1755 double rate = 12.34; 1756 DecimalFormat *formatDec = new DecimalFormat ("000.00", status); 1757 if(U_FAILURE(status)) { 1758 errcheckln(status, "Error creating DecimalFormat: %s", u_errorName(status)); 1759 delete formatDec; 1760 return; 1761 } 1762 failure(status, "new DecimalFormat"); 1763 UnicodeString temp; 1764 logln("toPattern: " + formatDec->toPattern(temp)); 1765 UnicodeString rateString; 1766 FieldPosition pos(FieldPosition::DONT_CARE); 1767 rateString = formatDec->format(rate, rateString, pos); 1768 if (rateString != UnicodeString("012.34")) 1769 errln("result : " + rateString + " expected : 012.34"); 1770 rate = 0.1234; 1771 delete formatDec;// = null; 1772 formatDec = new DecimalFormat ("+000.00%;-000.00%", status); 1773 failure(status, "new DecimalFormat"); 1774 logln("toPattern: " + formatDec->toPattern(temp)); 1775 rateString.remove(); 1776 rateString = formatDec->format(rate, rateString, pos); 1777 if (rateString != UnicodeString("+012.34%")) 1778 errln("result : " + rateString + " expected : +012.34%"); 1779 1780 delete formatDec; 1781 } 1782 1783 /** 1784 * @bug 4134034 1785 * DecimalFormat produces extra zeros when formatting numbers. 1786 */ 1787 void NumberFormatRegressionTest::Test4134034(void) 1788 { 1789 UErrorCode status = U_ZERO_ERROR; 1790 DecimalFormat *nf = new DecimalFormat("##,###,###.00", status); 1791 if (!failure(status, "new DecimalFormat")) { 1792 UnicodeString f; 1793 FieldPosition pos(FieldPosition::DONT_CARE); 1794 f = nf->format(9.02, f, pos); 1795 if (f == UnicodeString("9.02")) 1796 logln(f + " ok"); 1797 else 1798 errln("9.02 -> " + f + "; want 9.02"); 1799 1800 f.remove(); 1801 f = nf->format((int32_t)0, f, pos); 1802 if (f == UnicodeString(".00")) 1803 logln(f + " ok"); 1804 else 1805 errln("0 -> " + f + "; want .00"); 1806 } 1807 1808 delete nf; 1809 } 1810 1811 /** 1812 * @bug 4134300 1813 * CANNOT REPRODUCE - This bug could not be reproduced. It may be 1814 * a duplicate of 4134034. 1815 * 1816 * JDK 1.1.6 Bug, did NOT occur in 1.1.5 1817 * Possibly related to bug 4125885. 1818 * 1819 * This class demonstrates a regression in version 1.1.6 1820 * of DecimalFormat class. 1821 * 1822 * 1.1.6 Results 1823 * Value 1.2 Format #.00 Result '01.20' !!!wrong 1824 * Value 1.2 Format 0.00 Result '001.20' !!!wrong 1825 * Value 1.2 Format 00.00 Result '0001.20' !!!wrong 1826 * Value 1.2 Format #0.0# Result '1.2' 1827 * Value 1.2 Format #0.00 Result '001.20' !!!wrong 1828 * 1829 * 1.1.5 Results 1830 * Value 1.2 Format #.00 Result '1.20' 1831 * Value 1.2 Format 0.00 Result '1.20' 1832 * Value 1.2 Format 00.00 Result '01.20' 1833 * Value 1.2 Format #0.0# Result '1.2' 1834 * Value 1.2 Format #0.00 Result '1.20' 1835 */ 1836 void NumberFormatRegressionTest::Test4134300(void) { 1837 UnicodeString DATA [] = { 1838 // Pattern Expected string 1839 UnicodeString("#.00"), UnicodeString("1.20"), 1840 UnicodeString("0.00"), UnicodeString("1.20"), 1841 UnicodeString("00.00"), UnicodeString("01.20"), 1842 UnicodeString("#0.0#"), UnicodeString("1.2"), 1843 UnicodeString("#0.00"), UnicodeString("1.20") 1844 }; 1845 1846 for (int i=0; i< 10; i+=2) { 1847 UnicodeString result; 1848 UErrorCode status = U_ZERO_ERROR; 1849 DecimalFormat *df = new DecimalFormat(DATA[i], status); 1850 if (!failure(status, "new DecimalFormat")) { 1851 FieldPosition pos(FieldPosition::DONT_CARE); 1852 result = df->format(1.2, result, pos); 1853 if (result != DATA[i+1]) { 1854 errln("Fail: 1.2 x " + DATA[i] + " = " + result + 1855 "; want " + DATA[i+1]); 1856 } 1857 else { 1858 logln("Ok: 1.2 x " + DATA[i] + " = " + result); 1859 } 1860 } 1861 1862 delete df; 1863 } 1864 } 1865 1866 /** 1867 * @bug 4140009 1868 * Empty pattern produces double negative prefix. 1869 */ 1870 void NumberFormatRegressionTest::Test4140009(void) 1871 { 1872 UErrorCode status = U_ZERO_ERROR; 1873 DecimalFormatSymbols *syms = new DecimalFormatSymbols(Locale::getEnglish(), status); 1874 failure(status, "new DecimalFormatSymbols"); 1875 DecimalFormat *f = new DecimalFormat(UnicodeString(""), syms, status); 1876 if (!failure(status, "new DecimalFormat")) { 1877 UnicodeString s; 1878 FieldPosition pos(FieldPosition::DONT_CARE); 1879 s = f->format(123.456, s, pos); 1880 if (s != UnicodeString("123.456")) 1881 errln("Fail: Format empty pattern x 123.456 => " + s); 1882 s.remove(); 1883 s = f->format(-123.456, s, pos); 1884 if (s != UnicodeString("-123.456")) 1885 errln("Fail: Format empty pattern x -123.456 => " + s); 1886 } 1887 delete f; 1888 } 1889 1890 /** 1891 * @bug 4141750 1892 * BigDecimal numbers get their fractions truncated by NumberFormat. 1893 */ 1894 // {sfb} not pertinent in C++ ?? 1895 void NumberFormatRegressionTest::Test4141750(void) { 1896 /*try { 1897 UnicodeString str("12345.67"); 1898 BigDecimal bd = new BigDecimal(str); 1899 String sd = NumberFormat.getInstance(Locale.US).format(bd); 1900 if (!sd.endsWith("67")) errln("Fail: " + str + " x format -> " + sd); 1901 } 1902 catch (Exception e) { 1903 errln(e.toString()); 1904 e.printStackTrace(); 1905 }*/ 1906 } 1907 1908 /** 1909 * @bug 4145457 1910 * DecimalFormat toPattern() doesn't quote special characters or handle 1911 * single quotes. 1912 */ 1913 void NumberFormatRegressionTest::Test4145457() { 1914 //try { 1915 UErrorCode status = U_ZERO_ERROR; 1916 NumberFormat *nff = NumberFormat::createInstance(status); 1917 if (failure(status, "NumberFormat::createInstance", TRUE)){ 1918 delete nff; 1919 return; 1920 }; 1921 DecimalFormat *nf = dynamic_cast<DecimalFormat *>(nff); 1922 if(nf == NULL) { 1923 errln("DecimalFormat needed to continue"); 1924 return; 1925 } 1926 1927 DecimalFormatSymbols *sym = (DecimalFormatSymbols*) nf->getDecimalFormatSymbols(); 1928 sym->setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol, (UChar)/*'\''*/0x0027); 1929 nf->setDecimalFormatSymbols(*sym); 1930 double pi = 3.14159; 1931 1932 UnicodeString PATS [] = { 1933 UnicodeString("#.00 'num''ber'"), UnicodeString("''#.00''") 1934 }; 1935 1936 for (int32_t i=0; i<2; ++i) { 1937 nf->applyPattern(PATS[i], status); 1938 failure(status, "nf->applyPattern"); 1939 UnicodeString out; 1940 FieldPosition pos(FieldPosition::DONT_CARE); 1941 out = nf->format(pi, out, pos); 1942 UnicodeString pat; 1943 pat = nf->toPattern(pat); 1944 Formattable num; 1945 ParsePosition pp(0); 1946 nf->parse(out, num, pp); 1947 double val = num.getDouble(); 1948 1949 nf->applyPattern(pat, status); 1950 failure(status, "nf->applyPattern"); 1951 UnicodeString out2; 1952 out2 = nf->format(pi, out2, pos); 1953 UnicodeString pat2; 1954 pat2 = nf->toPattern(pat2); 1955 pp.setIndex(0); 1956 nf->parse(out2, num, pp); 1957 double val2 = num.getDouble(); 1958 1959 if (pat != pat2) 1960 errln("Fail with \"" + PATS[i] + "\": Patterns should concur, \"" + 1961 pat + "\" vs. \"" + pat2 + "\""); 1962 else 1963 logln("Ok \"" + PATS[i] + "\" toPattern() -> \"" + pat + '"'); 1964 1965 if (val == val2 && out == out2) { 1966 logln(UnicodeString("Ok ") + pi + " x \"" + PATS[i] + "\" -> \"" + 1967 out + "\" -> " + val + " -> \"" + 1968 out2 + "\" -> " + val2); 1969 } 1970 else { 1971 errln(UnicodeString("Fail ") + pi + " x \"" + PATS[i] + "\" -> \"" + 1972 out + "\" -> " + val + " -> \"" + 1973 out2 + "\" -> " + val2); 1974 } 1975 } 1976 /*} 1977 catch (ParseException e) { 1978 errln("Fail: " + e); 1979 e.printStackTrace(); 1980 }*/ 1981 1982 delete nff; 1983 } 1984 1985 /** 1986 * @bug 4147295 1987 * DecimalFormat.applyPattern() sets minimum integer digits incorrectly. 1988 * CANNOT REPRODUCE 1989 * This bug is a duplicate of 4139344, which is a duplicate of 4134300 1990 */ 1991 void NumberFormatRegressionTest::Test4147295(void) 1992 { 1993 UErrorCode status = U_ZERO_ERROR; 1994 DecimalFormat *sdf = new DecimalFormat(status); 1995 UnicodeString pattern("#,###"); 1996 logln("Applying pattern \"" + pattern + "\""); 1997 sdf->applyPattern(pattern, status); 1998 if (!failure(status, "sdf->applyPattern")) { 1999 int minIntDig = sdf->getMinimumIntegerDigits(); 2000 if (minIntDig != 0) { 2001 errln("Test failed"); 2002 errln(UnicodeString(" Minimum integer digits : ") + minIntDig); 2003 UnicodeString temp; 2004 errln(UnicodeString(" new pattern: ") + sdf->toPattern(temp)); 2005 } else { 2006 logln("Test passed"); 2007 logln(UnicodeString(" Minimum integer digits : ") + minIntDig); 2008 } 2009 } 2010 delete sdf; 2011 } 2012 2013 /** 2014 * @bug 4147706 2015 * DecimalFormat formats -0.0 as +0.0 2016 * See also older related bug 4106658, 4106667 2017 */ 2018 void NumberFormatRegressionTest::Test4147706(void) 2019 { 2020 UErrorCode status = U_ZERO_ERROR; 2021 DecimalFormat *df = new DecimalFormat("#,##0.0##", status); 2022 failure(status, "new DecimalFormat"); 2023 DecimalFormatSymbols *syms = new DecimalFormatSymbols(Locale::getEnglish(), status); 2024 if (!failure(status, "new DecimalFormatSymbols")) { 2025 UnicodeString f1; 2026 UnicodeString f2, temp; 2027 FieldPosition pos(FieldPosition::DONT_CARE); 2028 volatile double d1 = 0.0; // volatile to prevent code optimization 2029 double d2 = -0.0001; 2030 2031 #if U_PLATFORM == U_PF_HPUX 2032 d1 = 0.0 * -1.0; // old HPUX compiler ignores volatile keyword 2033 #else 2034 d1 *= -1.0; // Some compilers have a problem with defining -0.0 2035 #endif 2036 df->adoptDecimalFormatSymbols(syms); 2037 f1 = df->format(d1, f1, pos); 2038 f2 = df->format(d2, f2, pos); 2039 if (f1 != UnicodeString("-0.0")) { 2040 errln(UnicodeString("") + d1 + UnicodeString(" x \"") + df->toPattern(temp) + "\" is formatted as \"" + f1 + '"'); 2041 } 2042 if (f2 != UnicodeString("-0.0")) { 2043 errln(UnicodeString("") + d2 + UnicodeString(" x \"") + df->toPattern(temp) + "\" is formatted as \"" + f2 + '"'); 2044 } 2045 } 2046 2047 delete df; 2048 } 2049 2050 2051 // Not applicable, since no serialization in C++ 2052 /*class myformat implements Serializable 2053 { 2054 DateFormat _dateFormat = DateFormat.getDateInstance(); 2055 2056 public String Now() 2057 { 2058 GregorianCalendar calendar = new GregorianCalendar(); 2059 Date t = calendar.getTime(); 2060 String nowStr = _dateFormat.format(t); 2061 return nowStr; 2062 } 2063 }*/ 2064 2065 /** 2066 * @bug 4162198 2067 * NumberFormat cannot format Double.MAX_VALUE 2068 */ 2069 // TODO: make this test actually test something 2070 void 2071 NumberFormatRegressionTest::Test4162198(void) 2072 { 2073 // for some reason, DBL_MAX will not round trip. (bug in sprintf/atof) 2074 double dbl = INT32_MAX * 1000.0; 2075 UErrorCode status = U_ZERO_ERROR; 2076 NumberFormat *f = NumberFormat::createInstance(status); 2077 if(U_FAILURE(status)) { 2078 dataerrln("Couldn't create number format - %s", u_errorName(status)); 2079 return; 2080 } 2081 f->setMaximumFractionDigits(INT32_MAX); 2082 f->setMaximumIntegerDigits(INT32_MAX); 2083 UnicodeString s; 2084 f->format(dbl,s); 2085 logln(UnicodeString("The number ") + dbl + " formatted to " + s); 2086 Formattable n; 2087 //try { 2088 f->parse(s, n, status); 2089 if(U_FAILURE(status)) 2090 errln("Couldn't parse!"); 2091 //} catch (java.text.ParseException e) { 2092 // errln("Caught a ParseException:"); 2093 // e.printStackTrace(); 2094 //} 2095 2096 //logln("The string " + s + " parsed as " + n); 2097 2098 // {dlf} The old code assumes n is a double, but it isn't any more... 2099 // Formattable apparently does not and never did interconvert... too bad. 2100 //if(n.getDouble() != dbl) { 2101 // errln("Round trip failure"); 2102 //} 2103 if (n.getInt64() != dbl) { 2104 errln("Round trip failure"); 2105 } 2106 2107 delete f; 2108 } 2109 2110 /** 2111 * @bug 4162852 2112 * NumberFormat does not parse negative zero. 2113 */ 2114 void 2115 NumberFormatRegressionTest::Test4162852(void) 2116 { 2117 UErrorCode status = U_ZERO_ERROR; 2118 for(int32_t i=0; i < 2; ++i) { 2119 NumberFormat *f = (i == 0) ? NumberFormat::createInstance(status) 2120 : NumberFormat::createPercentInstance(status); 2121 if(U_FAILURE(status)) { 2122 dataerrln("Couldn't create number format - %s", u_errorName(status)); 2123 return; 2124 } 2125 double d = 0.0; 2126 d *= -1.0; 2127 UnicodeString s; 2128 f->format(d, s); 2129 Formattable n; 2130 f->parse(s, n, status); 2131 if(U_FAILURE(status)) 2132 errln("Couldn't parse!"); 2133 double e = n.getDouble(); 2134 logln(UnicodeString("") + 2135 d + " -> " + 2136 '"' + s + '"' + " -> " + e); 2137 #if (U_PLATFORM == U_PF_OS390 && !defined(IEEE_754)) || U_PLATFORM == U_PF_OS400 2138 if (e != 0.0) { 2139 #else 2140 if (e != 0.0 || 1.0/e > 0.0) { 2141 #endif 2142 logln("Failed to parse negative zero"); 2143 } 2144 delete f; 2145 } 2146 } 2147 2148 static double _u_abs(double a) { return a<0?-a:a; } 2149 2150 /** 2151 * May 17 1999 sync up - liu 2152 * @bug 4167494 2153 * NumberFormat truncates data 2154 */ 2155 void NumberFormatRegressionTest::Test4167494(void) { 2156 UErrorCode status = U_ZERO_ERROR; 2157 NumberFormat *fmt = NumberFormat::createInstance(Locale::getUS(), status); 2158 if (failure(status, "NumberFormat::createInstance", TRUE)){ 2159 delete fmt; 2160 return; 2161 }; 2162 2163 double a = DBL_MAX * 0.99; // DBL_MAX itself overflows to +Inf 2164 UnicodeString s; 2165 fmt->format(a, s); 2166 Formattable num; 2167 fmt->parse(s, num, status); 2168 failure(status, "Parse"); 2169 if (num.getType() == Formattable::kDouble && 2170 _u_abs(num.getDouble() - a) / a < 0.01) { // RT within 1% 2171 logln(UnicodeString("") + a + " -> \"" + s + "\" -> " + 2172 toString(num) + " ok"); 2173 } else { 2174 errln(UnicodeString("") + a + " -> \"" + s + "\" -> " + 2175 toString(num) + " FAIL"); 2176 } 2177 2178 // We don't test Double.MIN_VALUE because the locale data for the US 2179 // currently doesn't specify enough digits to display Double.MIN_VALUE. 2180 // This is correct for now; however, we leave this here as a reminder 2181 // in case we want to address this later. 2182 2183 delete fmt; 2184 } 2185 2186 /** 2187 * May 17 1999 sync up - liu 2188 * @bug 4170798 2189 * DecimalFormat.parse() fails when ParseIntegerOnly set to true 2190 */ 2191 void NumberFormatRegressionTest::Test4170798(void) { 2192 UErrorCode status = U_ZERO_ERROR; 2193 NumberFormat *nf = NumberFormat::createInstance(Locale::getUS(), status); 2194 if (failure(status, "NumberFormat::createInstance", TRUE)){ 2195 delete nf; 2196 return; 2197 }; 2198 DecimalFormat *df = dynamic_cast<DecimalFormat *>(nf); 2199 if(df == NULL) { 2200 errln("DecimalFormat needed to continue"); 2201 return; 2202 } 2203 df->setParseIntegerOnly(TRUE); 2204 Formattable n; 2205 ParsePosition pos(0); 2206 df->parse("-0.0", n, pos); 2207 if (n.getType() != Formattable::kLong 2208 || n.getLong() != 0) { 2209 errln(UnicodeString("FAIL: parse(\"-0.0\") returns ") + toString(n)); 2210 } 2211 delete nf; 2212 } 2213 2214 /** 2215 * May 17 1999 sync up - liu 2216 * toPattern only puts the first grouping separator in. 2217 */ 2218 void NumberFormatRegressionTest::Test4176114(void) { 2219 const char* DATA[] = { 2220 "00", "#00", 2221 "000", "#000", // No grouping 2222 "#000", "#000", // No grouping 2223 "#,##0", "#,##0", 2224 "#,000", "#,000", 2225 "0,000", "#0,000", 2226 "00,000", "#00,000", 2227 "000,000", "#,000,000", 2228 "0,000,000,000,000.0000", "#0,000,000,000,000.0000", // Reported 2229 }; 2230 int DATA_length = (int)(sizeof(DATA) / sizeof(DATA[0])); 2231 UErrorCode status = U_ZERO_ERROR; 2232 UnicodeString s; 2233 for (int i=0; i<DATA_length; i+=2) { 2234 DecimalFormat df(DATA[i], status); 2235 if (!failure(status, "DecimalFormat constructor")) { 2236 df.toPattern(s); 2237 UnicodeString exp(DATA[i+1]); 2238 if (s != exp) { 2239 errln(UnicodeString("FAIL: ") + DATA[i] + " -> " + 2240 s + ", want " + exp); 2241 } 2242 } 2243 } 2244 } 2245 2246 /** 2247 * May 17 1999 sync up - liu 2248 * @bug 4179818 2249 * DecimalFormat is incorrectly rounding numbers like 1.2501 to 1.2 2250 */ 2251 void NumberFormatRegressionTest::Test4179818(void) { 2252 const char* DATA[] = { 2253 // Input Pattern Expected output 2254 "1.2511", "#.#", "1.3", 2255 "1.2501", "#.#", "1.3", 2256 "0.9999", "#", "1", 2257 }; 2258 int DATA_length = (int)(sizeof(DATA) / sizeof(DATA[0])); 2259 double DOUBLE[] = { 2260 1.2511, 2261 1.2501, 2262 0.9999, 2263 }; 2264 UErrorCode status = U_ZERO_ERROR; 2265 DecimalFormatSymbols sym(Locale::getUS(), status); 2266 failure(status, "Construct DecimalFormatSymbols"); 2267 DecimalFormat fmt("#", sym, status); 2268 if (!failure(status, "Construct DecimalFormat")) { 2269 for (int i=0; i<DATA_length; i+=3) { 2270 double in = DOUBLE[i/3]; 2271 UnicodeString pat(DATA[i+1]); 2272 UnicodeString exp(DATA[i+2]); 2273 fmt.applyPattern(pat, status); 2274 failure(status, "applyPattern"); 2275 UnicodeString out; 2276 FieldPosition pos; 2277 fmt.format(in, out, pos); 2278 if (out == exp) { 2279 logln(UnicodeString("Ok: ") + in + " x " + pat + " = " + out); 2280 } else { 2281 errln(UnicodeString("FAIL: ") + in + " x " + pat + " = " + out + 2282 ", expected " + exp); 2283 } 2284 } 2285 } 2286 } 2287 2288 /** 2289 * May 17 1999 sync up - liu 2290 * Some DecimalFormatSymbols changes are not picked up by DecimalFormat. 2291 * This includes the minus sign, currency symbol, international currency 2292 * symbol, percent, and permille. This is filed as bugs 4212072 and 2293 * 4212073. 2294 */ 2295 void NumberFormatRegressionTest::Test4212072(void) { 2296 UErrorCode status = U_ZERO_ERROR; 2297 DecimalFormatSymbols sym(Locale::getUS(), status); 2298 2299 failure(status, "DecimalFormatSymbols ct", Locale::getUS()); 2300 DecimalFormat fmt(UnicodeString("#"), sym, status); 2301 if(failure(status, "DecimalFormat ct", Locale::getUS())) { 2302 return; 2303 } 2304 2305 UnicodeString s; 2306 FieldPosition pos; 2307 2308 sym.setSymbol(DecimalFormatSymbols::kMinusSignSymbol, (UChar)0x5e); 2309 fmt.setDecimalFormatSymbols(sym); 2310 s.remove(); 2311 if (fmt.format((int32_t)-1, s, pos) != UNICODE_STRING("^1", 2)) { 2312 errln(UnicodeString("FAIL: -1 x (minus=^) -> ") + s + 2313 ", exp ^1"); 2314 } 2315 s.remove(); 2316 if (fmt.getNegativePrefix(s) != UnicodeString((UChar)0x5e)) { 2317 errln(UnicodeString("FAIL: (minus=^).getNegativePrefix -> ") + 2318 s + ", exp ^"); 2319 } 2320 sym.setSymbol(DecimalFormatSymbols::kMinusSignSymbol, (UChar)0x2d); 2321 2322 fmt.applyPattern(UnicodeString("#%"), status); 2323 failure(status, "applyPattern percent"); 2324 sym.setSymbol(DecimalFormatSymbols::kPercentSymbol, (UChar)0x5e); 2325 fmt.setDecimalFormatSymbols(sym); 2326 s.remove(); 2327 if (fmt.format(0.25, s, pos) != UNICODE_STRING("25^", 3)) { 2328 errln(UnicodeString("FAIL: 0.25 x (percent=^) -> ") + s + 2329 ", exp 25^"); 2330 } 2331 s.remove(); 2332 if (fmt.getPositiveSuffix(s) != UnicodeString((UChar)0x5e)) { 2333 errln(UnicodeString("FAIL: (percent=^).getPositiveSuffix -> ") + 2334 s + ", exp ^"); 2335 } 2336 sym.setSymbol(DecimalFormatSymbols::kPercentSymbol, (UChar)0x25); 2337 2338 fmt.applyPattern(str("#\\u2030"), status); 2339 failure(status, "applyPattern permill"); 2340 sym.setSymbol(DecimalFormatSymbols::kPerMillSymbol, (UChar)0x5e); 2341 fmt.setDecimalFormatSymbols(sym); 2342 s.remove(); 2343 if (fmt.format(0.25, s, pos) != UNICODE_STRING("250^", 4)) { 2344 errln(UnicodeString("FAIL: 0.25 x (permill=^) -> ") + s + 2345 ", exp 250^"); 2346 } 2347 s.remove(); 2348 if (fmt.getPositiveSuffix(s) != UnicodeString((UChar)0x5e)) { 2349 errln(UnicodeString("FAIL: (permill=^).getPositiveSuffix -> ") + 2350 s + ", exp ^"); 2351 } 2352 sym.setSymbol(DecimalFormatSymbols::kPerMillSymbol, (UChar)0x2030); 2353 2354 fmt.applyPattern(str("\\u00A4#.00"), status); 2355 failure(status, "applyPattern currency"); 2356 sym.setSymbol(DecimalFormatSymbols::kCurrencySymbol, "usd"); 2357 fmt.setDecimalFormatSymbols(sym); 2358 s.remove(); 2359 if (fmt.format(12.5, s, pos) != UnicodeString("usd12.50")) { 2360 errln(UnicodeString("FAIL: 12.5 x (currency=usd) -> ") + s + 2361 ", exp usd12.50"); 2362 } 2363 s.remove(); 2364 if (fmt.getPositivePrefix(s) != UnicodeString("usd")) { 2365 errln(UnicodeString("FAIL: (currency=usd).getPositivePrefix -> ") + 2366 s + ", exp usd"); 2367 } 2368 sym.setSymbol(DecimalFormatSymbols::kCurrencySymbol, "$"); 2369 2370 fmt.applyPattern(str("\\u00A4\\u00A4#.00"), status); 2371 failure(status, "applyPattern intl currency"); 2372 sym.setSymbol(DecimalFormatSymbols::kIntlCurrencySymbol, "DOL"); 2373 fmt.setDecimalFormatSymbols(sym); 2374 s.remove(); 2375 if (fmt.format(12.5, s, pos) != UnicodeString("DOL12.50")) { 2376 errln(UnicodeString("FAIL: 12.5 x (intlcurrency=DOL) -> ") + s + 2377 ", exp DOL12.50"); 2378 } 2379 s.remove(); 2380 if (fmt.getPositivePrefix(s) != UnicodeString("DOL")) { 2381 errln(UnicodeString("FAIL: (intlcurrency=DOL).getPositivePrefix -> ") + 2382 s + ", exp DOL"); 2383 } 2384 sym.setSymbol(DecimalFormatSymbols::kIntlCurrencySymbol, "USD"); 2385 2386 // Since the pattern logic has changed, make sure that patterns round 2387 // trip properly. Test stream in/out integrity too. 2388 int32_t n; 2389 const Locale* avail = NumberFormat::getAvailableLocales(n); 2390 static const char* type[] = { 2391 "", 2392 "$ ", 2393 "% ", 2394 }; 2395 for (int i=0; i<n; ++i) { 2396 for (int j=0; j<3; ++j) { 2397 status = U_ZERO_ERROR; 2398 NumberFormat *nf; 2399 switch (j) { 2400 case 0: 2401 nf = NumberFormat::createInstance(avail[i], status); 2402 failure(status, "createInstance", avail[i]); 2403 break; 2404 case 1: 2405 nf = NumberFormat::createCurrencyInstance(avail[i], status); 2406 failure(status, "createCurrencyInstance", avail[i]); 2407 break; 2408 default: 2409 nf = NumberFormat::createPercentInstance(avail[i], status); 2410 failure(status, "createPercentInstance", avail[i]); 2411 break; 2412 } 2413 if (U_FAILURE(status)) { 2414 continue; 2415 } 2416 DecimalFormat *df = (DecimalFormat*) nf; 2417 2418 // Test toPattern/applyPattern round trip 2419 UnicodeString pat; 2420 df->toPattern(pat); 2421 DecimalFormatSymbols symb(avail[i], status); 2422 failure(status, "Construct DecimalFormatSymbols", avail[i]); 2423 DecimalFormat f2(pat, symb, status); 2424 if (failure(status, 2425 UnicodeString("Construct DecimalFormat(") + pat + ")")) { 2426 continue; 2427 } 2428 if (*df != f2) { 2429 UnicodeString l, p; 2430 errln(UnicodeString("FAIL: ") + type[j] + avail[i].getDisplayName(l) + 2431 " -> \"" + pat + 2432 "\" -> \"" + f2.toPattern(p) + "\""); 2433 } else { 2434 UnicodeString l, p; 2435 logln(UnicodeString("PASS: ") + type[j] + avail[i].getDisplayName(l) + 2436 " -> \"" + pat + 2437 "\""); 2438 } 2439 2440 // Test toLocalizedPattern/applyLocalizedPattern round trip 2441 df->toLocalizedPattern(pat); 2442 f2.applyLocalizedPattern(pat, status); 2443 failure(status, 2444 UnicodeString("applyLocalizedPattern(") + pat + ")", avail[i]); 2445 if (U_FAILURE(status)) { 2446 continue; 2447 } 2448 2449 // Make sure we set the currency attributes appropriately 2450 if (j == 1) { // Currency format 2451 f2.setCurrency(f2.getCurrency(), status); 2452 } 2453 failure(status, 2454 UnicodeString("setCurrency() for (") + pat + ")", avail[i]); 2455 if (U_FAILURE(status)) { 2456 continue; 2457 } 2458 2459 if (*df != f2) { 2460 UnicodeString l, p; 2461 errln(UnicodeString("FAIL: ") + type[j] + avail[i].getDisplayName(l) + 2462 " -> localized \"" + pat + 2463 "\" -> \"" + f2.toPattern(p) + "\""); 2464 } 2465 2466 delete nf; 2467 2468 // Test writeObject/readObject round trip 2469 // NOT ON ICU -- Java only 2470 } 2471 } 2472 } 2473 2474 /** 2475 * May 17 1999 sync up - liu 2476 * DecimalFormat.parse() fails for mulipliers 2^n. 2477 */ 2478 void NumberFormatRegressionTest::Test4216742(void) { 2479 UErrorCode status = U_ZERO_ERROR; 2480 DecimalFormat *fmt = (DecimalFormat*) NumberFormat::createInstance(Locale::getUS(), status); 2481 if (failure(status, "createInstance", Locale::getUS(), TRUE)){ 2482 delete fmt; 2483 return; 2484 }; 2485 int32_t DATA[] = { INT32_MIN, INT32_MAX, -100000000, 100000000 }; 2486 int DATA_length = (int)(sizeof(DATA) / sizeof(DATA[0])); 2487 for (int i=0; i<DATA_length; ++i) { 2488 UnicodeString str((UnicodeString)"" + DATA[i]); 2489 for (int m = 1; m <= 100; m++) { 2490 fmt->setMultiplier(m); 2491 Formattable num; 2492 fmt->parse(str, num, status); 2493 failure(status, "parse", Locale::getUS()); 2494 if (num.getType() != Formattable::kLong && 2495 num.getType() != Formattable::kDouble) { 2496 errln(UnicodeString("FAIL: Wanted number, got ") + 2497 toString(num)); 2498 } else { 2499 double d = num.getType() == Formattable::kDouble ? 2500 num.getDouble() : (double) num.getLong(); 2501 if ((d > 0) != (DATA[i] > 0)) { 2502 errln(UnicodeString("\"") + str + "\" parse(x " + 2503 fmt->getMultiplier() + 2504 ") => " + toString(num)); 2505 } 2506 } 2507 } 2508 } 2509 delete fmt; 2510 } 2511 2512 /** 2513 * May 17 1999 sync up - liu 2514 * DecimalFormat formats 1.001 to "1.00" instead of "1" with 2 fraction 2515 * digits. 2516 */ 2517 void NumberFormatRegressionTest::Test4217661(void) { 2518 const double D[] = { 0.001, 1.001, 0.006, 1.006 }; 2519 const char* S[] = { "0", "1", "0.01", "1.01" }; 2520 int D_length = (int)(sizeof(D) / sizeof(D[0])); 2521 UErrorCode status = U_ZERO_ERROR; 2522 NumberFormat *fmt = NumberFormat::createInstance(Locale::getUS(), status); 2523 if (failure(status, "createInstance", Locale::getUS(), TRUE)){ 2524 delete fmt; 2525 return; 2526 }; 2527 fmt->setMaximumFractionDigits(2); 2528 for (int i=0; i<D_length; i++) { 2529 UnicodeString s; 2530 fmt->format(D[i], s); 2531 if (s != UnicodeString(S[i])) { 2532 errln(UnicodeString("FAIL: Got ") + s + ", exp " + S[i]); 2533 } 2534 } 2535 delete fmt; 2536 } 2537 2538 /** 2539 * alphaWorks upgrade 2540 */ 2541 void NumberFormatRegressionTest::Test4161100(void) { 2542 UErrorCode status = U_ZERO_ERROR; 2543 NumberFormat *nf = NumberFormat::createInstance(Locale::getUS(), status); 2544 if (failure(status, "createInstance", Locale::getUS(), TRUE)){ 2545 delete nf; 2546 return; 2547 }; 2548 nf->setMinimumFractionDigits(1); 2549 nf->setMaximumFractionDigits(1); 2550 double a = -0.09; 2551 UnicodeString s; 2552 nf->format(a, s); 2553 UnicodeString pat; 2554 logln(UnicodeString() + a + " x " + 2555 ((DecimalFormat*) nf)->toPattern(pat) + " = " + s); 2556 if (s != UnicodeString("-0.1")) { 2557 errln("FAIL"); 2558 } 2559 delete nf; 2560 } 2561 2562 /** 2563 * June 16 1999 sync up - liu 2564 * Formatting .5 rounds to "1" instead of "0". (Regression in 1.2.2 RC1) 2565 */ 2566 void NumberFormatRegressionTest::Test4243011(void) { 2567 UErrorCode status = U_ZERO_ERROR; 2568 DecimalFormatSymbols sym(Locale::getUS(), status); 2569 failure(status, "DecimalFormatSymbols ct", Locale::getUS()); 2570 DecimalFormat fmt(UnicodeString("0."), sym, status); 2571 2572 if (!failure(status, "DecimalFormat ct", Locale::getUS())) { 2573 const double NUM[] = { -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5 }; 2574 const char* STR[] = { "-2.", "-2.", "-0.", "0.", "2.", "2.", "4.", "4." }; 2575 int32_t N = (int32_t)(sizeof(NUM) / sizeof(NUM[0])); 2576 2577 for (int32_t i=0; i<N; ++i) { 2578 UnicodeString str; 2579 UnicodeString exp(STR[i]); 2580 FieldPosition pos; 2581 fmt.format(NUM[i], str, pos); 2582 if (str == exp) { 2583 logln(UnicodeString("Ok ") + NUM[i] + " x 0. = " + str); 2584 } else { 2585 errln(UnicodeString("FAIL ") + NUM[i] + " x 0. = " + str + 2586 ", want " + exp); 2587 } 2588 } 2589 } 2590 } 2591 2592 /** 2593 * June 16 1999 sync up - liu 2594 * format(0.0) gives "0.1" if preceded by parse("99.99"). 2595 * (Regression in 1.2.2 RC1) 2596 */ 2597 void NumberFormatRegressionTest::Test4243108(void) { 2598 UErrorCode status = U_ZERO_ERROR; 2599 DecimalFormatSymbols sym(Locale::getUS(), status); 2600 failure(status, "DecimalFormatSymbols ct", Locale::getUS()); 2601 DecimalFormat fmt(UnicodeString("#.#"), sym, status); 2602 if (failure(status, "DecimalFormat ct", Locale::getUS())) { 2603 return; 2604 } 2605 2606 UnicodeString str; 2607 FieldPosition pos; 2608 2609 fmt.format(0.0, str, pos); 2610 UnicodeString exp("0"); 2611 if (str == exp) { 2612 logln(UnicodeString("Ok 0.0 x #.# = ") + str); 2613 } else { 2614 errln(UnicodeString("FAIL 0.0 x #.# = ") + str + 2615 ", want " + exp); 2616 } 2617 2618 str = "99.99"; 2619 Formattable val; 2620 fmt.parse(str, val, status); 2621 failure(status, "DecimalFormat.parse(99.99)", Locale::getUS()); 2622 if (val.getType() == Formattable::kDouble && 2623 val.getDouble() == 99.99) { 2624 logln(UnicodeString("Ok 99.99 / #.# = ") + toString(val)); 2625 } else { 2626 errln(UnicodeString("FAIL 99.99 / #.# = ") + toString(val) + 2627 ", want " + 99.99); 2628 } 2629 2630 str.remove(); 2631 fmt.format(0.0, str, pos); 2632 if (str == exp) { 2633 logln(UnicodeString("Ok 0.0 x #.# = ") + str); 2634 } else { 2635 errln(UnicodeString("FAIL 0.0 x #.# = ") + str + 2636 ", want " + exp); 2637 } 2638 } 2639 2640 2641 /** 2642 * DateFormat should call setIntegerParseOnly(TRUE) on adopted 2643 * NumberFormat objects. 2644 */ 2645 void NumberFormatRegressionTest::TestJ691(void) { 2646 UErrorCode status = U_ZERO_ERROR; 2647 Locale loc("fr", "CH"); 2648 2649 // set up the input date string & expected output 2650 UnicodeString udt("11.10.2000", ""); 2651 UnicodeString exp("11.10.00", ""); 2652 2653 // create a Calendar for this locale 2654 Calendar *cal = Calendar::createInstance(loc, status); 2655 if (U_FAILURE(status)) { 2656 dataerrln("FAIL: Calendar::createInstance() returned " + (UnicodeString)u_errorName(status)); 2657 return; 2658 } 2659 2660 // create a NumberFormat for this locale 2661 NumberFormat *nf = NumberFormat::createInstance(loc, status); 2662 if (U_FAILURE(status)) { 2663 dataerrln("FAIL: NumberFormat::createInstance() returned " + (UnicodeString)u_errorName(status)); 2664 return; 2665 } 2666 2667 // *** Here's the key: We don't want to have to do THIS: 2668 // nf->setParseIntegerOnly(TRUE); 2669 2670 // create the DateFormat 2671 DateFormat *df = DateFormat::createDateInstance(DateFormat::kShort, loc); 2672 if (U_FAILURE(status)) { 2673 errln("FAIL: DateFormat::createInstance() returned " + (UnicodeString)u_errorName(status)); 2674 return; 2675 } 2676 2677 df->adoptCalendar(cal); 2678 df->adoptNumberFormat(nf); 2679 2680 // set parsing to lenient & parse 2681 df->setLenient(TRUE); 2682 UDate ulocdat = df->parse(udt, status); 2683 2684 // format back to a string 2685 UnicodeString outString; 2686 df->format(ulocdat, outString); 2687 2688 if (outString != exp) { 2689 errln("FAIL: " + udt + " => " + outString); 2690 } 2691 2692 delete df; 2693 } 2694 2695 //--------------------------------------------------------------------------- 2696 // 2697 // Error Checking / Reporting macros 2698 // 2699 //--------------------------------------------------------------------------- 2700 #define TEST_CHECK_STATUS(status) { \ 2701 if (U_FAILURE(status)) { \ 2702 if (status == U_MISSING_RESOURCE_ERROR) { \ 2703 dataerrln("File %s, Line %d: status=%s", __FILE__, __LINE__, u_errorName(status)); \ 2704 } else { \ 2705 errln("File %s, Line %d: status=%s", __FILE__, __LINE__, u_errorName(status)); \ 2706 } return; \ 2707 }} 2708 2709 #define TEST_ASSERT(expr) \ 2710 if ((expr)==FALSE) {\ 2711 errln("File %s, line %d: Assertion Failed: " #expr "\n", __FILE__, __LINE__);\ 2712 } 2713 2714 2715 // Ticket 8199: Parse failure for numbers in the range of 1E10 - 1E18 2716 2717 void NumberFormatRegressionTest::Test8199(void) { 2718 UErrorCode status = U_ZERO_ERROR; 2719 NumberFormat *nf = NumberFormat::createInstance(Locale::getEnglish(), status); 2720 if (nf == NULL) { 2721 dataerrln("Fail: NumberFormat::createInstance(Locale::getEnglish(), status)"); 2722 return; 2723 } 2724 TEST_CHECK_STATUS(status); 2725 2726 // Note: Retrieving parsed values from a Formattable as a reduced-precision type 2727 // should always truncate, no other rounding scheme. 2728 2729 UnicodeString numStr = "1000000000.6"; // 9 zeroes 2730 Formattable val; 2731 nf->parse(numStr, val, status); 2732 TEST_CHECK_STATUS(status); 2733 TEST_ASSERT(Formattable::kDouble == val.getType()); 2734 TEST_ASSERT(1000000000 == val.getInt64(status)); 2735 TEST_CHECK_STATUS(status); 2736 TEST_ASSERT(1000000000.6 == val.getDouble(status)); 2737 TEST_CHECK_STATUS(status); 2738 2739 numStr = "100000000000000001.1"; // approx 1E17, parses as a double rather 2740 // than int64 because of the fraction 2741 // even though int64 is more precise. 2742 nf->parse(numStr, val, status); 2743 TEST_CHECK_STATUS(status); 2744 TEST_ASSERT(Formattable::kDouble == val.getType()); 2745 TEST_ASSERT(100000000000000001LL == val.getInt64(status)); 2746 TEST_CHECK_STATUS(status); 2747 TEST_ASSERT(100000000000000000.0 == val.getDouble(status)); 2748 TEST_CHECK_STATUS(status); 2749 2750 numStr = "1E17"; // Parses with the internal decimal number having non-zero exponent 2751 nf->parse(numStr, val, status); 2752 TEST_CHECK_STATUS(status); 2753 TEST_ASSERT(Formattable::kInt64 == val.getType()); 2754 TEST_ASSERT(100000000000000000LL == val.getInt64()); 2755 TEST_ASSERT(1.0E17 == val.getDouble(status)); 2756 TEST_CHECK_STATUS(status); 2757 2758 numStr = "9223372036854775807"; // largest int64_t 2759 nf->parse(numStr, val, status); 2760 TEST_CHECK_STATUS(status); 2761 TEST_ASSERT(Formattable::kInt64 == val.getType()); 2762 TEST_ASSERT(9223372036854775807LL == val.getInt64()); 2763 // In the following check, note that a substantial range of integers will 2764 // convert to the same double value. There are also platform variations 2765 // in the rounding at compile time of double constants. 2766 TEST_ASSERT(9223372036854775808.0 >= val.getDouble(status)); 2767 TEST_ASSERT(9223372036854774700.0 <= val.getDouble(status)); 2768 TEST_CHECK_STATUS(status); 2769 2770 numStr = "-9223372036854775808"; // smallest int64_t 2771 nf->parse(numStr, val, status); 2772 TEST_CHECK_STATUS(status); 2773 TEST_ASSERT(Formattable::kInt64 == val.getType()); 2774 // TEST_ASSERT(-9223372036854775808LL == val.getInt64()); // Compiler chokes on constant. 2775 TEST_ASSERT((int64_t)0x8000000000000000LL == val.getInt64()); 2776 TEST_ASSERT(-9223372036854775808.0 == val.getDouble(status)); 2777 TEST_CHECK_STATUS(status); 2778 2779 numStr = "9223372036854775808"; // largest int64_t + 1 2780 nf->parse(numStr, val, status); 2781 TEST_CHECK_STATUS(status); 2782 TEST_ASSERT(Formattable::kDouble == val.getType()); 2783 TEST_ASSERT(9223372036854775807LL == val.getInt64(status)); 2784 TEST_ASSERT(status == U_INVALID_FORMAT_ERROR); 2785 status = U_ZERO_ERROR; 2786 TEST_ASSERT(9223372036854775810.0 == val.getDouble(status)); 2787 TEST_CHECK_STATUS(status); 2788 2789 numStr = "-9223372036854775809"; // smallest int64_t - 1 2790 nf->parse(numStr, val, status); 2791 TEST_CHECK_STATUS(status); 2792 TEST_ASSERT(Formattable::kDouble == val.getType()); 2793 // TEST_ASSERT(-9223372036854775808LL == val.getInt64(status)); // spurious compiler warnings 2794 TEST_ASSERT((int64_t)0x8000000000000000LL == val.getInt64(status)); 2795 TEST_ASSERT(status == U_INVALID_FORMAT_ERROR); 2796 status = U_ZERO_ERROR; 2797 TEST_ASSERT(-9223372036854775810.0 == val.getDouble(status)); 2798 TEST_CHECK_STATUS(status); 2799 2800 // Test values near the limit of where doubles can represent all integers. 2801 // The implementation strategy of getInt64() changes at this boundary. 2802 // Strings to be parsed include a decimal fraction to force them to be 2803 // parsed as doubles rather than ints. The fraction is discarded 2804 // from the parsed double value because it is beyond what can be represented. 2805 2806 status = U_ZERO_ERROR; 2807 numStr = "9007199254740991.1"; // largest 53 bit int 2808 nf->parse(numStr, val, status); 2809 TEST_CHECK_STATUS(status); 2810 // printf("getInt64() returns %lld\n", val.getInt64(status)); 2811 TEST_ASSERT(Formattable::kDouble == val.getType()); 2812 TEST_ASSERT(9007199254740991LL == val.getInt64(status)); 2813 TEST_ASSERT(9007199254740991.0 == val.getDouble(status)); 2814 TEST_CHECK_STATUS(status); 2815 2816 status = U_ZERO_ERROR; 2817 numStr = "9007199254740992.1"; // 54 bits for the int part. 2818 nf->parse(numStr, val, status); 2819 TEST_CHECK_STATUS(status); 2820 TEST_ASSERT(Formattable::kDouble == val.getType()); 2821 TEST_ASSERT(9007199254740992LL == val.getInt64(status)); 2822 TEST_ASSERT(9007199254740992.0 == val.getDouble(status)); 2823 TEST_CHECK_STATUS(status); 2824 2825 status = U_ZERO_ERROR; 2826 numStr = "9007199254740993.1"; // 54 bits for the int part. Double will round 2827 nf->parse(numStr, val, status); // the ones digit, putting it up to ...994 2828 TEST_CHECK_STATUS(status); 2829 TEST_ASSERT(Formattable::kDouble == val.getType()); 2830 TEST_ASSERT(9007199254740993LL == val.getInt64(status)); 2831 TEST_ASSERT(9007199254740994.0 == val.getDouble(status)); 2832 TEST_CHECK_STATUS(status); 2833 2834 delete nf; 2835 } 2836 2837 void NumberFormatRegressionTest::Test9109(void) { 2838 UErrorCode status = U_ZERO_ERROR; 2839 Formattable val; 2840 ParsePosition pos; 2841 DecimalFormat fmt("+##", status); 2842 fmt.setLenient(TRUE); 2843 2844 if (U_FAILURE(status)) { 2845 dataerrln("Failed to create DecimalFormat with pattern '+##' - %s", u_errorName(status)); 2846 } 2847 2848 UnicodeString text("123"); 2849 int32_t expected = 123; 2850 int32_t expos = 3; 2851 2852 fmt.parse(text, val, pos); 2853 if (pos.getErrorIndex() >= 0) { 2854 errln(UnicodeString("Parse failure at ") + pos.getErrorIndex()); 2855 } else if (val.getLong() != 123) { 2856 errln(UnicodeString("Incorrect parse result: ") + val.getLong() + " expected: " + expected); 2857 } else if (pos.getIndex() != 3) { 2858 errln(UnicodeString("Incorrect parse position: ") + pos.getIndex() + " expected: " + expos); 2859 } 2860 } 2861 2862 2863 void NumberFormatRegressionTest::Test9780(void) { 2864 UErrorCode status = U_ZERO_ERROR; 2865 NumberFormat *nf = NumberFormat::createInstance(Locale::getUS(), status); 2866 if (failure(status, "NumberFormat::createInstance", TRUE)){ 2867 delete nf; 2868 return; 2869 }; 2870 DecimalFormat *df = dynamic_cast<DecimalFormat *>(nf); 2871 if(df == NULL) { 2872 errln("DecimalFormat needed to continue"); 2873 return; 2874 } 2875 df->setParseIntegerOnly(TRUE); 2876 2877 { 2878 Formattable n; 2879 ParsePosition pos(0); 2880 UnicodeString toParse("1,234",""); 2881 df->parse(toParse, n, pos); 2882 if (n.getType() != Formattable::kLong 2883 || n.getLong() != 1234) { 2884 errln(UnicodeString("FAIL: parse(\"") + toParse + UnicodeString("\") returns ") + toString(n)); 2885 } 2886 } 2887 // should still work in lenient mode, just won't get fastpath 2888 df->setLenient(TRUE); 2889 { 2890 Formattable n; 2891 ParsePosition pos(0); 2892 UnicodeString toParse("1,234",""); 2893 df->parse(toParse, n, pos); 2894 if (n.getType() != Formattable::kLong 2895 || n.getLong() != 1234) { 2896 errln(UnicodeString("FAIL: parse(\"") + toParse + UnicodeString("\") returns ") + toString(n)); 2897 } 2898 } 2899 delete nf; 2900 } 2901 2902 2903 void NumberFormatRegressionTest::Test9677(void) { 2904 static const UChar pattern[] = { 0x23,0x23,0x23,0x23,0x2E,0x23,0x23,0x23,0x23,0 }; // "####.####" 2905 static const UChar positivePrefix[] = { 0x40,0 }; // "@" 2906 static const UChar negativePrefix[] = { 0x6E,0 }; // "n" 2907 static const UChar text[] = { 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0 }; // 123456789 2908 static const UChar text2[] = { 0x6E, 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0 }; // n123456789 2909 2910 UErrorCode status = U_ZERO_ERROR; 2911 LocalUNumberFormatPointer f(unum_open(UNUM_DEFAULT, NULL, 0, "en_US", NULL, &status)); 2912 if (U_FAILURE(status)) { 2913 dataerrln("Failure opening unum_open"); 2914 return; 2915 } 2916 2917 if (U_SUCCESS(status)) { 2918 unum_applyPattern(f.getAlias(), FALSE, pattern, -1, NULL, &status); 2919 unum_setTextAttribute(f.getAlias(), UNUM_POSITIVE_PREFIX, positivePrefix, -1, &status); 2920 assertSuccess("setting attributes", status); 2921 } 2922 2923 if(U_SUCCESS(status)) { 2924 int32_t n = unum_parse(f.getAlias(), text, -1, NULL, &status); 2925 logln("unum_parse status %s, result %d\n", u_errorName(status), n); 2926 2927 if(U_FAILURE(status)) { 2928 logln("Got expected parse error %s\n", u_errorName(status)); 2929 status = U_ZERO_ERROR; 2930 } else { 2931 errln("FAIL: unum_parse status %s, result %d - expected failure\n", u_errorName(status), n); 2932 } 2933 } 2934 2935 if (U_SUCCESS(status)) { 2936 unum_setTextAttribute(f.getAlias(), UNUM_POSITIVE_PREFIX, NULL, 0, &status); 2937 assertSuccess("setting attributes", status); 2938 logln("removed positive prefix"); 2939 } 2940 2941 if(U_SUCCESS(status)) { 2942 int32_t n = unum_parse(f.getAlias(), text, -1, NULL, &status); 2943 logln("unum_parse status %s, result %d\n", u_errorName(status), n); 2944 2945 if(U_FAILURE(status)) { 2946 errln("FAIL: with pos prefix removed, parse error %s\n", u_errorName(status)); 2947 status = U_ZERO_ERROR; 2948 } else { 2949 if(n!=123456789) { 2950 errln("FAIL: with pos prefix removed , unum_parse status %s, result %d expected 123456789\n", u_errorName(status), n); 2951 } else { 2952 logln("PASS: with pos prefix removed , unum_parse status %s, result %d expected 123456789\n", u_errorName(status),n); 2953 } 2954 } 2955 } 2956 2957 if(U_SUCCESS(status)) { 2958 int32_t n = unum_parse(f.getAlias(), text2, -1, NULL, &status); 2959 logln("unum_parse status %s, result %d\n", u_errorName(status), n); 2960 2961 if(U_FAILURE(status)) { 2962 logln("text2: Got expected parse error %s\n", u_errorName(status)); 2963 status = U_ZERO_ERROR; 2964 } else { 2965 errln("FAIL: text2: unum_parse status %s, result %d - expected failure\n", u_errorName(status), n); 2966 } 2967 } 2968 2969 if (U_SUCCESS(status)) { 2970 unum_setTextAttribute(f.getAlias(), UNUM_NEGATIVE_PREFIX, negativePrefix, -1, &status); 2971 assertSuccess("setting attributes", status); 2972 logln("Set a different neg prefix prefix"); 2973 } 2974 2975 if(U_SUCCESS(status)) { 2976 int32_t n = unum_parse(f.getAlias(), text2, -1, NULL, &status); 2977 logln("unum_parse status %s, result %d\n", u_errorName(status), n); 2978 2979 if(U_FAILURE(status)) { 2980 errln("FAIL: with different neg prefix , parse error %s\n", u_errorName(status)); 2981 status = U_ZERO_ERROR; 2982 } else { 2983 ; 2984 if(n!=-123456789) { 2985 errln("FAIL: with different neg prefix , unum_parse status %s, result %d expected -123456789\n", u_errorName(status), n); 2986 } else { 2987 logln("PASS: with different neg prefix , unum_parse status %s, result %d expected -123456789\n", u_errorName(status), n); 2988 } 2989 } 2990 } 2991 } 2992 2993 void NumberFormatRegressionTest::Test10361(void) { 2994 // DecimalFormat/NumberFormat were artificially limiting the number of digits, 2995 // preventing formatting of big decimals. 2996 UErrorCode status = U_ZERO_ERROR; 2997 DecimalFormatSymbols symbols(Locale::getEnglish(), status); 2998 LocalPointer<DecimalFormat> df(new DecimalFormat("###.##", symbols, status)); 2999 TEST_CHECK_STATUS(status); 3000 3001 // Create a decimal number with a million digits. 3002 const int32_t NUMSIZE=1000000; 3003 char *num = new char[NUMSIZE]; 3004 for (int32_t i=0; i<NUMSIZE; i++) { 3005 num[i] = '0' + (i+1) % 10; 3006 } 3007 num[NUMSIZE-3] = '.'; 3008 num[NUMSIZE-1] = 0; 3009 3010 UnicodeString s; 3011 Formattable fmtable; 3012 fmtable.setDecimalNumber(num, status); 3013 TEST_CHECK_STATUS(status); 3014 3015 FieldPosition pos(UNUM_DECIMAL_SEPARATOR_FIELD); 3016 df->format(fmtable, s, pos, status); 3017 TEST_CHECK_STATUS(status); 3018 TEST_ASSERT(999999 == s.length()); 3019 TEST_ASSERT(999997 == pos.getBeginIndex()); 3020 TEST_ASSERT(999998 == pos.getEndIndex()); 3021 3022 UnicodeString expected(num, -1, US_INV); 3023 TEST_ASSERT(expected == s); 3024 delete [] num; 3025 } 3026 3027 #endif /* #if !UCONFIG_NO_FORMATTING */ 3028