12e5b6d6dSopenharmony_ci// © 2016 and later: Unicode, Inc. and others.
22e5b6d6dSopenharmony_ci// License & terms of use: http://www.unicode.org/copyright.html
32e5b6d6dSopenharmony_ci/*
42e5b6d6dSopenharmony_ci*******************************************************************************
52e5b6d6dSopenharmony_ci* Copyright (C) 2014-2015, International Business Machines Corporation and         *
62e5b6d6dSopenharmony_ci* others. All Rights Reserved.                                                *
72e5b6d6dSopenharmony_ci*******************************************************************************
82e5b6d6dSopenharmony_ci*
92e5b6d6dSopenharmony_ci* File numfmtspectest.cpp
102e5b6d6dSopenharmony_ci*
112e5b6d6dSopenharmony_ci*******************************************************************************
122e5b6d6dSopenharmony_ci*/
132e5b6d6dSopenharmony_ci#include <stdio.h>
142e5b6d6dSopenharmony_ci#include <stdlib.h>
152e5b6d6dSopenharmony_ci
162e5b6d6dSopenharmony_ci#include "intltest.h"
172e5b6d6dSopenharmony_ci
182e5b6d6dSopenharmony_ci#if !UCONFIG_NO_FORMATTING
192e5b6d6dSopenharmony_ci
202e5b6d6dSopenharmony_ci#include "unicode/localpointer.h"
212e5b6d6dSopenharmony_ci#include "unicode/decimfmt.h"
222e5b6d6dSopenharmony_ci#include "unicode/dtfmtsym.h"
232e5b6d6dSopenharmony_ci#include "uassert.h"
242e5b6d6dSopenharmony_ci
252e5b6d6dSopenharmony_cistatic const UChar kJPY[] = {0x4A, 0x50, 0x59};
262e5b6d6dSopenharmony_ci
272e5b6d6dSopenharmony_cistatic void fixNonBreakingSpace(UnicodeString &str) {
282e5b6d6dSopenharmony_ci    for (int32_t i = 0; i < str.length(); ++i) {
292e5b6d6dSopenharmony_ci        if (str[i] == 0xa0) {
302e5b6d6dSopenharmony_ci            str.setCharAt(i, 0x20);
312e5b6d6dSopenharmony_ci        }
322e5b6d6dSopenharmony_ci    }
332e5b6d6dSopenharmony_ci}
342e5b6d6dSopenharmony_ci
352e5b6d6dSopenharmony_cistatic NumberFormat *nfWithPattern(const char *pattern) {
362e5b6d6dSopenharmony_ci    UnicodeString upattern(pattern, -1, US_INV);
372e5b6d6dSopenharmony_ci    upattern = upattern.unescape();
382e5b6d6dSopenharmony_ci    UErrorCode status = U_ZERO_ERROR;
392e5b6d6dSopenharmony_ci    DecimalFormat *result = new DecimalFormat(
402e5b6d6dSopenharmony_ci            upattern, new DecimalFormatSymbols("fr", status), status);
412e5b6d6dSopenharmony_ci    if (U_FAILURE(status)) {
422e5b6d6dSopenharmony_ci        return NULL;
432e5b6d6dSopenharmony_ci    }
442e5b6d6dSopenharmony_ci
452e5b6d6dSopenharmony_ci    return result;
462e5b6d6dSopenharmony_ci}
472e5b6d6dSopenharmony_ci
482e5b6d6dSopenharmony_cistatic UnicodeString format(double d, const NumberFormat &fmt) {
492e5b6d6dSopenharmony_ci    UnicodeString result;
502e5b6d6dSopenharmony_ci    fmt.format(d, result);
512e5b6d6dSopenharmony_ci    fixNonBreakingSpace(result);
522e5b6d6dSopenharmony_ci    return result;
532e5b6d6dSopenharmony_ci}
542e5b6d6dSopenharmony_ci
552e5b6d6dSopenharmony_ciclass NumberFormatSpecificationTest : public IntlTest {
562e5b6d6dSopenharmony_cipublic:
572e5b6d6dSopenharmony_ci    NumberFormatSpecificationTest() {
582e5b6d6dSopenharmony_ci    }
592e5b6d6dSopenharmony_ci    void TestBasicPatterns();
602e5b6d6dSopenharmony_ci    void TestNfSetters();
612e5b6d6dSopenharmony_ci    void TestRounding();
622e5b6d6dSopenharmony_ci    void TestSignificantDigits();
632e5b6d6dSopenharmony_ci    void TestScientificNotation();
642e5b6d6dSopenharmony_ci    void TestPercent();
652e5b6d6dSopenharmony_ci    void TestPerMilli();
662e5b6d6dSopenharmony_ci    void TestPadding();
672e5b6d6dSopenharmony_ci    void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par=0) override;
682e5b6d6dSopenharmony_ciprivate:
692e5b6d6dSopenharmony_ci    void assertPatternFr(
702e5b6d6dSopenharmony_ci            const char *expected, double x, const char *pattern, UBool possibleDataError=false);
712e5b6d6dSopenharmony_ci
722e5b6d6dSopenharmony_ci};
732e5b6d6dSopenharmony_ci
742e5b6d6dSopenharmony_civoid NumberFormatSpecificationTest::runIndexedTest(
752e5b6d6dSopenharmony_ci        int32_t index, UBool exec, const char *&name, char *) {
762e5b6d6dSopenharmony_ci    if (exec) {
772e5b6d6dSopenharmony_ci        logln("TestSuite NumberFormatSpecificationTest: ");
782e5b6d6dSopenharmony_ci    }
792e5b6d6dSopenharmony_ci    TESTCASE_AUTO_BEGIN;
802e5b6d6dSopenharmony_ci    TESTCASE_AUTO(TestBasicPatterns);
812e5b6d6dSopenharmony_ci    TESTCASE_AUTO(TestNfSetters);
822e5b6d6dSopenharmony_ci    TESTCASE_AUTO(TestRounding);
832e5b6d6dSopenharmony_ci    TESTCASE_AUTO(TestSignificantDigits);
842e5b6d6dSopenharmony_ci    TESTCASE_AUTO(TestScientificNotation);
852e5b6d6dSopenharmony_ci    TESTCASE_AUTO(TestPercent);
862e5b6d6dSopenharmony_ci    TESTCASE_AUTO(TestPerMilli);
872e5b6d6dSopenharmony_ci    TESTCASE_AUTO(TestPadding);
882e5b6d6dSopenharmony_ci    TESTCASE_AUTO_END;
892e5b6d6dSopenharmony_ci}
902e5b6d6dSopenharmony_ci
912e5b6d6dSopenharmony_civoid NumberFormatSpecificationTest::TestBasicPatterns() {
922e5b6d6dSopenharmony_ci    assertPatternFr("1\\u202F234,57", 1234.567, "#,##0.##", true);
932e5b6d6dSopenharmony_ci    assertPatternFr("1234,57", 1234.567, "0.##", true);
942e5b6d6dSopenharmony_ci    assertPatternFr("1235", 1234.567, "0", true);
952e5b6d6dSopenharmony_ci    assertPatternFr("1\\u202F234,567", 1234.567, "#,##0.###", true);
962e5b6d6dSopenharmony_ci    assertPatternFr("1234,567", 1234.567, "###0.#####", true);
972e5b6d6dSopenharmony_ci    assertPatternFr("1234,5670", 1234.567, "###0.0000#", true);
982e5b6d6dSopenharmony_ci    assertPatternFr("01234,5670", 1234.567, "00000.0000", true);
992e5b6d6dSopenharmony_ci    assertPatternFr("1\\u202F234,57 \\u20ac", 1234.567, "#,##0.00 \\u00a4", true);
1002e5b6d6dSopenharmony_ci}
1012e5b6d6dSopenharmony_ci
1022e5b6d6dSopenharmony_civoid NumberFormatSpecificationTest::TestNfSetters() {
1032e5b6d6dSopenharmony_ci    LocalPointer<NumberFormat> nf(nfWithPattern("#,##0.##"));
1042e5b6d6dSopenharmony_ci    if (nf == NULL) {
1052e5b6d6dSopenharmony_ci        dataerrln("Error creating NumberFormat");
1062e5b6d6dSopenharmony_ci        return;
1072e5b6d6dSopenharmony_ci    }
1082e5b6d6dSopenharmony_ci    nf->setMaximumIntegerDigits(5);
1092e5b6d6dSopenharmony_ci    nf->setMinimumIntegerDigits(4);
1102e5b6d6dSopenharmony_ci    assertEquals("", u"34\u202F567,89", format(1234567.89, *nf), true);
1112e5b6d6dSopenharmony_ci    assertEquals("", u"0\u202F034,56", format(34.56, *nf), true);
1122e5b6d6dSopenharmony_ci}
1132e5b6d6dSopenharmony_ci
1142e5b6d6dSopenharmony_civoid NumberFormatSpecificationTest::TestRounding() {
1152e5b6d6dSopenharmony_ci    assertPatternFr("1,0", 1.25, "0.5", true);
1162e5b6d6dSopenharmony_ci    assertPatternFr("2,0", 1.75, "0.5", true);
1172e5b6d6dSopenharmony_ci    assertPatternFr("-1,0", -1.25, "0.5", true);
1182e5b6d6dSopenharmony_ci    assertPatternFr("-02,0", -1.75, "00.5", true);
1192e5b6d6dSopenharmony_ci    assertPatternFr("0", 2.0, "4", true);
1202e5b6d6dSopenharmony_ci    assertPatternFr("8", 6.0, "4", true);
1212e5b6d6dSopenharmony_ci    assertPatternFr("8", 10.0, "4", true);
1222e5b6d6dSopenharmony_ci    assertPatternFr("99,90", 99.0, "2.70", true);
1232e5b6d6dSopenharmony_ci    assertPatternFr("273,00", 272.0, "2.73", true);
1242e5b6d6dSopenharmony_ci    assertPatternFr("1\\u202F03,60", 104.0, "#,#3.70", true);
1252e5b6d6dSopenharmony_ci}
1262e5b6d6dSopenharmony_ci
1272e5b6d6dSopenharmony_civoid NumberFormatSpecificationTest::TestSignificantDigits() {
1282e5b6d6dSopenharmony_ci    assertPatternFr("1230", 1234.0, "@@@", true);
1292e5b6d6dSopenharmony_ci    assertPatternFr("1\\u202F234", 1234.0, "@,@@@", true);
1302e5b6d6dSopenharmony_ci    assertPatternFr("1\\u202F235\\u202F000", 1234567.0, "@,@@@", true);
1312e5b6d6dSopenharmony_ci    assertPatternFr("1\\u202F234\\u202F567", 1234567.0, "@@@@,@@@", true);
1322e5b6d6dSopenharmony_ci    assertPatternFr("12\\u202F34\\u202F567,00", 1234567.0, "@@@@,@@,@@@", true);
1332e5b6d6dSopenharmony_ci    assertPatternFr("12\\u202F34\\u202F567,0", 1234567.0, "@@@@,@@,@@#", true);
1342e5b6d6dSopenharmony_ci    assertPatternFr("12\\u202F34\\u202F567", 1234567.0, "@@@@,@@,@##", true);
1352e5b6d6dSopenharmony_ci    assertPatternFr("12\\u202F34\\u202F567", 1234567.001, "@@@@,@@,@##", true);
1362e5b6d6dSopenharmony_ci    assertPatternFr("12\\u202F34\\u202F567", 1234567.001, "@@@@,@@,###", true);
1372e5b6d6dSopenharmony_ci    assertPatternFr("1\\u202F200", 1234.0, "#,#@@", true);
1382e5b6d6dSopenharmony_ci}
1392e5b6d6dSopenharmony_ci
1402e5b6d6dSopenharmony_civoid NumberFormatSpecificationTest::TestScientificNotation() {
1412e5b6d6dSopenharmony_ci    assertPatternFr("1,23E4", 12345.0, "0.00E0", true);
1422e5b6d6dSopenharmony_ci    assertPatternFr("123,00E2", 12300.0, "000.00E0", true);
1432e5b6d6dSopenharmony_ci    assertPatternFr("123,0E2", 12300.0, "000.0#E0", true);
1442e5b6d6dSopenharmony_ci    assertPatternFr("123,0E2", 12300.1, "000.0#E0", true);
1452e5b6d6dSopenharmony_ci    assertPatternFr("123,01E2", 12301.0, "000.0#E0", true);
1462e5b6d6dSopenharmony_ci    assertPatternFr("123,01E+02", 12301.0, "000.0#E+00", true);
1472e5b6d6dSopenharmony_ci    assertPatternFr("12,3E3", 12345.0, "##0.00E0", true);
1482e5b6d6dSopenharmony_ci    assertPatternFr("12,300E3", 12300.1, "##0.0000E0", true);
1492e5b6d6dSopenharmony_ci    assertPatternFr("12,30E3", 12300.1, "##0.000#E0", true);
1502e5b6d6dSopenharmony_ci    assertPatternFr("12,301E3", 12301.0, "##0.000#E0", true);
1512e5b6d6dSopenharmony_ci    assertPatternFr("1,25E4", 12301.2, "0.05E0");
1522e5b6d6dSopenharmony_ci    assertPatternFr("170,0E-3", 0.17, "##0.000#E0", true);
1532e5b6d6dSopenharmony_ci
1542e5b6d6dSopenharmony_ci}
1552e5b6d6dSopenharmony_ci
1562e5b6d6dSopenharmony_civoid NumberFormatSpecificationTest::TestPercent() {
1572e5b6d6dSopenharmony_ci    assertPatternFr("57,3%", 0.573, "0.0%", true);
1582e5b6d6dSopenharmony_ci    assertPatternFr("%57,3", 0.573, "%0.0", true);
1592e5b6d6dSopenharmony_ci    assertPatternFr("p%p57,3", 0.573, "p%p0.0", true);
1602e5b6d6dSopenharmony_ci    assertPatternFr("p%p0,6", 0.573, "p'%'p0.0", true);
1612e5b6d6dSopenharmony_ci    assertPatternFr("%3,260", 0.0326, "%@@@@", true);
1622e5b6d6dSopenharmony_ci    assertPatternFr("%1\\u202F540", 15.43, "%#,@@@", true);
1632e5b6d6dSopenharmony_ci    assertPatternFr("%1\\u202F656,4", 16.55, "%#,##4.1", true);
1642e5b6d6dSopenharmony_ci    assertPatternFr("%16,3E3", 162.55, "%##0.00E0", true);
1652e5b6d6dSopenharmony_ci}
1662e5b6d6dSopenharmony_ci
1672e5b6d6dSopenharmony_civoid NumberFormatSpecificationTest::TestPerMilli() {
1682e5b6d6dSopenharmony_ci    assertPatternFr("573,0\\u2030", 0.573, "0.0\\u2030", true);
1692e5b6d6dSopenharmony_ci    assertPatternFr("\\u2030573,0", 0.573, "\\u20300.0", true);
1702e5b6d6dSopenharmony_ci    assertPatternFr("p\\u2030p573,0", 0.573, "p\\u2030p0.0", true);
1712e5b6d6dSopenharmony_ci    assertPatternFr("p\\u2030p0,6", 0.573, "p'\\u2030'p0.0", true);
1722e5b6d6dSopenharmony_ci    assertPatternFr("\\u203032,60", 0.0326, "\\u2030@@@@", true);
1732e5b6d6dSopenharmony_ci    assertPatternFr("\\u203015\\u202F400", 15.43, "\\u2030#,@@@", true);
1742e5b6d6dSopenharmony_ci    assertPatternFr("\\u203016\\u202F551,7", 16.55, "\\u2030#,##4.1", true);
1752e5b6d6dSopenharmony_ci    assertPatternFr("\\u2030163E3", 162.55, "\\u2030##0.00E0", true);
1762e5b6d6dSopenharmony_ci}
1772e5b6d6dSopenharmony_ci
1782e5b6d6dSopenharmony_civoid NumberFormatSpecificationTest::TestPadding() {
1792e5b6d6dSopenharmony_ci    assertPatternFr("$***1\\u202F234", 1234, "$**####,##0", true);
1802e5b6d6dSopenharmony_ci    assertPatternFr("xxx$1\\u202F234", 1234, "*x$####,##0", true);
1812e5b6d6dSopenharmony_ci    assertPatternFr("1\\u202F234xxx$", 1234, "####,##0*x$", true);
1822e5b6d6dSopenharmony_ci    assertPatternFr("1\\u202F234$xxx", 1234, "####,##0$*x", true);
1832e5b6d6dSopenharmony_ci    assertPatternFr("ne1\\u202F234nx", -1234, "####,##0$*x;ne#n", true);
1842e5b6d6dSopenharmony_ci    assertPatternFr("n1\\u202F234*xx", -1234, "####,##0$*x;n#'*'", true);
1852e5b6d6dSopenharmony_ci    assertPatternFr("yyyy%432,6", 4.33, "*y%4.2######",  true);
1862e5b6d6dSopenharmony_ci    assertPatternFr("EUR *433,00", 433.0, "\\u00a4\\u00a4 **####0.00");
1872e5b6d6dSopenharmony_ci    assertPatternFr("EUR *433,00", 433.0, "\\u00a4\\u00a4 **#######0");
1882e5b6d6dSopenharmony_ci    {
1892e5b6d6dSopenharmony_ci        UnicodeString upattern("\\u00a4\\u00a4 **#######0", -1, US_INV);
1902e5b6d6dSopenharmony_ci        upattern = upattern.unescape();
1912e5b6d6dSopenharmony_ci        UErrorCode status = U_ZERO_ERROR;
1922e5b6d6dSopenharmony_ci        UnicodeString result;
1932e5b6d6dSopenharmony_ci        DecimalFormat fmt(
1942e5b6d6dSopenharmony_ci                upattern, new DecimalFormatSymbols("fr", status), status);
1952e5b6d6dSopenharmony_ci        if (U_FAILURE(status)) {
1962e5b6d6dSopenharmony_ci            dataerrln("Error creating DecimalFormat - %s", u_errorName(status));
1972e5b6d6dSopenharmony_ci        } else {
1982e5b6d6dSopenharmony_ci            fmt.setCurrency(kJPY);
1992e5b6d6dSopenharmony_ci            fmt.format(433.22, result);
2002e5b6d6dSopenharmony_ci            assertSuccess("", status);
2012e5b6d6dSopenharmony_ci            assertEquals("", "JPY ****433", result, true);
2022e5b6d6dSopenharmony_ci        }
2032e5b6d6dSopenharmony_ci    }
2042e5b6d6dSopenharmony_ci    {
2052e5b6d6dSopenharmony_ci        UnicodeString upattern(
2062e5b6d6dSopenharmony_ci            "\\u00a4\\u00a4 **#######0;\\u00a4\\u00a4 (#)", -1, US_INV);
2072e5b6d6dSopenharmony_ci        upattern = upattern.unescape();
2082e5b6d6dSopenharmony_ci        UErrorCode status = U_ZERO_ERROR;
2092e5b6d6dSopenharmony_ci        UnicodeString result;
2102e5b6d6dSopenharmony_ci        DecimalFormat fmt(
2112e5b6d6dSopenharmony_ci                upattern,
2122e5b6d6dSopenharmony_ci                new DecimalFormatSymbols("en_US", status),
2132e5b6d6dSopenharmony_ci                status);
2142e5b6d6dSopenharmony_ci        if (U_FAILURE(status)) {
2152e5b6d6dSopenharmony_ci            dataerrln("Error creating DecimalFormat - %s", u_errorName(status));
2162e5b6d6dSopenharmony_ci        } else {
2172e5b6d6dSopenharmony_ci            fmt.format(-433.22, result);
2182e5b6d6dSopenharmony_ci            assertSuccess("", status);
2192e5b6d6dSopenharmony_ci            assertEquals("", "USD (433.22)", result, true);
2202e5b6d6dSopenharmony_ci        }
2212e5b6d6dSopenharmony_ci    }
2222e5b6d6dSopenharmony_ci    const char *paddedSciPattern = "QU**00.#####E0";
2232e5b6d6dSopenharmony_ci    assertPatternFr("QU***43,3E-1", 4.33, paddedSciPattern, true);
2242e5b6d6dSopenharmony_ci    {
2252e5b6d6dSopenharmony_ci        UErrorCode status = U_ZERO_ERROR;
2262e5b6d6dSopenharmony_ci        DecimalFormatSymbols *sym = new DecimalFormatSymbols("fr", status);
2272e5b6d6dSopenharmony_ci        sym->setSymbol(DecimalFormatSymbols::kExponentialSymbol, "EE");
2282e5b6d6dSopenharmony_ci        DecimalFormat fmt(
2292e5b6d6dSopenharmony_ci                paddedSciPattern,
2302e5b6d6dSopenharmony_ci                sym,
2312e5b6d6dSopenharmony_ci                status);
2322e5b6d6dSopenharmony_ci        if (U_FAILURE(status)) {
2332e5b6d6dSopenharmony_ci            dataerrln("Error creating DecimalFormat - %s", u_errorName(status));
2342e5b6d6dSopenharmony_ci        } else {
2352e5b6d6dSopenharmony_ci            UnicodeString result;
2362e5b6d6dSopenharmony_ci            fmt.format(4.33, result);
2372e5b6d6dSopenharmony_ci            assertSuccess("", status);
2382e5b6d6dSopenharmony_ci            assertEquals("", "QU**43,3EE-1", result, true);
2392e5b6d6dSopenharmony_ci        }
2402e5b6d6dSopenharmony_ci    }
2412e5b6d6dSopenharmony_ci    // padding cannot work as intended with scientific notation.
2422e5b6d6dSopenharmony_ci    assertPatternFr("QU**43,32E-1", 4.332, paddedSciPattern, true);
2432e5b6d6dSopenharmony_ci}
2442e5b6d6dSopenharmony_ci
2452e5b6d6dSopenharmony_civoid NumberFormatSpecificationTest::assertPatternFr(
2462e5b6d6dSopenharmony_ci        const char *expected,
2472e5b6d6dSopenharmony_ci        double x,
2482e5b6d6dSopenharmony_ci        const char *pattern,
2492e5b6d6dSopenharmony_ci        UBool possibleDataError) {
2502e5b6d6dSopenharmony_ci    UnicodeString upattern(pattern, -1, US_INV);
2512e5b6d6dSopenharmony_ci    UnicodeString uexpected(expected, -1, US_INV);
2522e5b6d6dSopenharmony_ci    upattern = upattern.unescape();
2532e5b6d6dSopenharmony_ci    uexpected = uexpected.unescape();
2542e5b6d6dSopenharmony_ci    UErrorCode status = U_ZERO_ERROR;
2552e5b6d6dSopenharmony_ci    UnicodeString result;
2562e5b6d6dSopenharmony_ci    DecimalFormat fmt(
2572e5b6d6dSopenharmony_ci            upattern, new DecimalFormatSymbols("fr_FR", status), status);
2582e5b6d6dSopenharmony_ci    if (U_FAILURE(status)) {
2592e5b6d6dSopenharmony_ci        dataerrln("Error creating DecimalFormatSymbols - %s", u_errorName(status));
2602e5b6d6dSopenharmony_ci        return;
2612e5b6d6dSopenharmony_ci    }
2622e5b6d6dSopenharmony_ci    fmt.format(x, result);
2632e5b6d6dSopenharmony_ci    fixNonBreakingSpace(result);
2642e5b6d6dSopenharmony_ci    assertSuccess("", status);
2652e5b6d6dSopenharmony_ci    assertEquals("", uexpected, result, possibleDataError);
2662e5b6d6dSopenharmony_ci}
2672e5b6d6dSopenharmony_ci
2682e5b6d6dSopenharmony_ciextern IntlTest *createNumberFormatSpecificationTest() {
2692e5b6d6dSopenharmony_ci    return new NumberFormatSpecificationTest();
2702e5b6d6dSopenharmony_ci}
2712e5b6d6dSopenharmony_ci
2722e5b6d6dSopenharmony_ci#endif
273