1 // © 2017 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3
4 #include "unicode/utypes.h"
5
6 #if !UCONFIG_NO_FORMATTING && !UPRV_INCOMPLETE_CPP11_SUPPORT
7
8 #include "charstr.h"
9 #include <cstdarg>
10 #include "unicode/unum.h"
11 #include "unicode/numberformatter.h"
12 #include "number_types.h"
13 #include "numbertest.h"
14
15 // Horrible workaround for the lack of a status code in the constructor...
16 UErrorCode globalNumberFormatterApiTestStatus = U_ZERO_ERROR;
17
NumberFormatterApiTest()18 NumberFormatterApiTest::NumberFormatterApiTest()
19 : NumberFormatterApiTest(globalNumberFormatterApiTestStatus) {
20 }
21
NumberFormatterApiTest(UErrorCode & status)22 NumberFormatterApiTest::NumberFormatterApiTest(UErrorCode &status)
23 : USD(u"USD", status), GBP(u"GBP", status),
24 CZK(u"CZK", status), CAD(u"CAD", status),
25 FRENCH_SYMBOLS(Locale::getFrench(), status),
26 SWISS_SYMBOLS(Locale("de-CH"), status),
27 MYANMAR_SYMBOLS(Locale("my"), status) {
28
29 MeasureUnit *unit = MeasureUnit::createMeter(status);
30 if (U_FAILURE(status)) {
31 dataerrln("%s %d status = %s", __FILE__, __LINE__, u_errorName(status));
32 return;
33 }
34 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
46 NumberingSystem *ns = NumberingSystem::createInstanceByName("mathsanb", status);
47 MATHSANB = *ns;
48 delete ns;
49 ns = NumberingSystem::createInstanceByName("latn", status);
50 LATN = *ns;
51 delete ns;
52 }
53
runIndexedTest(int32_t index,UBool exec,const char * & name,char *)54 void NumberFormatterApiTest::runIndexedTest(int32_t index, UBool exec, const char *&name, char *) {
55 if (exec) {
56 logln("TestSuite NumberFormatterApiTest: ");
57 }
58 TESTCASE_AUTO_BEGIN;
59 TESTCASE_AUTO(notationSimple);
60 TESTCASE_AUTO(notationScientific);
61 TESTCASE_AUTO(notationCompact);
62 TESTCASE_AUTO(unitMeasure);
63 TESTCASE_AUTO(unitCurrency);
64 TESTCASE_AUTO(unitPercent);
65 TESTCASE_AUTO(roundingFraction);
66 TESTCASE_AUTO(roundingFigures);
67 TESTCASE_AUTO(roundingFractionFigures);
68 TESTCASE_AUTO(roundingOther);
69 TESTCASE_AUTO(grouping);
70 TESTCASE_AUTO(padding);
71 TESTCASE_AUTO(integerWidth);
72 TESTCASE_AUTO(symbols);
73 // TODO: Add this method if currency symbols override support is added.
74 //TESTCASE_AUTO(symbolsOverride);
75 TESTCASE_AUTO(sign);
76 TESTCASE_AUTO(decimal);
77 TESTCASE_AUTO(locale);
78 TESTCASE_AUTO(formatTypes);
79 TESTCASE_AUTO(errors);
80 TESTCASE_AUTO_END;
81 }
82
notationSimple()83 void NumberFormatterApiTest::notationSimple() {
84 assertFormatDescending(
85 u"Basic",
86 NumberFormatter::with(),
87 Locale::getEnglish(),
88 u"87,650",
89 u"8,765",
90 u"876.5",
91 u"87.65",
92 u"8.765",
93 u"0.8765",
94 u"0.08765",
95 u"0.008765",
96 u"0");
97
98 assertFormatSingle(
99 u"Basic with Negative Sign",
100 NumberFormatter::with(),
101 Locale::getEnglish(),
102 -9876543.21,
103 u"-9,876,543.21");
104 }
105
106
notationScientific()107 void NumberFormatterApiTest::notationScientific() {
108 assertFormatDescending(
109 u"Scientific",
110 NumberFormatter::with().notation(Notation::scientific()),
111 Locale::getEnglish(),
112 u"8.765E4",
113 u"8.765E3",
114 u"8.765E2",
115 u"8.765E1",
116 u"8.765E0",
117 u"8.765E-1",
118 u"8.765E-2",
119 u"8.765E-3",
120 u"0E0");
121
122 assertFormatDescending(
123 u"Engineering",
124 NumberFormatter::with().notation(Notation::engineering()),
125 Locale::getEnglish(),
126 u"87.65E3",
127 u"8.765E3",
128 u"876.5E0",
129 u"87.65E0",
130 u"8.765E0",
131 u"876.5E-3",
132 u"87.65E-3",
133 u"8.765E-3",
134 u"0E0");
135
136 assertFormatDescending(
137 u"Scientific sign always shown",
138 NumberFormatter::with().notation(
139 Notation::scientific().withExponentSignDisplay(UNumberSignDisplay::UNUM_SIGN_ALWAYS)),
140 Locale::getEnglish(),
141 u"8.765E+4",
142 u"8.765E+3",
143 u"8.765E+2",
144 u"8.765E+1",
145 u"8.765E+0",
146 u"8.765E-1",
147 u"8.765E-2",
148 u"8.765E-3",
149 u"0E+0");
150
151 assertFormatDescending(
152 u"Scientific min exponent digits",
153 NumberFormatter::with().notation(Notation::scientific().withMinExponentDigits(2)),
154 Locale::getEnglish(),
155 u"8.765E04",
156 u"8.765E03",
157 u"8.765E02",
158 u"8.765E01",
159 u"8.765E00",
160 u"8.765E-01",
161 u"8.765E-02",
162 u"8.765E-03",
163 u"0E00");
164
165 assertFormatSingle(
166 u"Scientific Negative",
167 NumberFormatter::with().notation(Notation::scientific()),
168 Locale::getEnglish(),
169 -1000000,
170 u"-1E6");
171 }
172
notationCompact()173 void NumberFormatterApiTest::notationCompact() {
174 assertFormatDescending(
175 u"Compact Short",
176 NumberFormatter::with().notation(Notation::compactShort()),
177 Locale::getEnglish(),
178 u"88K",
179 u"8.8K",
180 u"876",
181 u"88",
182 u"8.8",
183 u"0.88",
184 u"0.088",
185 u"0.0088",
186 u"0");
187
188 assertFormatDescending(
189 u"Compact Long",
190 NumberFormatter::with().notation(Notation::compactLong()),
191 Locale::getEnglish(),
192 u"88 thousand",
193 u"8.8 thousand",
194 u"876",
195 u"88",
196 u"8.8",
197 u"0.88",
198 u"0.088",
199 u"0.0088",
200 u"0");
201
202 assertFormatDescending(
203 u"Compact Short Currency",
204 NumberFormatter::with().notation(Notation::compactShort()).unit(USD),
205 Locale::getEnglish(),
206 u"$88K",
207 u"$8.8K",
208 u"$876",
209 u"$88",
210 u"$8.8",
211 u"$0.88",
212 u"$0.088",
213 u"$0.0088",
214 u"$0");
215
216 assertFormatDescending(
217 u"Compact Short with ISO Currency",
218 NumberFormatter::with().notation(Notation::compactShort())
219 .unit(USD)
220 .unitWidth(UNumberUnitWidth::UNUM_UNIT_WIDTH_ISO_CODE),
221 Locale::getEnglish(),
222 u"USD 88K",
223 u"USD 8.8K",
224 u"USD 876",
225 u"USD 88",
226 u"USD 8.8",
227 u"USD 0.88",
228 u"USD 0.088",
229 u"USD 0.0088",
230 u"USD 0");
231
232 assertFormatDescending(
233 u"Compact Short with Long Name Currency",
234 NumberFormatter::with().notation(Notation::compactShort())
235 .unit(USD)
236 .unitWidth(UNumberUnitWidth::UNUM_UNIT_WIDTH_FULL_NAME),
237 Locale::getEnglish(),
238 u"88K US dollars",
239 u"8.8K US dollars",
240 u"876 US dollars",
241 u"88 US dollars",
242 u"8.8 US dollars",
243 u"0.88 US dollars",
244 u"0.088 US dollars",
245 u"0.0088 US dollars",
246 u"0 US dollars");
247
248 // Note: Most locales don't have compact long currency, so this currently falls back to short.
249 // This test case should be fixed when proper compact long currency patterns are added.
250 assertFormatDescending(
251 u"Compact Long Currency",
252 NumberFormatter::with().notation(Notation::compactLong()).unit(USD),
253 Locale::getEnglish(),
254 u"$88K", // should be something like "$88 thousand"
255 u"$8.8K",
256 u"$876",
257 u"$88",
258 u"$8.8",
259 u"$0.88",
260 u"$0.088",
261 u"$0.0088",
262 u"$0");
263
264 // Note: Most locales don't have compact long currency, so this currently falls back to short.
265 // This test case should be fixed when proper compact long currency patterns are added.
266 assertFormatDescending(
267 u"Compact Long with ISO Currency",
268 NumberFormatter::with().notation(Notation::compactLong())
269 .unit(USD)
270 .unitWidth(UNumberUnitWidth::UNUM_UNIT_WIDTH_ISO_CODE),
271 Locale::getEnglish(),
272 u"USD 88K", // should be something like "USD 88 thousand"
273 u"USD 8.8K",
274 u"USD 876",
275 u"USD 88",
276 u"USD 8.8",
277 u"USD 0.88",
278 u"USD 0.088",
279 u"USD 0.0088",
280 u"USD 0");
281
282 // TODO: This behavior could be improved and should be revisited.
283 assertFormatDescending(
284 u"Compact Long with Long Name Currency",
285 NumberFormatter::with().notation(Notation::compactLong())
286 .unit(USD)
287 .unitWidth(UNumberUnitWidth::UNUM_UNIT_WIDTH_FULL_NAME),
288 Locale::getEnglish(),
289 u"88 thousand US dollars",
290 u"8.8 thousand US dollars",
291 u"876 US dollars",
292 u"88 US dollars",
293 u"8.8 US dollars",
294 u"0.88 US dollars",
295 u"0.088 US dollars",
296 u"0.0088 US dollars",
297 u"0 US dollars");
298
299 assertFormatSingle(
300 u"Compact Plural One",
301 NumberFormatter::with().notation(Notation::compactLong()),
302 Locale::createFromName("es"),
303 1000000,
304 u"1 millón");
305
306 assertFormatSingle(
307 u"Compact Plural Other",
308 NumberFormatter::with().notation(Notation::compactLong()),
309 Locale::createFromName("es"),
310 2000000,
311 u"2 millones");
312
313 assertFormatSingle(
314 u"Compact with Negative Sign",
315 NumberFormatter::with().notation(Notation::compactShort()),
316 Locale::getEnglish(),
317 -9876543.21,
318 u"-9.9M");
319
320 assertFormatSingle(
321 u"Compact Rounding",
322 NumberFormatter::with().notation(Notation::compactShort()),
323 Locale::getEnglish(),
324 990000,
325 u"990K");
326
327 assertFormatSingle(
328 u"Compact Rounding",
329 NumberFormatter::with().notation(Notation::compactShort()),
330 Locale::getEnglish(),
331 999000,
332 u"999K");
333
334 assertFormatSingle(
335 u"Compact Rounding",
336 NumberFormatter::with().notation(Notation::compactShort()),
337 Locale::getEnglish(),
338 999900,
339 u"1M");
340
341 assertFormatSingle(
342 u"Compact Rounding",
343 NumberFormatter::with().notation(Notation::compactShort()),
344 Locale::getEnglish(),
345 9900000,
346 u"9.9M");
347
348 assertFormatSingle(
349 u"Compact Rounding",
350 NumberFormatter::with().notation(Notation::compactShort()),
351 Locale::getEnglish(),
352 9990000,
353 u"10M");
354 }
355
unitMeasure()356 void NumberFormatterApiTest::unitMeasure() {
357 assertFormatDescending(
358 u"Meters Short",
359 NumberFormatter::with().adoptUnit(new MeasureUnit(METER)),
360 Locale::getEnglish(),
361 u"87,650 m",
362 u"8,765 m",
363 u"876.5 m",
364 u"87.65 m",
365 u"8.765 m",
366 u"0.8765 m",
367 u"0.08765 m",
368 u"0.008765 m",
369 u"0 m");
370
371 assertFormatDescending(
372 u"Meters Long",
373 NumberFormatter::with().adoptUnit(new MeasureUnit(METER))
374 .unitWidth(UNumberUnitWidth::UNUM_UNIT_WIDTH_FULL_NAME),
375 Locale::getEnglish(),
376 u"87,650 meters",
377 u"8,765 meters",
378 u"876.5 meters",
379 u"87.65 meters",
380 u"8.765 meters",
381 u"0.8765 meters",
382 u"0.08765 meters",
383 u"0.008765 meters",
384 u"0 meters");
385
386 assertFormatDescending(
387 u"Compact Meters Long",
388 NumberFormatter::with().notation(Notation::compactLong())
389 .adoptUnit(new MeasureUnit(METER))
390 .unitWidth(UNumberUnitWidth::UNUM_UNIT_WIDTH_FULL_NAME),
391 Locale::getEnglish(),
392 u"88 thousand meters",
393 u"8.8 thousand meters",
394 u"876 meters",
395 u"88 meters",
396 u"8.8 meters",
397 u"0.88 meters",
398 u"0.088 meters",
399 u"0.0088 meters",
400 u"0 meters");
401
402 // TODO: Implement Measure in C++
403 // assertFormatSingleMeasure(
404 // u"Meters with Measure Input",
405 // NumberFormatter::with().unitWidth(UNumberUnitWidth::UNUM_UNIT_WIDTH_FULL_NAME),
406 // Locale::getEnglish(),
407 // new Measure(5.43, new MeasureUnit(METER)),
408 // u"5.43 meters");
409
410 // TODO: Implement Measure in C++
411 // assertFormatSingleMeasure(
412 // u"Measure format method takes precedence over fluent chain",
413 // NumberFormatter::with().adoptUnit(new MeasureUnit(METER)),
414 // Locale::getEnglish(),
415 // new Measure(5.43, USD),
416 // u"$5.43");
417
418 assertFormatSingle(
419 u"Meters with Negative Sign",
420 NumberFormatter::with().adoptUnit(new MeasureUnit(METER)),
421 Locale::getEnglish(),
422 -9876543.21,
423 u"-9,876,543.21 m");
424
425 // The locale string "सान" appears only in brx.txt:
426 assertFormatSingle(
427 u"Interesting Data Fallback 1",
428 NumberFormatter::with().adoptUnit(new MeasureUnit(DAY))
429 .unitWidth(UNumberUnitWidth::UNUM_UNIT_WIDTH_FULL_NAME),
430 Locale::createFromName("brx"),
431 5.43,
432 u"5.43 सान");
433
434 // Requires following the alias from unitsNarrow to unitsShort:
435 assertFormatSingle(
436 u"Interesting Data Fallback 2",
437 NumberFormatter::with().adoptUnit(new MeasureUnit(DAY))
438 .unitWidth(UNumberUnitWidth::UNUM_UNIT_WIDTH_NARROW),
439 Locale::createFromName("brx"),
440 5.43,
441 u"5.43 d");
442
443 // en_001.txt has a unitsNarrow/area/square-meter table, but table does not contain the OTHER unit,
444 // requiring fallback to the root.
445 assertFormatSingle(
446 u"Interesting Data Fallback 3",
447 NumberFormatter::with().adoptUnit(new MeasureUnit(SQUARE_METER))
448 .unitWidth(UNumberUnitWidth::UNUM_UNIT_WIDTH_NARROW),
449 Locale::createFromName("en-GB"),
450 5.43,
451 u"5.43 m²");
452
453 // es_US has "{0}°" for unitsNarrow/temperature/FAHRENHEIT.
454 // NOTE: This example is in the documentation.
455 assertFormatSingle(
456 u"Difference between Narrow and Short (Narrow Version)",
457 NumberFormatter::with().adoptUnit(new MeasureUnit(FAHRENHEIT))
458 .unitWidth(UNUM_UNIT_WIDTH_NARROW),
459 Locale("es-US"),
460 5.43,
461 u"5.43°");
462
463 assertFormatSingle(
464 u"Difference between Narrow and Short (Short Version)",
465 NumberFormatter::with().adoptUnit(new MeasureUnit(FAHRENHEIT))
466 .unitWidth(UNUM_UNIT_WIDTH_SHORT),
467 Locale("es-US"),
468 5.43,
469 u"5.43 °F");
470 }
471
unitCurrency()472 void NumberFormatterApiTest::unitCurrency() {
473 assertFormatDescending(
474 u"Currency",
475 NumberFormatter::with().unit(GBP),
476 Locale::getEnglish(),
477 u"£87,650.00",
478 u"£8,765.00",
479 u"£876.50",
480 u"£87.65",
481 u"£8.76",
482 u"£0.88",
483 u"£0.09",
484 u"£0.01",
485 u"£0.00");
486
487 assertFormatDescending(
488 u"Currency ISO",
489 NumberFormatter::with().unit(GBP).unitWidth(UNumberUnitWidth::UNUM_UNIT_WIDTH_ISO_CODE),
490 Locale::getEnglish(),
491 u"GBP 87,650.00",
492 u"GBP 8,765.00",
493 u"GBP 876.50",
494 u"GBP 87.65",
495 u"GBP 8.76",
496 u"GBP 0.88",
497 u"GBP 0.09",
498 u"GBP 0.01",
499 u"GBP 0.00");
500
501 assertFormatDescending(
502 u"Currency Long Name",
503 NumberFormatter::with().unit(GBP).unitWidth(UNumberUnitWidth::UNUM_UNIT_WIDTH_FULL_NAME),
504 Locale::getEnglish(),
505 u"87,650.00 British pounds",
506 u"8,765.00 British pounds",
507 u"876.50 British pounds",
508 u"87.65 British pounds",
509 u"8.76 British pounds",
510 u"0.88 British pounds",
511 u"0.09 British pounds",
512 u"0.01 British pounds",
513 u"0.00 British pounds");
514
515 assertFormatDescending(
516 u"Currency Hidden",
517 NumberFormatter::with().unit(GBP).unitWidth(UNUM_UNIT_WIDTH_HIDDEN),
518 Locale::getEnglish(),
519 u"87,650.00",
520 u"8,765.00",
521 u"876.50",
522 u"87.65",
523 u"8.76",
524 u"0.88",
525 u"0.09",
526 u"0.01",
527 u"0.00");
528
529 // TODO: Implement Measure in C++
530 // assertFormatSingleMeasure(
531 // u"Currency with CurrencyAmount Input",
532 // NumberFormatter::with(),
533 // Locale::getEnglish(),
534 // new CurrencyAmount(5.43, GBP),
535 // u"£5.43");
536
537 // TODO: Enable this test when DecimalFormat wrapper is done.
538 // assertFormatSingle(
539 // u"Currency Long Name from Pattern Syntax", NumberFormatter.fromDecimalFormat(
540 // PatternStringParser.parseToProperties("0 ¤¤¤"),
541 // DecimalFormatSymbols.getInstance(Locale::getEnglish()),
542 // null).unit(GBP), Locale::getEnglish(), 1234567.89, u"1234568 British pounds");
543
544 assertFormatSingle(
545 u"Currency with Negative Sign",
546 NumberFormatter::with().unit(GBP),
547 Locale::getEnglish(),
548 -9876543.21,
549 u"-£9,876,543.21");
550 }
551
unitPercent()552 void NumberFormatterApiTest::unitPercent() {
553 assertFormatDescending(
554 u"Percent",
555 NumberFormatter::with().unit(NoUnit::percent()),
556 Locale::getEnglish(),
557 u"87,650%",
558 u"8,765%",
559 u"876.5%",
560 u"87.65%",
561 u"8.765%",
562 u"0.8765%",
563 u"0.08765%",
564 u"0.008765%",
565 u"0%");
566
567 assertFormatDescending(
568 u"Permille",
569 NumberFormatter::with().unit(NoUnit::permille()),
570 Locale::getEnglish(),
571 u"87,650‰",
572 u"8,765‰",
573 u"876.5‰",
574 u"87.65‰",
575 u"8.765‰",
576 u"0.8765‰",
577 u"0.08765‰",
578 u"0.008765‰",
579 u"0‰");
580
581 assertFormatSingle(
582 u"NoUnit Base",
583 NumberFormatter::with().unit(NoUnit::base()),
584 Locale::getEnglish(),
585 51423,
586 u"51,423");
587
588 assertFormatSingle(
589 u"Percent with Negative Sign",
590 NumberFormatter::with().unit(NoUnit::percent()),
591 Locale::getEnglish(),
592 -98.7654321,
593 u"-98.765432%");
594 }
595
roundingFraction()596 void NumberFormatterApiTest::roundingFraction() {
597 assertFormatDescending(
598 u"Integer",
599 NumberFormatter::with().rounding(Rounder::integer()),
600 Locale::getEnglish(),
601 u"87,650",
602 u"8,765",
603 u"876",
604 u"88",
605 u"9",
606 u"1",
607 u"0",
608 u"0",
609 u"0");
610
611 assertFormatDescending(
612 u"Fixed Fraction",
613 NumberFormatter::with().rounding(Rounder::fixedFraction(3)),
614 Locale::getEnglish(),
615 u"87,650.000",
616 u"8,765.000",
617 u"876.500",
618 u"87.650",
619 u"8.765",
620 u"0.876",
621 u"0.088",
622 u"0.009",
623 u"0.000");
624
625 assertFormatDescending(
626 u"Min Fraction",
627 NumberFormatter::with().rounding(Rounder::minFraction(1)),
628 Locale::getEnglish(),
629 u"87,650.0",
630 u"8,765.0",
631 u"876.5",
632 u"87.65",
633 u"8.765",
634 u"0.8765",
635 u"0.08765",
636 u"0.008765",
637 u"0.0");
638
639 assertFormatDescending(
640 u"Max Fraction",
641 NumberFormatter::with().rounding(Rounder::maxFraction(1)),
642 Locale::getEnglish(),
643 u"87,650",
644 u"8,765",
645 u"876.5",
646 u"87.6",
647 u"8.8",
648 u"0.9",
649 u"0.1",
650 u"0",
651 u"0");
652
653 assertFormatDescending(
654 u"Min/Max Fraction",
655 NumberFormatter::with().rounding(Rounder::minMaxFraction(1, 3)),
656 Locale::getEnglish(),
657 u"87,650.0",
658 u"8,765.0",
659 u"876.5",
660 u"87.65",
661 u"8.765",
662 u"0.876",
663 u"0.088",
664 u"0.009",
665 u"0.0");
666 }
667
roundingFigures()668 void NumberFormatterApiTest::roundingFigures() {
669 assertFormatSingle(
670 u"Fixed Significant",
671 NumberFormatter::with().rounding(Rounder::fixedDigits(3)),
672 Locale::getEnglish(),
673 -98,
674 u"-98.0");
675
676 assertFormatSingle(
677 u"Fixed Significant Rounding",
678 NumberFormatter::with().rounding(Rounder::fixedDigits(3)),
679 Locale::getEnglish(),
680 -98.7654321,
681 u"-98.8");
682
683 assertFormatSingle(
684 u"Fixed Significant Zero",
685 NumberFormatter::with().rounding(Rounder::fixedDigits(3)),
686 Locale::getEnglish(),
687 0,
688 u"0.00");
689
690 assertFormatSingle(
691 u"Min Significant",
692 NumberFormatter::with().rounding(Rounder::minDigits(2)),
693 Locale::getEnglish(),
694 -9,
695 u"-9.0");
696
697 assertFormatSingle(
698 u"Max Significant",
699 NumberFormatter::with().rounding(Rounder::maxDigits(4)),
700 Locale::getEnglish(),
701 98.7654321,
702 u"98.77");
703
704 assertFormatSingle(
705 u"Min/Max Significant",
706 NumberFormatter::with().rounding(Rounder::minMaxDigits(3, 4)),
707 Locale::getEnglish(),
708 9.99999,
709 u"10.0");
710 }
711
roundingFractionFigures()712 void NumberFormatterApiTest::roundingFractionFigures() {
713 assertFormatDescending(
714 u"Basic Significant", // for comparison
715 NumberFormatter::with().rounding(Rounder::maxDigits(2)),
716 Locale::getEnglish(),
717 u"88,000",
718 u"8,800",
719 u"880",
720 u"88",
721 u"8.8",
722 u"0.88",
723 u"0.088",
724 u"0.0088",
725 u"0");
726
727 assertFormatDescending(
728 u"FracSig minMaxFrac minSig",
729 NumberFormatter::with().rounding(Rounder::minMaxFraction(1, 2).withMinDigits(3)),
730 Locale::getEnglish(),
731 u"87,650.0",
732 u"8,765.0",
733 u"876.5",
734 u"87.65",
735 u"8.76",
736 u"0.876", // minSig beats maxFrac
737 u"0.0876", // minSig beats maxFrac
738 u"0.00876", // minSig beats maxFrac
739 u"0.0");
740
741 assertFormatDescending(
742 u"FracSig minMaxFrac maxSig A",
743 NumberFormatter::with().rounding(Rounder::minMaxFraction(1, 3).withMaxDigits(2)),
744 Locale::getEnglish(),
745 u"88,000.0", // maxSig beats maxFrac
746 u"8,800.0", // maxSig beats maxFrac
747 u"880.0", // maxSig beats maxFrac
748 u"88.0", // maxSig beats maxFrac
749 u"8.8", // maxSig beats maxFrac
750 u"0.88", // maxSig beats maxFrac
751 u"0.088",
752 u"0.009",
753 u"0.0");
754
755 assertFormatDescending(
756 u"FracSig minMaxFrac maxSig B",
757 NumberFormatter::with().rounding(Rounder::fixedFraction(2).withMaxDigits(2)),
758 Locale::getEnglish(),
759 u"88,000.00", // maxSig beats maxFrac
760 u"8,800.00", // maxSig beats maxFrac
761 u"880.00", // maxSig beats maxFrac
762 u"88.00", // maxSig beats maxFrac
763 u"8.80", // maxSig beats maxFrac
764 u"0.88",
765 u"0.09",
766 u"0.01",
767 u"0.00");
768 }
769
roundingOther()770 void NumberFormatterApiTest::roundingOther() {
771 assertFormatDescending(
772 u"Rounding None",
773 NumberFormatter::with().rounding(Rounder::unlimited()),
774 Locale::getEnglish(),
775 u"87,650",
776 u"8,765",
777 u"876.5",
778 u"87.65",
779 u"8.765",
780 u"0.8765",
781 u"0.08765",
782 u"0.008765",
783 u"0");
784
785 assertFormatDescending(
786 u"Increment",
787 NumberFormatter::with().rounding(Rounder::increment(0.5).withMinFraction(1)),
788 Locale::getEnglish(),
789 u"87,650.0",
790 u"8,765.0",
791 u"876.5",
792 u"87.5",
793 u"9.0",
794 u"1.0",
795 u"0.0",
796 u"0.0",
797 u"0.0");
798
799 assertFormatDescending(
800 u"Increment with Min Fraction",
801 NumberFormatter::with().rounding(Rounder::increment(0.5).withMinFraction(2)),
802 Locale::getEnglish(),
803 u"87,650.00",
804 u"8,765.00",
805 u"876.50",
806 u"87.50",
807 u"9.00",
808 u"1.00",
809 u"0.00",
810 u"0.00",
811 u"0.00");
812
813 assertFormatDescending(
814 u"Currency Standard",
815 NumberFormatter::with().rounding(Rounder::currency(UCurrencyUsage::UCURR_USAGE_STANDARD))
816 .unit(CZK),
817 Locale::getEnglish(),
818 u"CZK 87,650.00",
819 u"CZK 8,765.00",
820 u"CZK 876.50",
821 u"CZK 87.65",
822 u"CZK 8.76",
823 u"CZK 0.88",
824 u"CZK 0.09",
825 u"CZK 0.01",
826 u"CZK 0.00");
827
828 assertFormatDescending(
829 u"Currency Cash",
830 NumberFormatter::with().rounding(Rounder::currency(UCurrencyUsage::UCURR_USAGE_CASH))
831 .unit(CZK),
832 Locale::getEnglish(),
833 u"CZK 87,650",
834 u"CZK 8,765",
835 u"CZK 876",
836 u"CZK 88",
837 u"CZK 9",
838 u"CZK 1",
839 u"CZK 0",
840 u"CZK 0",
841 u"CZK 0");
842
843 assertFormatDescending(
844 u"Currency Cash with Nickel Rounding",
845 NumberFormatter::with().rounding(Rounder::currency(UCurrencyUsage::UCURR_USAGE_CASH))
846 .unit(CAD),
847 Locale::getEnglish(),
848 u"CA$87,650.00",
849 u"CA$8,765.00",
850 u"CA$876.50",
851 u"CA$87.65",
852 u"CA$8.75",
853 u"CA$0.90",
854 u"CA$0.10",
855 u"CA$0.00",
856 u"CA$0.00");
857
858 assertFormatDescending(
859 u"Currency not in top-level fluent chain",
860 NumberFormatter::with().rounding(
861 Rounder::currency(UCurrencyUsage::UCURR_USAGE_CASH).withCurrency(CZK)),
862 Locale::getEnglish(),
863 u"87,650",
864 u"8,765",
865 u"876",
866 u"88",
867 u"9",
868 u"1",
869 u"0",
870 u"0",
871 u"0");
872
873 // NOTE: Other tests cover the behavior of the other rounding modes.
874 assertFormatDescending(
875 u"Rounding Mode CEILING",
876 NumberFormatter::with().rounding(Rounder::integer().withMode(UNumberFormatRoundingMode::UNUM_ROUND_CEILING)),
877 Locale::getEnglish(),
878 u"87,650",
879 u"8,765",
880 u"877",
881 u"88",
882 u"9",
883 u"1",
884 u"1",
885 u"1",
886 u"0");
887 }
888
grouping()889 void NumberFormatterApiTest::grouping() {
890 assertFormatDescendingBig(
891 u"Western Grouping",
892 NumberFormatter::with().grouping(Grouper::defaults()),
893 Locale::getEnglish(),
894 u"87,650,000",
895 u"8,765,000",
896 u"876,500",
897 u"87,650",
898 u"8,765",
899 u"876.5",
900 u"87.65",
901 u"8.765",
902 u"0");
903
904 assertFormatDescendingBig(
905 u"Indic Grouping",
906 NumberFormatter::with().grouping(Grouper::defaults()),
907 Locale("en-IN"),
908 u"8,76,50,000",
909 u"87,65,000",
910 u"8,76,500",
911 u"87,650",
912 u"8,765",
913 u"876.5",
914 u"87.65",
915 u"8.765",
916 u"0");
917
918 assertFormatDescendingBig(
919 u"Western Grouping, Wide",
920 NumberFormatter::with().grouping(Grouper::minTwoDigits()),
921 Locale::getEnglish(),
922 u"87,650,000",
923 u"8,765,000",
924 u"876,500",
925 u"87,650",
926 u"8765",
927 u"876.5",
928 u"87.65",
929 u"8.765",
930 u"0");
931
932 assertFormatDescendingBig(
933 u"Indic Grouping, Wide",
934 NumberFormatter::with().grouping(Grouper::minTwoDigits()),
935 Locale("en-IN"),
936 u"8,76,50,000",
937 u"87,65,000",
938 u"8,76,500",
939 u"87,650",
940 u"8765",
941 u"876.5",
942 u"87.65",
943 u"8.765",
944 u"0");
945
946 assertFormatDescendingBig(
947 u"No Grouping",
948 NumberFormatter::with().grouping(Grouper::none()),
949 Locale("en-IN"),
950 u"87650000",
951 u"8765000",
952 u"876500",
953 u"87650",
954 u"8765",
955 u"876.5",
956 u"87.65",
957 u"8.765",
958 u"0");
959 }
960
padding()961 void NumberFormatterApiTest::padding() {
962 assertFormatDescending(
963 u"Padding",
964 NumberFormatter::with().padding(Padder::none()),
965 Locale::getEnglish(),
966 u"87,650",
967 u"8,765",
968 u"876.5",
969 u"87.65",
970 u"8.765",
971 u"0.8765",
972 u"0.08765",
973 u"0.008765",
974 u"0");
975
976 assertFormatDescending(
977 u"Padding",
978 NumberFormatter::with().padding(
979 Padder::codePoints(
980 '*', 8, PadPosition::UNUM_PAD_AFTER_PREFIX)),
981 Locale::getEnglish(),
982 u"**87,650",
983 u"***8,765",
984 u"***876.5",
985 u"***87.65",
986 u"***8.765",
987 u"**0.8765",
988 u"*0.08765",
989 u"0.008765",
990 u"*******0");
991
992 assertFormatDescending(
993 u"Padding with code points",
994 NumberFormatter::with().padding(
995 Padder::codePoints(
996 0x101E4, 8, PadPosition::UNUM_PAD_AFTER_PREFIX)),
997 Locale::getEnglish(),
998 u"87,650",
999 u"8,765",
1000 u"876.5",
1001 u"87.65",
1002 u"8.765",
1003 u"0.8765",
1004 u"0.08765",
1005 u"0.008765",
1006 u"0");
1007
1008 assertFormatDescending(
1009 u"Padding with wide digits",
1010 NumberFormatter::with().padding(
1011 Padder::codePoints(
1012 '*', 8, PadPosition::UNUM_PAD_AFTER_PREFIX))
1013 .adoptSymbols(new NumberingSystem(MATHSANB)),
1014 Locale::getEnglish(),
1015 u"**,",
1016 u"***,",
1017 u"***.",
1018 u"***.",
1019 u"***.",
1020 u"**.",
1021 u"*.",
1022 u".",
1023 u"*******");
1024
1025 assertFormatDescending(
1026 u"Padding with currency spacing",
1027 NumberFormatter::with().padding(
1028 Padder::codePoints(
1029 '*', 10, PadPosition::UNUM_PAD_AFTER_PREFIX))
1030 .unit(GBP)
1031 .unitWidth(UNumberUnitWidth::UNUM_UNIT_WIDTH_ISO_CODE),
1032 Locale::getEnglish(),
1033 u"GBP 87,650.00",
1034 u"GBP 8,765.00",
1035 u"GBP*876.50",
1036 u"GBP**87.65",
1037 u"GBP***8.76",
1038 u"GBP***0.88",
1039 u"GBP***0.09",
1040 u"GBP***0.01",
1041 u"GBP***0.00");
1042
1043 assertFormatSingle(
1044 u"Pad Before Prefix",
1045 NumberFormatter::with().padding(
1046 Padder::codePoints(
1047 '*', 8, PadPosition::UNUM_PAD_BEFORE_PREFIX)),
1048 Locale::getEnglish(),
1049 -88.88,
1050 u"**-88.88");
1051
1052 assertFormatSingle(
1053 u"Pad After Prefix",
1054 NumberFormatter::with().padding(
1055 Padder::codePoints(
1056 '*', 8, PadPosition::UNUM_PAD_AFTER_PREFIX)),
1057 Locale::getEnglish(),
1058 -88.88,
1059 u"-**88.88");
1060
1061 assertFormatSingle(
1062 u"Pad Before Suffix",
1063 NumberFormatter::with().padding(
1064 Padder::codePoints(
1065 '*', 8, PadPosition::UNUM_PAD_BEFORE_SUFFIX)).unit(NoUnit::percent()),
1066 Locale::getEnglish(),
1067 88.88,
1068 u"88.88**%");
1069
1070 assertFormatSingle(
1071 u"Pad After Suffix",
1072 NumberFormatter::with().padding(
1073 Padder::codePoints(
1074 '*', 8, PadPosition::UNUM_PAD_AFTER_SUFFIX)).unit(NoUnit::percent()),
1075 Locale::getEnglish(),
1076 88.88,
1077 u"88.88%**");
1078
1079 assertFormatSingle(
1080 u"Currency Spacing with Zero Digit Padding Broken",
1081 NumberFormatter::with().padding(
1082 Padder::codePoints(
1083 '0', 12, PadPosition::UNUM_PAD_AFTER_PREFIX))
1084 .unit(GBP)
1085 .unitWidth(UNumberUnitWidth::UNUM_UNIT_WIDTH_ISO_CODE),
1086 Locale::getEnglish(),
1087 514.23,
1088 u"GBP 000514.23"); // TODO: This is broken; it renders too wide (13 instead of 12).
1089 }
1090
integerWidth()1091 void NumberFormatterApiTest::integerWidth() {
1092 assertFormatDescending(
1093 u"Integer Width Default",
1094 NumberFormatter::with().integerWidth(IntegerWidth::zeroFillTo(1)),
1095 Locale::getEnglish(),
1096 u"87,650",
1097 u"8,765",
1098 u"876.5",
1099 u"87.65",
1100 u"8.765",
1101 u"0.8765",
1102 u"0.08765",
1103 u"0.008765",
1104 u"0");
1105
1106 assertFormatDescending(
1107 u"Integer Width Zero Fill 0",
1108 NumberFormatter::with().integerWidth(IntegerWidth::zeroFillTo(0)),
1109 Locale::getEnglish(),
1110 u"87,650",
1111 u"8,765",
1112 u"876.5",
1113 u"87.65",
1114 u"8.765",
1115 u".8765",
1116 u".08765",
1117 u".008765",
1118 u""); // TODO: Avoid the empty string here?
1119
1120 assertFormatDescending(
1121 u"Integer Width Zero Fill 3",
1122 NumberFormatter::with().integerWidth(IntegerWidth::zeroFillTo(3)),
1123 Locale::getEnglish(),
1124 u"87,650",
1125 u"8,765",
1126 u"876.5",
1127 u"087.65",
1128 u"008.765",
1129 u"000.8765",
1130 u"000.08765",
1131 u"000.008765",
1132 u"000");
1133
1134 assertFormatDescending(
1135 u"Integer Width Max 3",
1136 NumberFormatter::with().integerWidth(IntegerWidth::zeroFillTo(1).truncateAt(3)),
1137 Locale::getEnglish(),
1138 u"650",
1139 u"765",
1140 u"876.5",
1141 u"87.65",
1142 u"8.765",
1143 u"0.8765",
1144 u"0.08765",
1145 u"0.008765",
1146 u"0");
1147
1148 assertFormatDescending(
1149 u"Integer Width Fixed 2",
1150 NumberFormatter::with().integerWidth(IntegerWidth::zeroFillTo(2).truncateAt(2)),
1151 Locale::getEnglish(),
1152 u"50",
1153 u"65",
1154 u"76.5",
1155 u"87.65",
1156 u"08.765",
1157 u"00.8765",
1158 u"00.08765",
1159 u"00.008765",
1160 u"00");
1161 }
1162
symbols()1163 void NumberFormatterApiTest::symbols() {
1164 assertFormatDescending(
1165 u"French Symbols with Japanese Data 1",
1166 NumberFormatter::with().symbols(FRENCH_SYMBOLS),
1167 Locale::getJapan(),
1168 u"87 650",
1169 u"8 765",
1170 u"876,5",
1171 u"87,65",
1172 u"8,765",
1173 u"0,8765",
1174 u"0,08765",
1175 u"0,008765",
1176 u"0");
1177
1178 assertFormatSingle(
1179 u"French Symbols with Japanese Data 2",
1180 NumberFormatter::with().notation(Notation::compactShort()).symbols(FRENCH_SYMBOLS),
1181 Locale::getJapan(),
1182 12345,
1183 u"1,2\u4E07");
1184
1185 assertFormatDescending(
1186 u"Latin Numbering System with Arabic Data",
1187 NumberFormatter::with().adoptSymbols(new NumberingSystem(LATN)).unit(USD),
1188 Locale("ar"),
1189 u"US$ 87,650.00",
1190 u"US$ 8,765.00",
1191 u"US$ 876.50",
1192 u"US$ 87.65",
1193 u"US$ 8.76",
1194 u"US$ 0.88",
1195 u"US$ 0.09",
1196 u"US$ 0.01",
1197 u"US$ 0.00");
1198
1199 assertFormatDescending(
1200 u"Math Numbering System with French Data",
1201 NumberFormatter::with().adoptSymbols(new NumberingSystem(MATHSANB)),
1202 Locale::getFrench(),
1203 u" ",
1204 u" ",
1205 u",",
1206 u",",
1207 u",",
1208 u",",
1209 u",",
1210 u",",
1211 u"");
1212
1213 assertFormatSingle(
1214 u"Swiss Symbols (used in documentation)",
1215 NumberFormatter::with().symbols(SWISS_SYMBOLS),
1216 Locale::getEnglish(),
1217 12345.67,
1218 u"12’345.67");
1219
1220 assertFormatSingle(
1221 u"Myanmar Symbols (used in documentation)",
1222 NumberFormatter::with().symbols(MYANMAR_SYMBOLS),
1223 Locale::getEnglish(),
1224 12345.67,
1225 u"\u1041\u1042,\u1043\u1044\u1045.\u1046\u1047");
1226
1227 // NOTE: Locale ar puts ¤ after the number in NS arab but before the number in NS latn.
1228
1229 assertFormatSingle(
1230 u"Currency symbol should precede number in ar with NS latn",
1231 NumberFormatter::with().adoptSymbols(new NumberingSystem(LATN)).unit(USD),
1232 Locale("ar"),
1233 12345.67,
1234 u"US$ 12,345.67");
1235
1236 assertFormatSingle(
1237 u"Currency symbol should precede number in ar@numbers=latn",
1238 NumberFormatter::with().unit(USD),
1239 Locale("ar@numbers=latn"),
1240 12345.67,
1241 u"US$ 12,345.67");
1242
1243 assertFormatSingle(
1244 u"Currency symbol should follow number in ar with NS arab",
1245 NumberFormatter::with().unit(USD),
1246 Locale("ar"),
1247 12345.67,
1248 u"١٢٬٣٤٥٫٦٧ US$");
1249
1250 assertFormatSingle(
1251 u"Currency symbol should follow number in ar@numbers=arab",
1252 NumberFormatter::with().unit(USD),
1253 Locale("ar@numbers=arab"),
1254 12345.67,
1255 u"١٢٬٣٤٥٫٦٧ US$");
1256
1257 UErrorCode status = U_ZERO_ERROR;
1258 DecimalFormatSymbols symbols = SWISS_SYMBOLS;
1259 UnlocalizedNumberFormatter f = NumberFormatter::with().symbols(symbols);
1260 symbols.setSymbol(DecimalFormatSymbols::ENumberFormatSymbol::kGroupingSeparatorSymbol, u"!", status);
1261 assertFormatSingle(
1262 u"Symbols object should be copied", f, Locale::getEnglish(), 12345.67, u"12’345.67");
1263
1264 assertFormatSingle(
1265 u"The last symbols setter wins",
1266 NumberFormatter::with().symbols(symbols).adoptSymbols(new NumberingSystem(LATN)),
1267 Locale::getEnglish(),
1268 12345.67,
1269 u"12,345.67");
1270
1271 assertFormatSingle(
1272 u"The last symbols setter wins",
1273 NumberFormatter::with().adoptSymbols(new NumberingSystem(LATN)).symbols(symbols),
1274 Locale::getEnglish(),
1275 12345.67,
1276 u"12!345.67");
1277 }
1278
1279 // TODO: Enable if/when currency symbol override is added.
1280 //void NumberFormatterTest::symbolsOverride() {
1281 // DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(Locale::getEnglish());
1282 // dfs.setCurrencySymbol("@");
1283 // dfs.setInternationalCurrencySymbol("foo");
1284 // assertFormatSingle(
1285 // u"Custom Short Currency Symbol",
1286 // NumberFormatter::with().unit(Currency.getInstance("XXX")).symbols(dfs),
1287 // Locale::getEnglish(),
1288 // 12.3,
1289 // u"@ 12.30");
1290 //}
1291
sign()1292 void NumberFormatterApiTest::sign() {
1293 assertFormatSingle(
1294 u"Sign Auto Positive",
1295 NumberFormatter::with().sign(UNumberSignDisplay::UNUM_SIGN_AUTO),
1296 Locale::getEnglish(),
1297 444444,
1298 u"444,444");
1299
1300 assertFormatSingle(
1301 u"Sign Auto Negative",
1302 NumberFormatter::with().sign(UNumberSignDisplay::UNUM_SIGN_AUTO),
1303 Locale::getEnglish(),
1304 -444444,
1305 u"-444,444");
1306
1307 assertFormatSingle(
1308 u"Sign Always Positive",
1309 NumberFormatter::with().sign(UNumberSignDisplay::UNUM_SIGN_ALWAYS),
1310 Locale::getEnglish(),
1311 444444,
1312 u"+444,444");
1313
1314 assertFormatSingle(
1315 u"Sign Always Negative",
1316 NumberFormatter::with().sign(UNumberSignDisplay::UNUM_SIGN_ALWAYS),
1317 Locale::getEnglish(),
1318 -444444,
1319 u"-444,444");
1320
1321 assertFormatSingle(
1322 u"Sign Never Positive",
1323 NumberFormatter::with().sign(UNumberSignDisplay::UNUM_SIGN_NEVER),
1324 Locale::getEnglish(),
1325 444444,
1326 u"444,444");
1327
1328 assertFormatSingle(
1329 u"Sign Never Negative",
1330 NumberFormatter::with().sign(UNumberSignDisplay::UNUM_SIGN_NEVER),
1331 Locale::getEnglish(),
1332 -444444,
1333 u"444,444");
1334
1335 assertFormatSingle(
1336 u"Sign Accounting Positive",
1337 NumberFormatter::with().sign(UNumberSignDisplay::UNUM_SIGN_ACCOUNTING).unit(USD),
1338 Locale::getEnglish(),
1339 444444,
1340 u"$444,444.00");
1341
1342 assertFormatSingle(
1343 u"Sign Accounting Negative",
1344 NumberFormatter::with().sign(UNumberSignDisplay::UNUM_SIGN_ACCOUNTING).unit(USD),
1345 Locale::getEnglish(),
1346 -444444,
1347 u"($444,444.00)");
1348
1349 assertFormatSingle(
1350 u"Sign Accounting-Always Positive",
1351 NumberFormatter::with().sign(UNumberSignDisplay::UNUM_SIGN_ACCOUNTING_ALWAYS).unit(USD),
1352 Locale::getEnglish(),
1353 444444,
1354 u"+$444,444.00");
1355
1356 assertFormatSingle(
1357 u"Sign Accounting-Always Negative",
1358 NumberFormatter::with().sign(UNumberSignDisplay::UNUM_SIGN_ACCOUNTING_ALWAYS).unit(USD),
1359 Locale::getEnglish(),
1360 -444444,
1361 u"($444,444.00)");
1362
1363 assertFormatSingle(
1364 u"Sign Accounting Negative Hidden",
1365 NumberFormatter::with().sign(UNumberSignDisplay::UNUM_SIGN_ACCOUNTING)
1366 .unit(USD)
1367 .unitWidth(UNUM_UNIT_WIDTH_HIDDEN),
1368 Locale::getEnglish(),
1369 -444444,
1370 u"(444,444.00)");
1371 }
1372
decimal()1373 void NumberFormatterApiTest::decimal() {
1374 assertFormatDescending(
1375 u"Decimal Default",
1376 NumberFormatter::with().decimal(UNumberDecimalSeparatorDisplay::UNUM_DECIMAL_SEPARATOR_AUTO),
1377 Locale::getEnglish(),
1378 u"87,650",
1379 u"8,765",
1380 u"876.5",
1381 u"87.65",
1382 u"8.765",
1383 u"0.8765",
1384 u"0.08765",
1385 u"0.008765",
1386 u"0");
1387
1388 assertFormatDescending(
1389 u"Decimal Always Shown",
1390 NumberFormatter::with().decimal(UNumberDecimalSeparatorDisplay::UNUM_DECIMAL_SEPARATOR_ALWAYS),
1391 Locale::getEnglish(),
1392 u"87,650.",
1393 u"8,765.",
1394 u"876.5",
1395 u"87.65",
1396 u"8.765",
1397 u"0.8765",
1398 u"0.08765",
1399 u"0.008765",
1400 u"0.");
1401 }
1402
locale()1403 void NumberFormatterApiTest::locale() {
1404 // Coverage for the locale setters.
1405 UErrorCode status = U_ZERO_ERROR;
1406 UnicodeString actual = NumberFormatter::withLocale(Locale::getFrench()).formatInt(1234, status)
1407 .toString();
1408 assertEquals("Locale withLocale()", u"1 234", actual);
1409 }
1410
formatTypes()1411 void NumberFormatterApiTest::formatTypes() {
1412 UErrorCode status = U_ZERO_ERROR;
1413 LocalizedNumberFormatter formatter = NumberFormatter::withLocale(Locale::getEnglish());
1414 const char* str1 = "98765432123456789E1";
1415 UnicodeString actual = formatter.formatDecimal(str1, status).toString();
1416 assertEquals("Format decNumber", u"987,654,321,234,567,890", actual);
1417 }
1418
errors()1419 void NumberFormatterApiTest::errors() {
1420 LocalizedNumberFormatter lnf = NumberFormatter::withLocale(Locale::getEnglish()).rounding(
1421 Rounder::fixedFraction(
1422 -1));
1423
1424 {
1425 UErrorCode status1 = U_ZERO_ERROR;
1426 UErrorCode status2 = U_ZERO_ERROR;
1427 FormattedNumber fn = lnf.formatInt(1, status1);
1428 assertEquals(
1429 "Should fail with U_ILLEGAL_ARGUMENT_ERROR since rounder is not legal",
1430 U_ILLEGAL_ARGUMENT_ERROR,
1431 status1);
1432 FieldPosition fp;
1433 fn.populateFieldPosition(fp, status2);
1434 assertEquals(
1435 "Should fail with U_ILLEGAL_ARGUMENT_ERROR on terminal method",
1436 U_ILLEGAL_ARGUMENT_ERROR,
1437 status2);
1438 }
1439
1440 {
1441 UErrorCode status = U_ZERO_ERROR;
1442 lnf.copyErrorTo(status);
1443 assertEquals(
1444 "Should fail with U_ILLEGAL_ARGUMENT_ERROR since rounder is not legal",
1445 U_ILLEGAL_ARGUMENT_ERROR,
1446 status);
1447 }
1448 }
1449
1450
assertFormatDescending(const UnicodeString & message,const UnlocalizedNumberFormatter & f,Locale locale,...)1451 void NumberFormatterApiTest::assertFormatDescending(const UnicodeString &message,
1452 const UnlocalizedNumberFormatter &f,
1453 Locale locale, ...) {
1454 va_list args;
1455 va_start(args, locale);
1456 static double inputs[] = {87650, 8765, 876.5, 87.65, 8.765, 0.8765, 0.08765, 0.008765, 0};
1457 const LocalizedNumberFormatter l1 = f.threshold(0).locale(locale); // no self-regulation
1458 const LocalizedNumberFormatter l2 = f.threshold(1).locale(locale); // all self-regulation
1459 UErrorCode status = U_ZERO_ERROR;
1460 for (int16_t i = 0; i < 9; i++) {
1461 char16_t caseNumber = u'0' + i;
1462 double d = inputs[i];
1463 UnicodeString expected = va_arg(args, const char16_t*);
1464 UnicodeString actual1 = l1.formatDouble(d, status).toString();
1465 assertSuccess(message + u": Unsafe Path: " + caseNumber, status);
1466 assertEquals(message + u": Unsafe Path: " + caseNumber, expected, actual1);
1467 UnicodeString actual2 = l2.formatDouble(d, status).toString();
1468 assertSuccess(message + u": Safe Path: " + caseNumber, status);
1469 assertEquals(message + u": Safe Path: " + caseNumber, expected, actual2);
1470 }
1471 }
1472
assertFormatDescendingBig(const UnicodeString & message,const UnlocalizedNumberFormatter & f,Locale locale,...)1473 void NumberFormatterApiTest::assertFormatDescendingBig(const UnicodeString &message,
1474 const UnlocalizedNumberFormatter &f,
1475 Locale locale, ...) {
1476 va_list args;
1477 va_start(args, locale);
1478 static double inputs[] = {87650000, 8765000, 876500, 87650, 8765, 876.5, 87.65, 8.765, 0};
1479 const LocalizedNumberFormatter l1 = f.threshold(0).locale(locale); // no self-regulation
1480 const LocalizedNumberFormatter l2 = f.threshold(1).locale(locale); // all self-regulation
1481 UErrorCode status = U_ZERO_ERROR;
1482 for (int16_t i = 0; i < 9; i++) {
1483 char16_t caseNumber = u'0' + i;
1484 double d = inputs[i];
1485 UnicodeString expected = va_arg(args, const char16_t*);
1486 UnicodeString actual1 = l1.formatDouble(d, status).toString();
1487 assertSuccess(message + u": Unsafe Path: " + caseNumber, status);
1488 assertEquals(message + u": Unsafe Path: " + caseNumber, expected, actual1);
1489 UnicodeString actual2 = l2.formatDouble(d, status).toString();
1490 assertSuccess(message + u": Safe Path: " + caseNumber, status);
1491 assertEquals(message + u": Safe Path: " + caseNumber, expected, actual2);
1492 }
1493 }
1494
assertFormatSingle(const UnicodeString & message,const UnlocalizedNumberFormatter & f,Locale locale,double input,const UnicodeString & expected)1495 void NumberFormatterApiTest::assertFormatSingle(const UnicodeString &message,
1496 const UnlocalizedNumberFormatter &f, Locale locale,
1497 double input, const UnicodeString &expected) {
1498 const LocalizedNumberFormatter l1 = f.threshold(0).locale(locale); // no self-regulation
1499 const LocalizedNumberFormatter l2 = f.threshold(1).locale(locale); // all self-regulation
1500 UErrorCode status = U_ZERO_ERROR;
1501 UnicodeString actual1 = l1.formatDouble(input, status).toString();
1502 assertSuccess(message + u": Unsafe Path", status);
1503 assertEquals(message + u": Unsafe Path", expected, actual1);
1504 UnicodeString actual2 = l2.formatDouble(input, status).toString();
1505 assertSuccess(message + u": Safe Path", status);
1506 assertEquals(message + u": Safe Path", expected, actual2);
1507 }
1508
1509 #endif /* #if !UCONFIG_NO_FORMATTING */
1510