OLD | NEW |
1 // © 2017 and later: Unicode, Inc. and others. | 1 // © 2017 and later: Unicode, Inc. and others. |
2 // License & terms of use: http://www.unicode.org/copyright.html | 2 // License & terms of use: http://www.unicode.org/copyright.html |
3 | 3 |
4 #include "unicode/utypes.h" | 4 #include "unicode/utypes.h" |
5 | 5 |
6 #if !UCONFIG_NO_FORMATTING && !UPRV_INCOMPLETE_CPP11_SUPPORT | 6 #if !UCONFIG_NO_FORMATTING && !UPRV_INCOMPLETE_CPP11_SUPPORT |
7 | 7 |
8 #include "charstr.h" | 8 #include "charstr.h" |
9 #include <cstdarg> | 9 #include <cstdarg> |
10 #include "unicode/unum.h" | 10 #include "unicode/unum.h" |
11 #include "unicode/numberformatter.h" | 11 #include "unicode/numberformatter.h" |
12 #include "number_types.h" | 12 #include "number_types.h" |
13 #include "numbertest.h" | 13 #include "numbertest.h" |
14 | 14 |
15 // Horrible workaround for the lack of a status code in the constructor... | 15 // Horrible workaround for the lack of a status code in the constructor... |
16 UErrorCode globalNumberFormatterApiTestStatus = U_ZERO_ERROR; | 16 UErrorCode globalNumberFormatterApiTestStatus = U_ZERO_ERROR; |
17 | 17 |
18 NumberFormatterApiTest::NumberFormatterApiTest() | 18 NumberFormatterApiTest::NumberFormatterApiTest() |
19 : NumberFormatterApiTest(globalNumberFormatterApiTestStatus) { | 19 : NumberFormatterApiTest(globalNumberFormatterApiTestStatus) { |
20 } | 20 } |
21 | 21 |
22 NumberFormatterApiTest::NumberFormatterApiTest(UErrorCode &status) | 22 NumberFormatterApiTest::NumberFormatterApiTest(UErrorCode &status) |
23 : USD(u"USD", status), GBP(u"GBP", status), | 23 : USD(u"USD", status), GBP(u"GBP", status), |
24 CZK(u"CZK", status), CAD(u"CAD", status), | 24 CZK(u"CZK", status), CAD(u"CAD", status), |
25 FRENCH_SYMBOLS(Locale::getFrench(), status), | 25 FRENCH_SYMBOLS(Locale::getFrench(), status), |
26 SWISS_SYMBOLS(Locale("de-CH"), status), | 26 SWISS_SYMBOLS(Locale("de-CH"), status), |
27 MYANMAR_SYMBOLS(Locale("my"), status) { | 27 MYANMAR_SYMBOLS(Locale("my"), status) { |
28 | 28 |
29 MeasureUnit *unit = MeasureUnit::createMeter(status); | 29 // Check for error on the first MeasureUnit in case there is no data |
| 30 LocalPointer<MeasureUnit> unit(MeasureUnit::createMeter(status)); |
30 if (U_FAILURE(status)) { | 31 if (U_FAILURE(status)) { |
31 dataerrln("%s %d status = %s", __FILE__, __LINE__, u_errorName(status)); | 32 dataerrln("%s %d status = %s", __FILE__, __LINE__, u_errorName(status)); |
32 return; | 33 return; |
33 } | 34 } |
34 METER = *unit; | 35 METER = *unit; |
35 delete unit; | |
36 unit = MeasureUnit::createDay(status); | |
37 DAY = *unit; | |
38 delete unit; | |
39 unit = MeasureUnit::createSquareMeter(status); | |
40 SQUARE_METER = *unit; | |
41 delete unit; | |
42 unit = MeasureUnit::createFahrenheit(status); | |
43 FAHRENHEIT = *unit; | |
44 delete unit; | |
45 | 36 |
46 NumberingSystem *ns = NumberingSystem::createInstanceByName("mathsanb", stat
us); | 37 DAY = *LocalPointer<MeasureUnit>(MeasureUnit::createDay(status)); |
47 MATHSANB = *ns; | 38 SQUARE_METER = *LocalPointer<MeasureUnit>(MeasureUnit::createSquareMeter(sta
tus)); |
48 delete ns; | 39 FAHRENHEIT = *LocalPointer<MeasureUnit>(MeasureUnit::createFahrenheit(status
)); |
49 ns = NumberingSystem::createInstanceByName("latn", status); | 40 SECOND = *LocalPointer<MeasureUnit>(MeasureUnit::createSecond(status)); |
50 LATN = *ns; | 41 POUND = *LocalPointer<MeasureUnit>(MeasureUnit::createPound(status)); |
51 delete ns; | 42 SQUARE_MILE = *LocalPointer<MeasureUnit>(MeasureUnit::createSquareMile(statu
s)); |
| 43 JOULE = *LocalPointer<MeasureUnit>(MeasureUnit::createJoule(status)); |
| 44 FURLONG = *LocalPointer<MeasureUnit>(MeasureUnit::createFurlong(status)); |
| 45 |
| 46 MATHSANB = *LocalPointer<NumberingSystem>(NumberingSystem::createInstanceByN
ame("mathsanb", status)); |
| 47 LATN = *LocalPointer<NumberingSystem>(NumberingSystem::createInstanceByName(
"latn", status)); |
52 } | 48 } |
53 | 49 |
54 void NumberFormatterApiTest::runIndexedTest(int32_t index, UBool exec, const cha
r *&name, char *) { | 50 void NumberFormatterApiTest::runIndexedTest(int32_t index, UBool exec, const cha
r *&name, char *) { |
55 if (exec) { | 51 if (exec) { |
56 logln("TestSuite NumberFormatterApiTest: "); | 52 logln("TestSuite NumberFormatterApiTest: "); |
57 } | 53 } |
58 TESTCASE_AUTO_BEGIN; | 54 TESTCASE_AUTO_BEGIN; |
59 TESTCASE_AUTO(notationSimple); | 55 TESTCASE_AUTO(notationSimple); |
60 TESTCASE_AUTO(notationScientific); | 56 TESTCASE_AUTO(notationScientific); |
61 TESTCASE_AUTO(notationCompact); | 57 TESTCASE_AUTO(notationCompact); |
62 TESTCASE_AUTO(unitMeasure); | 58 TESTCASE_AUTO(unitMeasure); |
| 59 TESTCASE_AUTO(unitCompoundMeasure); |
63 TESTCASE_AUTO(unitCurrency); | 60 TESTCASE_AUTO(unitCurrency); |
64 TESTCASE_AUTO(unitPercent); | 61 TESTCASE_AUTO(unitPercent); |
65 TESTCASE_AUTO(roundingFraction); | 62 TESTCASE_AUTO(roundingFraction); |
66 TESTCASE_AUTO(roundingFigures); | 63 TESTCASE_AUTO(roundingFigures); |
67 TESTCASE_AUTO(roundingFractionFigures); | 64 TESTCASE_AUTO(roundingFractionFigures); |
68 TESTCASE_AUTO(roundingOther); | 65 TESTCASE_AUTO(roundingOther); |
69 TESTCASE_AUTO(grouping); | 66 TESTCASE_AUTO(grouping); |
70 TESTCASE_AUTO(padding); | 67 TESTCASE_AUTO(padding); |
71 TESTCASE_AUTO(integerWidth); | 68 TESTCASE_AUTO(integerWidth); |
72 TESTCASE_AUTO(symbols); | 69 TESTCASE_AUTO(symbols); |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
348 assertFormatSingle( | 345 assertFormatSingle( |
349 u"Compact Rounding", | 346 u"Compact Rounding", |
350 NumberFormatter::with().notation(Notation::compactShort()), | 347 NumberFormatter::with().notation(Notation::compactShort()), |
351 Locale::getEnglish(), | 348 Locale::getEnglish(), |
352 9990000, | 349 9990000, |
353 u"10M"); | 350 u"10M"); |
354 } | 351 } |
355 | 352 |
356 void NumberFormatterApiTest::unitMeasure() { | 353 void NumberFormatterApiTest::unitMeasure() { |
357 assertFormatDescending( | 354 assertFormatDescending( |
358 u"Meters Short", | 355 u"Meters Short and unit() method", |
359 NumberFormatter::with().adoptUnit(new MeasureUnit(METER)), | 356 NumberFormatter::with().unit(METER), |
360 Locale::getEnglish(), | 357 Locale::getEnglish(), |
361 u"87,650 m", | 358 u"87,650 m", |
362 u"8,765 m", | 359 u"8,765 m", |
363 u"876.5 m", | 360 u"876.5 m", |
364 u"87.65 m", | 361 u"87.65 m", |
365 u"8.765 m", | 362 u"8.765 m", |
366 u"0.8765 m", | 363 u"0.8765 m", |
367 u"0.08765 m", | 364 u"0.08765 m", |
368 u"0.008765 m", | 365 u"0.008765 m", |
369 u"0 m"); | 366 u"0 m"); |
370 | 367 |
371 assertFormatDescending( | 368 assertFormatDescending( |
372 u"Meters Long", | 369 u"Meters Long and adoptUnit() method", |
373 NumberFormatter::with().adoptUnit(new MeasureUnit(METER)) | 370 NumberFormatter::with().adoptUnit(new MeasureUnit(METER)) |
374 .unitWidth(UNumberUnitWidth::UNUM_UNIT_WIDTH_FULL_NAME), | 371 .unitWidth(UNumberUnitWidth::UNUM_UNIT_WIDTH_FULL_NAME), |
375 Locale::getEnglish(), | 372 Locale::getEnglish(), |
376 u"87,650 meters", | 373 u"87,650 meters", |
377 u"8,765 meters", | 374 u"8,765 meters", |
378 u"876.5 meters", | 375 u"876.5 meters", |
379 u"87.65 meters", | 376 u"87.65 meters", |
380 u"8.765 meters", | 377 u"8.765 meters", |
381 u"0.8765 meters", | 378 u"0.8765 meters", |
382 u"0.08765 meters", | 379 u"0.08765 meters", |
383 u"0.008765 meters", | 380 u"0.008765 meters", |
384 u"0 meters"); | 381 u"0 meters"); |
385 | 382 |
386 assertFormatDescending( | 383 assertFormatDescending( |
387 u"Compact Meters Long", | 384 u"Compact Meters Long", |
388 NumberFormatter::with().notation(Notation::compactLong()) | 385 NumberFormatter::with().notation(Notation::compactLong()) |
389 .adoptUnit(new MeasureUnit(METER)) | 386 .unit(METER) |
390 .unitWidth(UNumberUnitWidth::UNUM_UNIT_WIDTH_FULL_NAME), | 387 .unitWidth(UNumberUnitWidth::UNUM_UNIT_WIDTH_FULL_NAME), |
391 Locale::getEnglish(), | 388 Locale::getEnglish(), |
392 u"88 thousand meters", | 389 u"88 thousand meters", |
393 u"8.8 thousand meters", | 390 u"8.8 thousand meters", |
394 u"876 meters", | 391 u"876 meters", |
395 u"88 meters", | 392 u"88 meters", |
396 u"8.8 meters", | 393 u"8.8 meters", |
397 u"0.88 meters", | 394 u"0.88 meters", |
398 u"0.088 meters", | 395 u"0.088 meters", |
399 u"0.0088 meters", | 396 u"0.0088 meters", |
400 u"0 meters"); | 397 u"0 meters"); |
401 | 398 |
402 // TODO: Implement Measure in C++ | 399 // TODO: Implement Measure in C++ |
403 // assertFormatSingleMeasure( | 400 // assertFormatSingleMeasure( |
404 // u"Meters with Measure Input", | 401 // u"Meters with Measure Input", |
405 // NumberFormatter::with().unitWidth(UNumberUnitWidth::UNUM_UNIT_WIDT
H_FULL_NAME), | 402 // NumberFormatter::with().unitWidth(UNumberUnitWidth::UNUM_UNIT_WIDT
H_FULL_NAME), |
406 // Locale::getEnglish(), | 403 // Locale::getEnglish(), |
407 // new Measure(5.43, new MeasureUnit(METER)), | 404 // new Measure(5.43, new MeasureUnit(METER)), |
408 // u"5.43 meters"); | 405 // u"5.43 meters"); |
409 | 406 |
410 // TODO: Implement Measure in C++ | 407 // TODO: Implement Measure in C++ |
411 // assertFormatSingleMeasure( | 408 // assertFormatSingleMeasure( |
412 // u"Measure format method takes precedence over fluent chain", | 409 // u"Measure format method takes precedence over fluent chain", |
413 // NumberFormatter::with().adoptUnit(new MeasureUnit(METER)), | 410 // NumberFormatter::with().unit(METER), |
414 // Locale::getEnglish(), | 411 // Locale::getEnglish(), |
415 // new Measure(5.43, USD), | 412 // new Measure(5.43, USD), |
416 // u"$5.43"); | 413 // u"$5.43"); |
417 | 414 |
418 assertFormatSingle( | 415 assertFormatSingle( |
419 u"Meters with Negative Sign", | 416 u"Meters with Negative Sign", |
420 NumberFormatter::with().adoptUnit(new MeasureUnit(METER)), | 417 NumberFormatter::with().unit(METER), |
421 Locale::getEnglish(), | 418 Locale::getEnglish(), |
422 -9876543.21, | 419 -9876543.21, |
423 u"-9,876,543.21 m"); | 420 u"-9,876,543.21 m"); |
424 | 421 |
425 // The locale string "सान" appears only in brx.txt: | 422 // The locale string "सान" appears only in brx.txt: |
426 assertFormatSingle( | 423 assertFormatSingle( |
427 u"Interesting Data Fallback 1", | 424 u"Interesting Data Fallback 1", |
428 NumberFormatter::with().adoptUnit(new MeasureUnit(DAY)) | 425 NumberFormatter::with().unit(DAY) |
429 .unitWidth(UNumberUnitWidth::UNUM_UNIT_WIDTH_FULL_NAME), | 426 .unitWidth(UNumberUnitWidth::UNUM_UNIT_WIDTH_FULL_NAME), |
430 Locale::createFromName("brx"), | 427 Locale::createFromName("brx"), |
431 5.43, | 428 5.43, |
432 u"5.43 सान"); | 429 u"5.43 सान"); |
433 | 430 |
434 // Requires following the alias from unitsNarrow to unitsShort: | 431 // Requires following the alias from unitsNarrow to unitsShort: |
435 assertFormatSingle( | 432 assertFormatSingle( |
436 u"Interesting Data Fallback 2", | 433 u"Interesting Data Fallback 2", |
437 NumberFormatter::with().adoptUnit(new MeasureUnit(DAY)) | 434 NumberFormatter::with().unit(DAY) |
438 .unitWidth(UNumberUnitWidth::UNUM_UNIT_WIDTH_NARROW), | 435 .unitWidth(UNumberUnitWidth::UNUM_UNIT_WIDTH_NARROW), |
439 Locale::createFromName("brx"), | 436 Locale::createFromName("brx"), |
440 5.43, | 437 5.43, |
441 u"5.43 d"); | 438 u"5.43 d"); |
442 | 439 |
443 // en_001.txt has a unitsNarrow/area/square-meter table, but table does not
contain the OTHER unit, | 440 // en_001.txt has a unitsNarrow/area/square-meter table, but table does not
contain the OTHER unit, |
444 // requiring fallback to the root. | 441 // requiring fallback to the root. |
445 assertFormatSingle( | 442 assertFormatSingle( |
446 u"Interesting Data Fallback 3", | 443 u"Interesting Data Fallback 3", |
447 NumberFormatter::with().adoptUnit(new MeasureUnit(SQUARE_METER)) | 444 NumberFormatter::with().unit(SQUARE_METER) |
448 .unitWidth(UNumberUnitWidth::UNUM_UNIT_WIDTH_NARROW), | 445 .unitWidth(UNumberUnitWidth::UNUM_UNIT_WIDTH_NARROW), |
449 Locale::createFromName("en-GB"), | 446 Locale::createFromName("en-GB"), |
450 5.43, | 447 5.43, |
451 u"5.43 m²"); | 448 u"5.43 m²"); |
452 | 449 |
453 // es_US has "{0}°" for unitsNarrow/temperature/FAHRENHEIT. | 450 // es_US has "{0}°" for unitsNarrow/temperature/FAHRENHEIT. |
454 // NOTE: This example is in the documentation. | 451 // NOTE: This example is in the documentation. |
455 assertFormatSingle( | 452 assertFormatSingle( |
456 u"Difference between Narrow and Short (Narrow Version)", | 453 u"Difference between Narrow and Short (Narrow Version)", |
457 NumberFormatter::with().adoptUnit(new MeasureUnit(FAHRENHEIT)) | 454 NumberFormatter::with().unit(FAHRENHEIT) |
458 .unitWidth(UNUM_UNIT_WIDTH_NARROW), | 455 .unitWidth(UNUM_UNIT_WIDTH_NARROW), |
459 Locale("es-US"), | 456 Locale("es-US"), |
460 5.43, | 457 5.43, |
461 u"5.43°"); | 458 u"5.43°"); |
462 | 459 |
463 assertFormatSingle( | 460 assertFormatSingle( |
464 u"Difference between Narrow and Short (Short Version)", | 461 u"Difference between Narrow and Short (Short Version)", |
465 NumberFormatter::with().adoptUnit(new MeasureUnit(FAHRENHEIT)) | 462 NumberFormatter::with().unit(FAHRENHEIT) |
466 .unitWidth(UNUM_UNIT_WIDTH_SHORT), | 463 .unitWidth(UNUM_UNIT_WIDTH_SHORT), |
467 Locale("es-US"), | 464 Locale("es-US"), |
468 5.43, | 465 5.43, |
469 u"5.43 °F"); | 466 u"5.43 °F"); |
470 } | 467 } |
471 | 468 |
| 469 void NumberFormatterApiTest::unitCompoundMeasure() { |
| 470 assertFormatDescending( |
| 471 u"Meters Per Second Short (unit that simplifies) and perUnit method"
, |
| 472 NumberFormatter::with().unit(METER).perUnit(SECOND), |
| 473 Locale::getEnglish(), |
| 474 u"87,650 m/s", |
| 475 u"8,765 m/s", |
| 476 u"876.5 m/s", |
| 477 u"87.65 m/s", |
| 478 u"8.765 m/s", |
| 479 u"0.8765 m/s", |
| 480 u"0.08765 m/s", |
| 481 u"0.008765 m/s", |
| 482 u"0 m/s"); |
| 483 |
| 484 assertFormatDescending( |
| 485 u"Pounds Per Square Mile Short (secondary unit has per-format) and a
doptPerUnit method", |
| 486 NumberFormatter::with().unit(POUND).adoptPerUnit(new MeasureUnit(SQU
ARE_MILE)), |
| 487 Locale::getEnglish(), |
| 488 u"87,650 lb/mi²", |
| 489 u"8,765 lb/mi²", |
| 490 u"876.5 lb/mi²", |
| 491 u"87.65 lb/mi²", |
| 492 u"8.765 lb/mi²", |
| 493 u"0.8765 lb/mi²", |
| 494 u"0.08765 lb/mi²", |
| 495 u"0.008765 lb/mi²", |
| 496 u"0 lb/mi²"); |
| 497 |
| 498 assertFormatDescending( |
| 499 u"Joules Per Furlong Short (unit with no simplifications or special
patterns)", |
| 500 NumberFormatter::with().unit(JOULE).perUnit(FURLONG), |
| 501 Locale::getEnglish(), |
| 502 u"87,650 J/fur", |
| 503 u"8,765 J/fur", |
| 504 u"876.5 J/fur", |
| 505 u"87.65 J/fur", |
| 506 u"8.765 J/fur", |
| 507 u"0.8765 J/fur", |
| 508 u"0.08765 J/fur", |
| 509 u"0.008765 J/fur", |
| 510 u"0 J/fur"); |
| 511 } |
| 512 |
472 void NumberFormatterApiTest::unitCurrency() { | 513 void NumberFormatterApiTest::unitCurrency() { |
473 assertFormatDescending( | 514 assertFormatDescending( |
474 u"Currency", | 515 u"Currency", |
475 NumberFormatter::with().unit(GBP), | 516 NumberFormatter::with().unit(GBP), |
476 Locale::getEnglish(), | 517 Locale::getEnglish(), |
477 u"£87,650.00", | 518 u"£87,650.00", |
478 u"£8,765.00", | 519 u"£8,765.00", |
479 u"£876.50", | 520 u"£876.50", |
480 u"£87.65", | 521 u"£87.65", |
481 u"£8.76", | 522 u"£8.76", |
(...skipping 1033 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1515 UErrorCode status = U_ZERO_ERROR; | 1556 UErrorCode status = U_ZERO_ERROR; |
1516 UnicodeString actual1 = l1.formatDouble(input, status).toString(); | 1557 UnicodeString actual1 = l1.formatDouble(input, status).toString(); |
1517 assertSuccess(message + u": Unsafe Path", status); | 1558 assertSuccess(message + u": Unsafe Path", status); |
1518 assertEquals(message + u": Unsafe Path", expected, actual1); | 1559 assertEquals(message + u": Unsafe Path", expected, actual1); |
1519 UnicodeString actual2 = l2.formatDouble(input, status).toString(); | 1560 UnicodeString actual2 = l2.formatDouble(input, status).toString(); |
1520 assertSuccess(message + u": Safe Path", status); | 1561 assertSuccess(message + u": Safe Path", status); |
1521 assertEquals(message + u": Safe Path", expected, actual2); | 1562 assertEquals(message + u": Safe Path", expected, actual2); |
1522 } | 1563 } |
1523 | 1564 |
1524 #endif /* #if !UCONFIG_NO_FORMATTING */ | 1565 #endif /* #if !UCONFIG_NO_FORMATTING */ |
OLD | NEW |