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