File: numbertest_patternstring.cpp

package info (click to toggle)
icu 78.2-1
  • links: PTS
  • area: main
  • in suites: experimental
  • size: 123,992 kB
  • sloc: cpp: 527,891; ansic: 112,789; sh: 4,983; makefile: 4,657; perl: 3,199; python: 2,933; xml: 749; sed: 36; lisp: 12
file content (151 lines) | stat: -rw-r--r-- 5,865 bytes parent folder | download | duplicates (9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
// © 2017 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html

#include "unicode/utypes.h"

#if !UCONFIG_NO_FORMATTING

#include "numbertest.h"
#include "number_patternstring.h"

void PatternStringTest::runIndexedTest(int32_t index, UBool exec, const char*& name, char*) {
    if (exec) {
        logln("TestSuite PatternStringTest: ");
    }
    TESTCASE_AUTO_BEGIN;
        TESTCASE_AUTO(testLocalized);
        TESTCASE_AUTO(testToPatternSimple);
        TESTCASE_AUTO(testExceptionOnInvalid);
        TESTCASE_AUTO(testBug13117);
        TESTCASE_AUTO(testCurrencyDecimal);
    TESTCASE_AUTO_END;
}

void PatternStringTest::testLocalized() {
    IcuTestErrorCode status(*this, "testLocalized");
    DecimalFormatSymbols symbols(Locale::getEnglish(), status);
    if (status.isFailure()) { return; }
    symbols.setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol, u"a", status);
    symbols.setSymbol(DecimalFormatSymbols::kPercentSymbol, u"b", status);
    symbols.setSymbol(DecimalFormatSymbols::kMinusSignSymbol, u".", status);
    symbols.setSymbol(DecimalFormatSymbols::kPlusSignSymbol, u"'", status);

    UnicodeString standard = u"+-abcb''a''#,##0.0%'a%'";
    UnicodeString localized = u"’.'ab'c'b''a'''#,##0a0b'a%'";
    UnicodeString toStandard = u"+-'ab'c'b''a'''#,##0.0%'a%'";

    assertEquals(
            "standard to localized",
            localized,
            PatternStringUtils::convertLocalized(standard, symbols, true, status));
    assertEquals(
            "localized to standard",
            toStandard,
            PatternStringUtils::convertLocalized(localized, symbols, false, status));
}

void PatternStringTest::testToPatternSimple() {
    const char16_t* cases[][2] = {{u"#", u"0"},
                                  {u"0", u"0"},
                                  {u"#0", u"0"},
                                  {u"###", u"0"},
                                  {u"0.##", u"0.##"},
                                  {u"0.00", u"0.00"},
                                  {u"0.00#", u"0.00#"},
                                  {u"0.05", u"0.05"},
                                  {u"#E0", u"#E0"},
                                  {u"0E0", u"0E0"},
                                  {u"#00E00", u"#00E00"},
                                  {u"#,##0", u"#,##0"},
                                  {u"0¤", u"0¤"},
                                  {u"0¤a", u"0¤a"},
                                  {u"0¤00", u"0¤00"},
                                  {u"#;#", u"0;0"},
            // ignore a negative prefix pattern of '-' since that is the default:
                                  {u"#;-#", u"0"},
                                  {u"pp#,000;(#)", u"pp#,000;(#,000)"},
                                  {u"**##0", u"**##0"},
                                  {u"*'x'##0", u"*x##0"},
                                  {u"a''b0", u"a''b0"},
                                  {u"*''##0", u"*''##0"},
                                  {u"*📺##0", u"*'📺'##0"},
                                  {u"*'நி'##0", u"*'நி'##0"},};

    UErrorCode status = U_ZERO_ERROR;
    for (const char16_t** cas : cases) {
        UnicodeString input(cas[0]);
        UnicodeString output(cas[1]);

        DecimalFormatProperties properties = PatternParser::parseToProperties(
                input, IGNORE_ROUNDING_NEVER, status);
        assertSuccess(input, status);
        UnicodeString actual = PatternStringUtils::propertiesToPatternString(properties, status);
        assertEquals(input, output, actual);
        status = U_ZERO_ERROR;
    }
}

void PatternStringTest::testExceptionOnInvalid() {
    static const char16_t* invalidPatterns[] = {
            u"#.#.#",
            u"0#",
            u"0#.",
            u".#0",
            u"0#.#0",
            u"@0",
            u"0@",
            u"0,",
            u"0,,",
            u"0,,0",
            u"0,,0,",
            u"#,##0E0"};

    for (const auto* pattern : invalidPatterns) {
        UErrorCode status = U_ZERO_ERROR;
        ParsedPatternInfo patternInfo;
        PatternParser::parseToPatternInfo(pattern, patternInfo, status);
        assertTrue(pattern, U_FAILURE(status));
    }
}

void PatternStringTest::testBug13117() {
    UErrorCode status = U_ZERO_ERROR;
    DecimalFormatProperties expected = PatternParser::parseToProperties(
            u"0", IGNORE_ROUNDING_NEVER, status);
    DecimalFormatProperties actual = PatternParser::parseToProperties(
            u"0;", IGNORE_ROUNDING_NEVER, status);
    assertSuccess("Spot 1", status);
    assertTrue("Should not consume negative subpattern", expected == actual);
}

void PatternStringTest::testCurrencyDecimal() {
    IcuTestErrorCode status(*this, "testCurrencyDecimal");

    // Manually create a NumberFormatter from a specific pattern
    ParsedPatternInfo patternInfo;
    PatternParser::parseToPatternInfo(u"a0¤00b", patternInfo, status);
    MacroProps macros;
    macros.unit = CurrencyUnit(u"EUR", status);
    macros.affixProvider = &patternInfo;
    LocalizedNumberFormatter nf = NumberFormatter::with().macros(macros).locale("und");

    // Test that the output is as expected
    FormattedNumber fn = nf.formatDouble(3.14, status);
    assertEquals("Should substitute currency symbol", u"a3€14b", fn.toTempString(status));

    // Test field positions
    static const UFieldPosition expectedFieldPositions[] = {
            {UNUM_INTEGER_FIELD, 1, 2},
            {UNUM_CURRENCY_FIELD, 2, 3},
            {UNUM_FRACTION_FIELD, 3, 5}};
    checkFormattedValue(
        u"Currency as decimal basic field positions",
        fn,
        u"a3€14b",
        UFIELD_CATEGORY_NUMBER,
        expectedFieldPositions,
        UPRV_LENGTHOF(expectedFieldPositions)
    );
}

#endif /* #if !UCONFIG_NO_FORMATTING */