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...
16UErrorCode globalNumberFormatterApiTestStatus = U_ZERO_ERROR;
17
18NumberFormatterApiTest::NumberFormatterApiTest()
19        : NumberFormatterApiTest(globalNumberFormatterApiTestStatus) {
20}
21
22NumberFormatterApiTest::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
54void 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
83void 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
107void 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
173void 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
356void 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
472void 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
552void 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
596void 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
668void 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
712void 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
770void 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
889void 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
961void 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
1091void 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
1163void 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
1292void 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
1373void 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
1403void 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
1411void 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
1419void 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
1451void 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
1473void 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
1495void 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