]>
Commit | Line | Data |
---|---|---|
3d1f044b A |
1 | // © 2016 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 <set> | |
9 | ||
10 | #include "unicode/formattedvalue.h" | |
11 | #include "unicode/unum.h" | |
12 | #include "unicode/udat.h" | |
13 | #include "intltest.h" | |
14 | #include "itformat.h" | |
15 | ||
16 | ||
17 | class FormattedValueTest : public IntlTest { | |
18 | public: | |
19 | void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par=0); | |
20 | private: | |
21 | void testBasic(); | |
22 | void testSetters(); | |
23 | void testLocalPointer(); | |
24 | ||
25 | void assertAllPartsEqual( | |
26 | UnicodeString messagePrefix, | |
27 | const ConstrainedFieldPosition& cfpos, | |
28 | int32_t matching, | |
29 | UFieldCategory category, | |
30 | int32_t field, | |
31 | int32_t start, | |
32 | int32_t limit, | |
33 | int64_t context); | |
34 | }; | |
35 | ||
36 | void FormattedValueTest::runIndexedTest(int32_t index, UBool exec, const char *&name, char *) { | |
37 | if (exec) { | |
38 | logln("TestSuite FormattedValueTest: "); | |
39 | } | |
40 | TESTCASE_AUTO_BEGIN; | |
41 | TESTCASE_AUTO(testBasic); | |
42 | TESTCASE_AUTO(testSetters); | |
43 | TESTCASE_AUTO(testLocalPointer); | |
44 | TESTCASE_AUTO_END; | |
45 | } | |
46 | ||
47 | ||
48 | void FormattedValueTest::testBasic() { | |
49 | IcuTestErrorCode status(*this, "testBasic"); | |
50 | ConstrainedFieldPosition cfpos; | |
51 | assertAllPartsEqual( | |
52 | u"basic", | |
53 | cfpos, | |
54 | 7, | |
55 | UFIELD_CATEGORY_UNDEFINED, | |
56 | 0, | |
57 | 0, | |
58 | 0, | |
59 | 0LL); | |
60 | } | |
61 | ||
62 | void FormattedValueTest::testSetters() { | |
63 | IcuTestErrorCode status(*this, "testSetters"); | |
64 | ConstrainedFieldPosition cfpos; | |
65 | ||
66 | cfpos.constrainCategory(UFIELD_CATEGORY_DATE); | |
67 | assertAllPartsEqual( | |
68 | u"setters 0", | |
69 | cfpos, | |
70 | 4, | |
71 | UFIELD_CATEGORY_DATE, | |
72 | 0, | |
73 | 0, | |
74 | 0, | |
75 | 0LL); | |
76 | ||
77 | cfpos.constrainField(UFIELD_CATEGORY_NUMBER, UNUM_COMPACT_FIELD); | |
78 | assertAllPartsEqual( | |
79 | u"setters 1", | |
80 | cfpos, | |
81 | 2, | |
82 | UFIELD_CATEGORY_NUMBER, | |
83 | UNUM_COMPACT_FIELD, | |
84 | 0, | |
85 | 0, | |
86 | 0LL); | |
87 | ||
88 | cfpos.setInt64IterationContext(42424242424242LL); | |
89 | assertAllPartsEqual( | |
90 | u"setters 2", | |
91 | cfpos, | |
92 | 2, | |
93 | UFIELD_CATEGORY_NUMBER, | |
94 | UNUM_COMPACT_FIELD, | |
95 | 0, | |
96 | 0, | |
97 | 42424242424242LL); | |
98 | ||
99 | cfpos.setState(UFIELD_CATEGORY_NUMBER, UNUM_COMPACT_FIELD, 5, 10); | |
100 | assertAllPartsEqual( | |
101 | u"setters 3", | |
102 | cfpos, | |
103 | 2, | |
104 | UFIELD_CATEGORY_NUMBER, | |
105 | UNUM_COMPACT_FIELD, | |
106 | 5, | |
107 | 10, | |
108 | 42424242424242LL); | |
109 | ||
110 | cfpos.reset(); | |
111 | assertAllPartsEqual( | |
112 | u"setters 4", | |
113 | cfpos, | |
114 | 7, | |
115 | UFIELD_CATEGORY_UNDEFINED, | |
116 | 0, | |
117 | 0, | |
118 | 0, | |
119 | 0LL); | |
120 | } | |
121 | ||
122 | void FormattedValueTest::testLocalPointer() { | |
123 | UErrorCode status = U_ZERO_ERROR; | |
124 | LocalUConstrainedFieldPositionPointer ucfpos(ucfpos_open(&status)); | |
125 | assertSuccess("Openining LocalUConstrainedFieldPositionPointer", status); | |
126 | assertEquals(u"Test that object is valid", | |
127 | 0LL, | |
128 | ucfpos_getInt64IterationContext(ucfpos.getAlias(), &status)); | |
129 | assertSuccess("Using LocalUConstrainedFieldPositionPointer", status); | |
130 | } | |
131 | ||
132 | /** For matching, turn on these bits: | |
133 | * | |
134 | * 1 = UNUM_INTEGER_FIELD | |
135 | * 2 = UNUM_COMPACT_FIELD | |
136 | * 4 = UDAT_AM_PM_FIELD | |
137 | */ | |
138 | void FormattedValueTest::assertAllPartsEqual( | |
139 | UnicodeString messagePrefix, | |
140 | const ConstrainedFieldPosition& cfpos, | |
141 | int32_t matching, | |
142 | UFieldCategory category, | |
143 | int32_t field, | |
144 | int32_t start, | |
145 | int32_t limit, | |
146 | int64_t context) { | |
147 | assertEquals(messagePrefix + u": category", | |
148 | category, cfpos.getCategory()); | |
149 | assertEquals(messagePrefix + u": field", | |
150 | field, cfpos.getField()); | |
151 | assertEquals(messagePrefix + u": start", | |
152 | start, cfpos.getStart()); | |
153 | assertEquals(messagePrefix + u": limit", | |
154 | limit, cfpos.getLimit()); | |
155 | assertEquals(messagePrefix + u": context", | |
156 | context, cfpos.getInt64IterationContext()); | |
157 | ||
158 | assertEquals(messagePrefix + u": integer field", | |
159 | (UBool) ((matching & 1) != 0), cfpos.matchesField(UFIELD_CATEGORY_NUMBER, UNUM_INTEGER_FIELD)); | |
160 | assertEquals(messagePrefix + u": compact field", | |
161 | (UBool) ((matching & 2) != 0), cfpos.matchesField(UFIELD_CATEGORY_NUMBER, UNUM_COMPACT_FIELD)); | |
162 | assertEquals(messagePrefix + u": date field", | |
163 | (UBool) ((matching & 4) != 0), cfpos.matchesField(UFIELD_CATEGORY_DATE, UDAT_AM_PM_FIELD)); | |
164 | } | |
165 | ||
166 | ||
167 | void IntlTestWithFieldPosition::checkFormattedValue( | |
168 | const char16_t* message, | |
169 | const FormattedValue& fv, | |
170 | UnicodeString expectedString, | |
171 | UFieldCategory expectedCategory, | |
172 | const UFieldPosition* expectedFieldPositions, | |
173 | int32_t length) { | |
174 | LocalArray<UFieldPositionWithCategory> converted(new UFieldPositionWithCategory[length]); | |
175 | for (int32_t i=0; i<length; i++) { | |
176 | converted[i].category = expectedCategory; | |
177 | converted[i].field = expectedFieldPositions[i].field; | |
178 | converted[i].beginIndex = expectedFieldPositions[i].beginIndex; | |
179 | converted[i].endIndex = expectedFieldPositions[i].endIndex; | |
180 | } | |
181 | checkMixedFormattedValue(message, fv, expectedString, converted.getAlias(), length); | |
182 | } | |
183 | ||
184 | ||
185 | UnicodeString CFPosToUnicodeString(const ConstrainedFieldPosition& cfpos) { | |
186 | UnicodeString sb; | |
187 | sb.append(u"CFPos["); | |
188 | sb.append(Int64ToUnicodeString(cfpos.getStart())); | |
189 | sb.append(u'-'); | |
190 | sb.append(Int64ToUnicodeString(cfpos.getLimit())); | |
191 | sb.append(u' '); | |
192 | sb.append(Int64ToUnicodeString(cfpos.getCategory())); | |
193 | sb.append(u':'); | |
194 | sb.append(Int64ToUnicodeString(cfpos.getField())); | |
195 | sb.append(u']'); | |
196 | return sb; | |
197 | } | |
198 | ||
199 | ||
200 | void IntlTestWithFieldPosition::checkMixedFormattedValue( | |
201 | const char16_t* message, | |
202 | const FormattedValue& fv, | |
203 | UnicodeString expectedString, | |
204 | const UFieldPositionWithCategory* expectedFieldPositions, | |
205 | int32_t length) { | |
206 | IcuTestErrorCode status(*this, "checkMixedFormattedValue"); | |
207 | UnicodeString baseMessage = UnicodeString(message) + u": " + fv.toString(status) + u": "; | |
208 | ||
209 | // Check string values | |
210 | assertEquals(baseMessage + u"string", expectedString, fv.toString(status)); | |
211 | assertEquals(baseMessage + u"temp string", expectedString, fv.toTempString(status)); | |
212 | ||
213 | // The temp string is guaranteed to be NUL-terminated | |
214 | UnicodeString readOnlyAlias = fv.toTempString(status); | |
215 | if (!status.errIfFailureAndReset()) { | |
216 | assertEquals(baseMessage + u"NUL-terminated", | |
217 | 0, readOnlyAlias.getBuffer()[readOnlyAlias.length()]); | |
218 | } | |
219 | ||
220 | // Check nextPosition over all fields | |
221 | ConstrainedFieldPosition cfpos; | |
222 | for (int32_t i = 0; i < length; i++) { | |
223 | assertTrue(baseMessage + u"A has next position @ " + Int64ToUnicodeString(i), | |
224 | fv.nextPosition(cfpos, status)); | |
225 | int32_t expectedCategory = expectedFieldPositions[i].category; | |
226 | int32_t expectedField = expectedFieldPositions[i].field; | |
227 | int32_t expectedStart = expectedFieldPositions[i].beginIndex; | |
228 | int32_t expectedLimit = expectedFieldPositions[i].endIndex; | |
229 | assertEquals(baseMessage + u"A category @ " + Int64ToUnicodeString(i), | |
230 | expectedCategory, cfpos.getCategory()); | |
231 | assertEquals(baseMessage + u"A field @ " + Int64ToUnicodeString(i), | |
232 | expectedField, cfpos.getField()); | |
233 | assertEquals(baseMessage + u"A start @ " + Int64ToUnicodeString(i), | |
234 | expectedStart, cfpos.getStart()); | |
235 | assertEquals(baseMessage + u"A limit @ " + Int64ToUnicodeString(i), | |
236 | expectedLimit, cfpos.getLimit()); | |
237 | } | |
238 | UBool afterLoopResult = fv.nextPosition(cfpos, status); | |
239 | assertFalse(baseMessage + u"A after loop: " + CFPosToUnicodeString(cfpos), afterLoopResult); | |
240 | ||
241 | // Check nextPosition constrained over each category one at a time | |
242 | for (int32_t category=0; category<UFIELD_CATEGORY_COUNT; category++) { | |
243 | cfpos.reset(); | |
244 | cfpos.constrainCategory(static_cast<UFieldCategory>(category)); | |
245 | for (int32_t i = 0; i < length; i++) { | |
246 | if (expectedFieldPositions[i].category != category) { | |
247 | continue; | |
248 | } | |
249 | assertTrue(baseMessage + u"B has next position @ " + Int64ToUnicodeString(i), | |
250 | fv.nextPosition(cfpos, status)); | |
251 | int32_t expectedCategory = expectedFieldPositions[i].category; | |
252 | int32_t expectedField = expectedFieldPositions[i].field; | |
253 | int32_t expectedStart = expectedFieldPositions[i].beginIndex; | |
254 | int32_t expectedLimit = expectedFieldPositions[i].endIndex; | |
255 | assertEquals(baseMessage + u"B category @ " + Int64ToUnicodeString(i), | |
256 | expectedCategory, cfpos.getCategory()); | |
257 | assertEquals(baseMessage + u"B field @ " + Int64ToUnicodeString(i), | |
258 | expectedField, cfpos.getField()); | |
259 | assertEquals(baseMessage + u"B start @ " + Int64ToUnicodeString(i), | |
260 | expectedStart, cfpos.getStart()); | |
261 | assertEquals(baseMessage + u"B limit @ " + Int64ToUnicodeString(i), | |
262 | expectedLimit, cfpos.getLimit()); | |
263 | } | |
264 | UBool afterLoopResult = fv.nextPosition(cfpos, status); | |
265 | assertFalse(baseMessage + u"B after loop @ " + CFPosToUnicodeString(cfpos), afterLoopResult); | |
266 | } | |
267 | ||
268 | // Check nextPosition constrained over each field one at a time | |
269 | std::set<std::pair<UFieldCategory, int32_t>> uniqueFields; | |
270 | for (int32_t i = 0; i < length; i++) { | |
271 | uniqueFields.insert({expectedFieldPositions[i].category, expectedFieldPositions[i].field}); | |
272 | } | |
273 | for (std::pair<UFieldCategory, int32_t> categoryAndField : uniqueFields) { | |
274 | cfpos.reset(); | |
275 | cfpos.constrainField(categoryAndField.first, categoryAndField.second); | |
276 | for (int32_t i = 0; i < length; i++) { | |
277 | if (expectedFieldPositions[i].category != categoryAndField.first) { | |
278 | continue; | |
279 | } | |
280 | if (expectedFieldPositions[i].field != categoryAndField.second) { | |
281 | continue; | |
282 | } | |
283 | assertTrue(baseMessage + u"C has next position @ " + Int64ToUnicodeString(i), | |
284 | fv.nextPosition(cfpos, status)); | |
285 | int32_t expectedCategory = expectedFieldPositions[i].category; | |
286 | int32_t expectedField = expectedFieldPositions[i].field; | |
287 | int32_t expectedStart = expectedFieldPositions[i].beginIndex; | |
288 | int32_t expectedLimit = expectedFieldPositions[i].endIndex; | |
289 | assertEquals(baseMessage + u"C category @ " + Int64ToUnicodeString(i), | |
290 | expectedCategory, cfpos.getCategory()); | |
291 | assertEquals(baseMessage + u"C field @ " + Int64ToUnicodeString(i), | |
292 | expectedField, cfpos.getField()); | |
293 | assertEquals(baseMessage + u"C start @ " + Int64ToUnicodeString(i), | |
294 | expectedStart, cfpos.getStart()); | |
295 | assertEquals(baseMessage + u"C limit @ " + Int64ToUnicodeString(i), | |
296 | expectedLimit, cfpos.getLimit()); | |
297 | } | |
298 | UBool afterLoopResult = fv.nextPosition(cfpos, status); | |
299 | assertFalse(baseMessage + u"C after loop: " + CFPosToUnicodeString(cfpos), afterLoopResult); | |
300 | } | |
301 | } | |
302 | ||
303 | ||
304 | extern IntlTest *createFormattedValueTest() { | |
305 | return new FormattedValueTest(); | |
306 | } | |
307 | ||
308 | #endif /* !UCONFIG_NO_FORMATTING */ |