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_microprops.h"
10 #include "number_patternmodifier.h"
11
runIndexedTest(int32_t index,UBool exec,const char * & name,char *)12 void PatternModifierTest::runIndexedTest(int32_t index, UBool exec, const char *&name, char *) {
13 if (exec) {
14 logln("TestSuite PatternModifierTest: ");
15 }
16 TESTCASE_AUTO_BEGIN;
17 TESTCASE_AUTO(testBasic);
18 TESTCASE_AUTO(testPatternWithNoPlaceholder);
19 TESTCASE_AUTO(testMutableEqualsImmutable);
20 TESTCASE_AUTO_END;
21 }
22
testBasic()23 void PatternModifierTest::testBasic() {
24 UErrorCode status = U_ZERO_ERROR;
25 MutablePatternModifier mod(false);
26 ParsedPatternInfo patternInfo;
27 PatternParser::parseToPatternInfo(u"a0b", patternInfo, status);
28 assertSuccess("Spot 1", status);
29 mod.setPatternInfo(&patternInfo, kUndefinedField);
30 mod.setPatternAttributes(UNUM_SIGN_AUTO, false);
31 DecimalFormatSymbols symbols(Locale::getEnglish(), status);
32 mod.setSymbols(&symbols, {u"USD", status}, UNUM_UNIT_WIDTH_SHORT, nullptr, status);
33 if (!assertSuccess("Spot 2", status, true)) {
34 return;
35 }
36
37 mod.setNumberProperties(SIGNUM_POS, StandardPlural::Form::COUNT);
38 assertEquals("Pattern a0b", u"a", getPrefix(mod, status));
39 assertEquals("Pattern a0b", u"b", getSuffix(mod, status));
40 mod.setPatternAttributes(UNUM_SIGN_ALWAYS, false);
41 assertEquals("Pattern a0b", u"+a", getPrefix(mod, status));
42 assertEquals("Pattern a0b", u"b", getSuffix(mod, status));
43 mod.setNumberProperties(SIGNUM_NEG_ZERO, StandardPlural::Form::COUNT);
44 assertEquals("Pattern a0b", u"-a", getPrefix(mod, status));
45 assertEquals("Pattern a0b", u"b", getSuffix(mod, status));
46 mod.setNumberProperties(SIGNUM_POS_ZERO, StandardPlural::Form::COUNT);
47 assertEquals("Pattern a0b", u"+a", getPrefix(mod, status));
48 assertEquals("Pattern a0b", u"b", getSuffix(mod, status));
49 mod.setPatternAttributes(UNUM_SIGN_EXCEPT_ZERO, false);
50 assertEquals("Pattern a0b", u"a", getPrefix(mod, status));
51 assertEquals("Pattern a0b", u"b", getSuffix(mod, status));
52 mod.setNumberProperties(SIGNUM_NEG, StandardPlural::Form::COUNT);
53 assertEquals("Pattern a0b", u"-a", getPrefix(mod, status));
54 assertEquals("Pattern a0b", u"b", getSuffix(mod, status));
55 mod.setPatternAttributes(UNUM_SIGN_NEVER, false);
56 assertEquals("Pattern a0b", u"a", getPrefix(mod, status));
57 assertEquals("Pattern a0b", u"b", getSuffix(mod, status));
58 assertSuccess("Spot 3", status);
59
60 ParsedPatternInfo patternInfo2;
61 PatternParser::parseToPatternInfo(u"a0b;c-0d", patternInfo2, status);
62 assertSuccess("Spot 4", status);
63 mod.setPatternInfo(&patternInfo2, kUndefinedField);
64 mod.setPatternAttributes(UNUM_SIGN_AUTO, false);
65 mod.setNumberProperties(SIGNUM_POS, StandardPlural::Form::COUNT);
66 assertEquals("Pattern a0b;c-0d", u"a", getPrefix(mod, status));
67 assertEquals("Pattern a0b;c-0d", u"b", getSuffix(mod, status));
68 mod.setPatternAttributes(UNUM_SIGN_ALWAYS, false);
69 assertEquals("Pattern a0b;c-0d", u"c+", getPrefix(mod, status));
70 assertEquals("Pattern a0b;c-0d", u"d", getSuffix(mod, status));
71 mod.setNumberProperties(SIGNUM_NEG_ZERO, StandardPlural::Form::COUNT);
72 assertEquals("Pattern a0b;c-0d", u"c-", getPrefix(mod, status));
73 assertEquals("Pattern a0b;c-0d", u"d", getSuffix(mod, status));
74 mod.setNumberProperties(SIGNUM_POS_ZERO, StandardPlural::Form::COUNT);
75 assertEquals("Pattern a0b;c-0d", u"c+", getPrefix(mod, status));
76 assertEquals("Pattern a0b;c-0d", u"d", getSuffix(mod, status));
77 mod.setPatternAttributes(UNUM_SIGN_EXCEPT_ZERO, false);
78 assertEquals("Pattern a0b;c-0d", u"a", getPrefix(mod, status));
79 assertEquals("Pattern a0b;c-0d", u"b", getSuffix(mod, status));
80 mod.setNumberProperties(SIGNUM_NEG, StandardPlural::Form::COUNT);
81 assertEquals("Pattern a0b;c-0d", u"c-", getPrefix(mod, status));
82 assertEquals("Pattern a0b;c-0d", u"d", getSuffix(mod, status));
83 mod.setPatternAttributes(UNUM_SIGN_NEVER, false);
84 assertEquals("Pattern a0b;c-0d", u"a", getPrefix(mod, status));
85 assertEquals("Pattern a0b;c-0d", u"b", getSuffix(mod, status));
86 assertSuccess("Spot 5", status);
87 }
88
testPatternWithNoPlaceholder()89 void PatternModifierTest::testPatternWithNoPlaceholder() {
90 UErrorCode status = U_ZERO_ERROR;
91 MutablePatternModifier mod(false);
92 ParsedPatternInfo patternInfo;
93 PatternParser::parseToPatternInfo(u"abc", patternInfo, status);
94 assertSuccess("Spot 1", status);
95 mod.setPatternInfo(&patternInfo, kUndefinedField);
96 mod.setPatternAttributes(UNUM_SIGN_AUTO, false);
97 DecimalFormatSymbols symbols(Locale::getEnglish(), status);
98 mod.setSymbols(&symbols, {u"USD", status}, UNUM_UNIT_WIDTH_SHORT, nullptr, status);
99 if (!assertSuccess("Spot 2", status, true)) {
100 return;
101 }
102 mod.setNumberProperties(SIGNUM_POS, StandardPlural::Form::COUNT);
103
104 // Unsafe Code Path
105 FormattedStringBuilder nsb;
106 nsb.append(u"x123y", kUndefinedField, status);
107 assertSuccess("Spot 3", status);
108 mod.apply(nsb, 1, 4, status);
109 assertSuccess("Spot 4", status);
110 assertEquals("Unsafe Path", u"xabcy", nsb.toUnicodeString());
111
112 // Safe Code Path
113 nsb.clear();
114 nsb.append(u"x123y", kUndefinedField, status);
115 assertSuccess("Spot 5", status);
116 MicroProps micros;
117 LocalPointer<ImmutablePatternModifier> imod(mod.createImmutable(status), status);
118 if (U_FAILURE(status)) {
119 dataerrln("%s %d Error in ImmutablePatternModifier creation",
120 __FILE__, __LINE__);
121 assertSuccess("Spot 6", status);
122 return;
123 }
124 DecimalQuantity quantity;
125 imod->applyToMicros(micros, quantity, status);
126 micros.modMiddle->apply(nsb, 1, 4, status);
127 assertSuccess("Spot 7", status);
128 assertEquals("Safe Path", u"xabcy", nsb.toUnicodeString());
129 }
130
testMutableEqualsImmutable()131 void PatternModifierTest::testMutableEqualsImmutable() {
132 UErrorCode status = U_ZERO_ERROR;
133 MutablePatternModifier mod(false);
134 ParsedPatternInfo patternInfo;
135 PatternParser::parseToPatternInfo("a0b;c-0d", patternInfo, status);
136 assertSuccess("Spot 1", status);
137 mod.setPatternInfo(&patternInfo, kUndefinedField);
138 mod.setPatternAttributes(UNUM_SIGN_AUTO, false);
139 DecimalFormatSymbols symbols(Locale::getEnglish(), status);
140 mod.setSymbols(&symbols, {u"USD", status}, UNUM_UNIT_WIDTH_SHORT, nullptr, status);
141 assertSuccess("Spot 2", status);
142 if (U_FAILURE(status)) { return; }
143 DecimalQuantity fq;
144 fq.setToInt(1);
145
146 FormattedStringBuilder nsb1;
147 MicroProps micros1;
148 mod.addToChain(µs1);
149 mod.processQuantity(fq, micros1, status);
150 micros1.modMiddle->apply(nsb1, 0, 0, status);
151 assertSuccess("Spot 3", status);
152
153 FormattedStringBuilder nsb2;
154 MicroProps micros2;
155 LocalPointer<ImmutablePatternModifier> immutable(mod.createImmutable(status));
156 immutable->applyToMicros(micros2, fq, status);
157 micros2.modMiddle->apply(nsb2, 0, 0, status);
158 assertSuccess("Spot 4", status);
159
160 FormattedStringBuilder nsb3;
161 MicroProps micros3;
162 mod.addToChain(µs3);
163 mod.setPatternAttributes(UNUM_SIGN_ALWAYS, false);
164 mod.processQuantity(fq, micros3, status);
165 micros3.modMiddle->apply(nsb3, 0, 0, status);
166 assertSuccess("Spot 5", status);
167
168 assertTrue(nsb1.toUnicodeString() + " vs " + nsb2.toUnicodeString(), nsb1.contentEquals(nsb2));
169 assertFalse(nsb1.toUnicodeString() + " vs " + nsb3.toUnicodeString(), nsb1.contentEquals(nsb3));
170 }
171
getPrefix(const MutablePatternModifier & mod,UErrorCode & status)172 UnicodeString PatternModifierTest::getPrefix(const MutablePatternModifier &mod, UErrorCode &status) {
173 FormattedStringBuilder nsb;
174 mod.apply(nsb, 0, 0, status);
175 int32_t prefixLength = mod.getPrefixLength();
176 return UnicodeString(nsb.toUnicodeString(), 0, prefixLength);
177 }
178
getSuffix(const MutablePatternModifier & mod,UErrorCode & status)179 UnicodeString PatternModifierTest::getSuffix(const MutablePatternModifier &mod, UErrorCode &status) {
180 FormattedStringBuilder nsb;
181 mod.apply(nsb, 0, 0, status);
182 int32_t prefixLength = mod.getPrefixLength();
183 return UnicodeString(nsb.toUnicodeString(), prefixLength, nsb.length() - prefixLength);
184 }
185
186 #endif /* #if !UCONFIG_NO_FORMATTING */
187