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