• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, 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, 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, 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, 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     mod.setPatternAttributes(UNUM_SIGN_AUTO, false, true);
61     mod.setNumberProperties(SIGNUM_POS, StandardPlural::Form::COUNT);
62     assertEquals("Pattern a0b", u"~a", getPrefix(mod, status));
63     assertEquals("Pattern a0b", u"b", getSuffix(mod, status));
64     mod.setNumberProperties(SIGNUM_NEG, StandardPlural::Form::COUNT);
65     assertEquals("Pattern a0b", u"~-a", getPrefix(mod, status));
66     assertEquals("Pattern a0b", u"b", getSuffix(mod, status));
67     mod.setPatternAttributes(UNUM_SIGN_ALWAYS, false, true);
68     mod.setNumberProperties(SIGNUM_POS, StandardPlural::Form::COUNT);
69     assertEquals("Pattern a0b", u"~+a", getPrefix(mod, status));
70     assertEquals("Pattern a0b", u"b", getSuffix(mod, status));
71     assertSuccess("Spot 3.5", status);
72 
73     ParsedPatternInfo patternInfo2;
74     PatternParser::parseToPatternInfo(u"a0b;c-0d", patternInfo2, status);
75     assertSuccess("Spot 4", status);
76     mod.setPatternInfo(&patternInfo2, kUndefinedField);
77     mod.setPatternAttributes(UNUM_SIGN_AUTO, false, false);
78     mod.setNumberProperties(SIGNUM_POS, StandardPlural::Form::COUNT);
79     assertEquals("Pattern a0b;c-0d", u"a", getPrefix(mod, status));
80     assertEquals("Pattern a0b;c-0d", u"b", getSuffix(mod, status));
81     mod.setPatternAttributes(UNUM_SIGN_ALWAYS, false, false);
82     assertEquals("Pattern a0b;c-0d", u"c+", getPrefix(mod, status));
83     assertEquals("Pattern a0b;c-0d", u"d", getSuffix(mod, status));
84     mod.setNumberProperties(SIGNUM_NEG_ZERO, StandardPlural::Form::COUNT);
85     assertEquals("Pattern a0b;c-0d", u"c-", getPrefix(mod, status));
86     assertEquals("Pattern a0b;c-0d", u"d", getSuffix(mod, status));
87     mod.setNumberProperties(SIGNUM_POS_ZERO, StandardPlural::Form::COUNT);
88     assertEquals("Pattern a0b;c-0d", u"c+", getPrefix(mod, status));
89     assertEquals("Pattern a0b;c-0d", u"d", getSuffix(mod, status));
90     mod.setPatternAttributes(UNUM_SIGN_EXCEPT_ZERO, false, false);
91     assertEquals("Pattern a0b;c-0d", u"a", getPrefix(mod, status));
92     assertEquals("Pattern a0b;c-0d", u"b", getSuffix(mod, status));
93     mod.setNumberProperties(SIGNUM_NEG, StandardPlural::Form::COUNT);
94     assertEquals("Pattern a0b;c-0d", u"c-", getPrefix(mod, status));
95     assertEquals("Pattern a0b;c-0d", u"d", getSuffix(mod, status));
96     mod.setPatternAttributes(UNUM_SIGN_NEVER, false, false);
97     assertEquals("Pattern a0b;c-0d", u"a", getPrefix(mod, status));
98     assertEquals("Pattern a0b;c-0d", u"b", getSuffix(mod, status));
99     assertSuccess("Spot 5", status);
100 
101     mod.setPatternAttributes(UNUM_SIGN_AUTO, false, true);
102     mod.setNumberProperties(SIGNUM_POS, StandardPlural::Form::COUNT);
103     assertEquals("Pattern a0b;c-0d", u"c~", getPrefix(mod, status));
104     assertEquals("Pattern a0b;c-0d", u"d", getSuffix(mod, status));
105     mod.setNumberProperties(SIGNUM_NEG, StandardPlural::Form::COUNT);
106     assertEquals("Pattern a0b;c-0d", u"c~-", getPrefix(mod, status));
107     assertEquals("Pattern a0b;c-0d", u"d", getSuffix(mod, status));
108     mod.setPatternAttributes(UNUM_SIGN_ALWAYS, false, true);
109     mod.setNumberProperties(SIGNUM_POS, StandardPlural::Form::COUNT);
110     assertEquals("Pattern a0b;c-0d", u"c~+", getPrefix(mod, status));
111     assertEquals("Pattern a0b;c-0d", u"d", getSuffix(mod, status));
112     assertSuccess("Spot 5.5", status);
113 }
114 
testPatternWithNoPlaceholder()115 void PatternModifierTest::testPatternWithNoPlaceholder() {
116     UErrorCode status = U_ZERO_ERROR;
117     MutablePatternModifier mod(false);
118     ParsedPatternInfo patternInfo;
119     PatternParser::parseToPatternInfo(u"abc", patternInfo, status);
120     assertSuccess("Spot 1", status);
121     mod.setPatternInfo(&patternInfo, kUndefinedField);
122     mod.setPatternAttributes(UNUM_SIGN_AUTO, false, false);
123     DecimalFormatSymbols symbols(Locale::getEnglish(), status);
124     mod.setSymbols(&symbols, {u"USD", status}, UNUM_UNIT_WIDTH_SHORT, nullptr, status);
125     if (!assertSuccess("Spot 2", status, true)) {
126         return;
127     }
128     mod.setNumberProperties(SIGNUM_POS, StandardPlural::Form::COUNT);
129 
130     // Unsafe Code Path
131     FormattedStringBuilder nsb;
132     nsb.append(u"x123y", kUndefinedField, status);
133     assertSuccess("Spot 3", status);
134     mod.apply(nsb, 1, 4, status);
135     assertSuccess("Spot 4", status);
136     assertEquals("Unsafe Path", u"xabcy", nsb.toUnicodeString());
137 
138     // Safe Code Path
139     nsb.clear();
140     nsb.append(u"x123y", kUndefinedField, status);
141     assertSuccess("Spot 5", status);
142     MicroProps micros;
143     LocalPointer<ImmutablePatternModifier> imod(mod.createImmutable(status), status);
144     if (U_FAILURE(status)) {
145       dataerrln("%s %d  Error in ImmutablePatternModifier creation",
146                 __FILE__, __LINE__);
147       assertSuccess("Spot 6", status);
148       return;
149     }
150     DecimalQuantity quantity;
151     imod->applyToMicros(micros, quantity, status);
152     micros.modMiddle->apply(nsb, 1, 4, status);
153     assertSuccess("Spot 7", status);
154     assertEquals("Safe Path", u"xabcy", nsb.toUnicodeString());
155 }
156 
testMutableEqualsImmutable()157 void PatternModifierTest::testMutableEqualsImmutable() {
158     UErrorCode status = U_ZERO_ERROR;
159     MutablePatternModifier mod(false);
160     ParsedPatternInfo patternInfo;
161     PatternParser::parseToPatternInfo("a0b;c-0d", patternInfo, status);
162     assertSuccess("Spot 1", status);
163     mod.setPatternInfo(&patternInfo, kUndefinedField);
164     mod.setPatternAttributes(UNUM_SIGN_AUTO, false, false);
165     DecimalFormatSymbols symbols(Locale::getEnglish(), status);
166     mod.setSymbols(&symbols, {u"USD", status}, UNUM_UNIT_WIDTH_SHORT, nullptr, status);
167     assertSuccess("Spot 2", status);
168     if (U_FAILURE(status)) { return; }
169     DecimalQuantity fq;
170     fq.setToInt(1);
171 
172     FormattedStringBuilder nsb1;
173     MicroProps micros1;
174     mod.addToChain(&micros1);
175     mod.processQuantity(fq, micros1, status);
176     micros1.modMiddle->apply(nsb1, 0, 0, status);
177     assertSuccess("Spot 3", status);
178 
179     FormattedStringBuilder nsb2;
180     MicroProps micros2;
181     LocalPointer<ImmutablePatternModifier> immutable(mod.createImmutable(status));
182     immutable->applyToMicros(micros2, fq, status);
183     micros2.modMiddle->apply(nsb2, 0, 0, status);
184     assertSuccess("Spot 4", status);
185 
186     FormattedStringBuilder nsb3;
187     MicroProps micros3;
188     mod.addToChain(&micros3);
189     mod.setPatternAttributes(UNUM_SIGN_ALWAYS, false, false);
190     mod.processQuantity(fq, micros3, status);
191     micros3.modMiddle->apply(nsb3, 0, 0, status);
192     assertSuccess("Spot 5", status);
193 
194     assertTrue(nsb1.toUnicodeString() + " vs " + nsb2.toUnicodeString(), nsb1.contentEquals(nsb2));
195     assertFalse(nsb1.toUnicodeString() + " vs " + nsb3.toUnicodeString(), nsb1.contentEquals(nsb3));
196 }
197 
getPrefix(const MutablePatternModifier & mod,UErrorCode & status)198 UnicodeString PatternModifierTest::getPrefix(const MutablePatternModifier &mod, UErrorCode &status) {
199     FormattedStringBuilder nsb;
200     mod.apply(nsb, 0, 0, status);
201     int32_t prefixLength = mod.getPrefixLength();
202     return UnicodeString(nsb.toUnicodeString(), 0, prefixLength);
203 }
204 
getSuffix(const MutablePatternModifier & mod,UErrorCode & status)205 UnicodeString PatternModifierTest::getSuffix(const MutablePatternModifier &mod, UErrorCode &status) {
206     FormattedStringBuilder nsb;
207     mod.apply(nsb, 0, 0, status);
208     int32_t prefixLength = mod.getPrefixLength();
209     return UnicodeString(nsb.toUnicodeString(), prefixLength, nsb.length() - prefixLength);
210 }
211 
212 #endif /* #if !UCONFIG_NO_FORMATTING */
213