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
7
8 #include "numbertest.h"
9 #include "number_patternstring.h"
10
runIndexedTest(int32_t index,UBool exec,const char * & name,char *)11 void PatternStringTest::runIndexedTest(int32_t index, UBool exec, const char*& name, char*) {
12 if (exec) {
13 logln("TestSuite PatternStringTest: ");
14 }
15 TESTCASE_AUTO_BEGIN;
16 TESTCASE_AUTO(testLocalized);
17 TESTCASE_AUTO(testToPatternSimple);
18 TESTCASE_AUTO(testExceptionOnInvalid);
19 TESTCASE_AUTO(testBug13117);
20 TESTCASE_AUTO_END;
21 }
22
testLocalized()23 void PatternStringTest::testLocalized() {
24 IcuTestErrorCode status(*this, "testLocalized");
25 DecimalFormatSymbols symbols(Locale::getEnglish(), status);
26 if (status.isFailure()) { return; }
27 symbols.setSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol, u"a", status);
28 symbols.setSymbol(DecimalFormatSymbols::kPercentSymbol, u"b", status);
29 symbols.setSymbol(DecimalFormatSymbols::kMinusSignSymbol, u".", status);
30 symbols.setSymbol(DecimalFormatSymbols::kPlusSignSymbol, u"'", status);
31
32 UnicodeString standard = u"+-abcb''a''#,##0.0%'a%'";
33 UnicodeString localized = u"’.'ab'c'b''a'''#,##0a0b'a%'";
34 UnicodeString toStandard = u"+-'ab'c'b''a'''#,##0.0%'a%'";
35
36 assertEquals(
37 "standard to localized",
38 localized,
39 PatternStringUtils::convertLocalized(standard, symbols, true, status));
40 assertEquals(
41 "localized to standard",
42 toStandard,
43 PatternStringUtils::convertLocalized(localized, symbols, false, status));
44 }
45
testToPatternSimple()46 void PatternStringTest::testToPatternSimple() {
47 const char16_t* cases[][2] = {{u"#", u"0"},
48 {u"0", u"0"},
49 {u"#0", u"0"},
50 {u"###", u"0"},
51 {u"0.##", u"0.##"},
52 {u"0.00", u"0.00"},
53 {u"0.00#", u"0.00#"},
54 {u"0.05", u"0.05"},
55 {u"#E0", u"#E0"},
56 {u"0E0", u"0E0"},
57 {u"#00E00", u"#00E00"},
58 {u"#,##0", u"#,##0"},
59 {u"#;#", u"0;0"},
60 // ignore a negative prefix pattern of '-' since that is the default:
61 {u"#;-#", u"0"},
62 {u"pp#,000;(#)", u"pp#,000;(#,000)"},
63 {u"**##0", u"**##0"},
64 {u"*'x'##0", u"*x##0"},
65 {u"a''b0", u"a''b0"},
66 {u"*''##0", u"*''##0"},
67 {u"*##0", u"*''##0"},
68 {u"*'நி'##0", u"*'நி'##0"},};
69
70 UErrorCode status = U_ZERO_ERROR;
71 for (const char16_t** cas : cases) {
72 UnicodeString input(cas[0]);
73 UnicodeString output(cas[1]);
74
75 DecimalFormatProperties properties = PatternParser::parseToProperties(
76 input, IGNORE_ROUNDING_NEVER, status);
77 assertSuccess(input, status);
78 UnicodeString actual = PatternStringUtils::propertiesToPatternString(properties, status);
79 assertEquals(input, output, actual);
80 }
81 }
82
testExceptionOnInvalid()83 void PatternStringTest::testExceptionOnInvalid() {
84 static const char16_t* invalidPatterns[] = {
85 u"#.#.#",
86 u"0#",
87 u"0#.",
88 u".#0",
89 u"0#.#0",
90 u"@0",
91 u"0@",
92 u"0,",
93 u"0,,",
94 u"0,,0",
95 u"0,,0,",
96 u"#,##0E0"};
97
98 for (auto pattern : invalidPatterns) {
99 UErrorCode status = U_ZERO_ERROR;
100 ParsedPatternInfo patternInfo;
101 PatternParser::parseToPatternInfo(pattern, patternInfo, status);
102 assertTrue(pattern, U_FAILURE(status));
103 }
104 }
105
testBug13117()106 void PatternStringTest::testBug13117() {
107 UErrorCode status = U_ZERO_ERROR;
108 DecimalFormatProperties expected = PatternParser::parseToProperties(
109 u"0", IGNORE_ROUNDING_NEVER, status);
110 DecimalFormatProperties actual = PatternParser::parseToProperties(
111 u"0;", IGNORE_ROUNDING_NEVER, status);
112 assertSuccess("Spot 1", status);
113 assertTrue("Should not consume negative subpattern", expected == actual);
114 }
115
116 #endif /* #if !UCONFIG_NO_FORMATTING */
117