]>
Commit | Line | Data |
---|---|---|
3d1f044b A |
1 | // © 2018 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 "unicode/uformattedvalue.h" | |
9 | #include "unicode/unum.h" | |
10 | #include "unicode/ustring.h" | |
11 | #include "cformtst.h" | |
12 | #include "cintltst.h" | |
13 | #include "cmemory.h" | |
14 | #include "cstring.h" | |
15 | #include "uassert.h" | |
16 | ||
17 | static void TestBasic(void); | |
18 | static void TestSetters(void); | |
19 | ||
20 | static void AssertAllPartsEqual( | |
21 | const char* messagePrefix, | |
22 | const UConstrainedFieldPosition* ucfpos, | |
23 | int32_t matching, | |
24 | UFieldCategory category, | |
25 | int32_t field, | |
26 | int32_t start, | |
27 | int32_t limit, | |
28 | int64_t context); | |
29 | ||
30 | void addUFormattedValueTest(TestNode** root); | |
31 | ||
32 | #define TESTCASE(x) addTest(root, &x, "tsformat/uformattedvalue/" #x) | |
33 | ||
34 | void addUFormattedValueTest(TestNode** root) { | |
35 | TESTCASE(TestBasic); | |
36 | TESTCASE(TestSetters); | |
37 | } | |
38 | ||
39 | ||
40 | static void TestBasic() { | |
41 | UErrorCode status = U_ZERO_ERROR; | |
42 | UConstrainedFieldPosition* ucfpos = ucfpos_open(&status); | |
43 | assertSuccess("opening ucfpos", &status); | |
44 | assertTrue("ucfpos should not be null", ucfpos != NULL); | |
45 | ||
46 | AssertAllPartsEqual( | |
47 | "basic", | |
48 | ucfpos, | |
49 | 7, | |
50 | UFIELD_CATEGORY_UNDEFINED, | |
51 | 0, | |
52 | 0, | |
53 | 0, | |
54 | 0LL); | |
55 | ||
56 | ucfpos_close(ucfpos); | |
57 | } | |
58 | ||
59 | void TestSetters() { | |
60 | UErrorCode status = U_ZERO_ERROR; | |
61 | UConstrainedFieldPosition* ucfpos = ucfpos_open(&status); | |
62 | assertSuccess("opening ucfpos", &status); | |
63 | assertTrue("ucfpos should not be null", ucfpos != NULL); | |
64 | ||
65 | ucfpos_constrainCategory(ucfpos, UFIELD_CATEGORY_DATE, &status); | |
66 | assertSuccess("setters 0", &status); | |
67 | AssertAllPartsEqual( | |
68 | "setters 0", | |
69 | ucfpos, | |
70 | 4, | |
71 | UFIELD_CATEGORY_DATE, | |
72 | 0, | |
73 | 0, | |
74 | 0, | |
75 | 0LL); | |
76 | ||
77 | ucfpos_constrainField(ucfpos, UFIELD_CATEGORY_NUMBER, UNUM_COMPACT_FIELD, &status); | |
78 | assertSuccess("setters 1", &status); | |
79 | AssertAllPartsEqual( | |
80 | "setters 1", | |
81 | ucfpos, | |
82 | 2, | |
83 | UFIELD_CATEGORY_NUMBER, | |
84 | UNUM_COMPACT_FIELD, | |
85 | 0, | |
86 | 0, | |
87 | 0LL); | |
88 | ||
89 | ucfpos_setInt64IterationContext(ucfpos, 42424242424242LL, &status); | |
90 | assertSuccess("setters 2", &status); | |
91 | AssertAllPartsEqual( | |
92 | "setters 2", | |
93 | ucfpos, | |
94 | 2, | |
95 | UFIELD_CATEGORY_NUMBER, | |
96 | UNUM_COMPACT_FIELD, | |
97 | 0, | |
98 | 0, | |
99 | 42424242424242LL); | |
100 | ||
101 | ucfpos_setState(ucfpos, UFIELD_CATEGORY_NUMBER, UNUM_COMPACT_FIELD, 5, 10, &status); | |
102 | assertSuccess("setters 3", &status); | |
103 | AssertAllPartsEqual( | |
104 | "setters 3", | |
105 | ucfpos, | |
106 | 2, | |
107 | UFIELD_CATEGORY_NUMBER, | |
108 | UNUM_COMPACT_FIELD, | |
109 | 5, | |
110 | 10, | |
111 | 42424242424242LL); | |
112 | ||
113 | ucfpos_reset(ucfpos, &status); | |
114 | assertSuccess("setters 4", &status); | |
115 | AssertAllPartsEqual( | |
116 | "setters 4", | |
117 | ucfpos, | |
118 | 7, | |
119 | UFIELD_CATEGORY_UNDEFINED, | |
120 | 0, | |
121 | 0, | |
122 | 0, | |
123 | 0LL); | |
124 | ||
125 | ucfpos_close(ucfpos); | |
126 | } | |
127 | ||
128 | /** For matching, turn on these bits: | |
129 | * | |
130 | * 1 = UNUM_INTEGER_FIELD | |
131 | * 2 = UNUM_COMPACT_FIELD | |
132 | * 4 = UDAT_AM_PM_FIELD | |
133 | */ | |
134 | static void AssertAllPartsEqual( | |
135 | const char* messagePrefix, | |
136 | const UConstrainedFieldPosition* ucfpos, | |
137 | int32_t matching, | |
138 | UFieldCategory category, | |
139 | int32_t field, | |
140 | int32_t start, | |
141 | int32_t limit, | |
142 | int64_t context) { | |
143 | ||
144 | UErrorCode status = U_ZERO_ERROR; | |
145 | ||
146 | char message[256]; | |
147 | uprv_strncpy(message, messagePrefix, 256); | |
148 | int32_t prefixEnd = (int32_t)uprv_strlen(messagePrefix); | |
149 | message[prefixEnd++] = ':'; | |
150 | message[prefixEnd++] = ' '; | |
151 | U_ASSERT(prefixEnd < 256); | |
152 | ||
153 | #define AAPE_MSG(suffix) (uprv_strncpy(message+prefixEnd, suffix, 256-prefixEnd)-prefixEnd) | |
154 | ||
155 | UFieldCategory _category = ucfpos_getCategory(ucfpos, &status); | |
156 | assertSuccess(AAPE_MSG("_"), &status); | |
157 | assertIntEquals(AAPE_MSG("category"), category, _category); | |
158 | ||
159 | int32_t _field = ucfpos_getField(ucfpos, &status); | |
160 | assertSuccess(AAPE_MSG("field"), &status); | |
161 | assertIntEquals(AAPE_MSG("field"), field, _field); | |
162 | ||
163 | int32_t _start, _limit; | |
164 | ucfpos_getIndexes(ucfpos, &_start, &_limit, &status); | |
165 | assertSuccess(AAPE_MSG("indexes"), &status); | |
166 | assertIntEquals(AAPE_MSG("start"), start, _start); | |
167 | assertIntEquals(AAPE_MSG("limit"), limit, _limit); | |
168 | ||
169 | int64_t _context = ucfpos_getInt64IterationContext(ucfpos, &status); | |
170 | assertSuccess(AAPE_MSG("context"), &status); | |
171 | assertIntEquals(AAPE_MSG("context"), context, _context); | |
172 | ||
173 | UBool _matchesInteger = ucfpos_matchesField(ucfpos, UFIELD_CATEGORY_NUMBER, UNUM_INTEGER_FIELD, &status); | |
174 | assertSuccess(AAPE_MSG("integer field"), &status); | |
175 | assertTrue(AAPE_MSG("integer field"), | |
176 | ((matching & 1) != 0) ? _matchesInteger : !_matchesInteger); | |
177 | ||
178 | UBool _matchesCompact = ucfpos_matchesField(ucfpos, UFIELD_CATEGORY_NUMBER, UNUM_COMPACT_FIELD, &status); | |
179 | assertSuccess(AAPE_MSG("compact field"), &status); | |
180 | assertTrue(AAPE_MSG("compact field"), | |
181 | ((matching & 2) != 0) ? _matchesCompact : !_matchesCompact); | |
182 | ||
183 | UBool _matchesDate = ucfpos_matchesField(ucfpos, UFIELD_CATEGORY_DATE, UDAT_AM_PM_FIELD, &status); | |
184 | assertSuccess(AAPE_MSG("date field"), &status); | |
185 | assertTrue(AAPE_MSG("date field"), | |
186 | ((matching & 4) != 0) ? _matchesDate : !_matchesDate); | |
187 | } | |
188 | ||
189 | ||
190 | static void checkFormattedValueString( | |
191 | const char* message, | |
192 | const UFormattedValue* fv, | |
193 | const UChar* expectedString, | |
194 | UErrorCode* ec) { | |
195 | int32_t length; | |
196 | const UChar* actualString = ufmtval_getString(fv, &length, ec); | |
197 | if (U_FAILURE(*ec)) { | |
198 | assertIntEquals(message, 0, length); | |
199 | return; | |
200 | } | |
201 | assertSuccess(message, ec); | |
202 | // The string is guaranteed to be NUL-terminated. | |
203 | int32_t actualLength = u_strlen(actualString); | |
204 | assertIntEquals(message, actualLength, length); | |
205 | assertUEquals(message, expectedString, actualString); | |
206 | } | |
207 | ||
208 | // Declared in cformtst.h | |
209 | void checkFormattedValue( | |
210 | const char* message, | |
211 | const UFormattedValue* fv, | |
212 | const UChar* expectedString, | |
213 | UFieldCategory expectedCategory, | |
214 | const UFieldPosition* expectedFieldPositions, | |
215 | int32_t expectedFieldPositionsLength) { | |
340931cb | 216 | (void)expectedFieldPositionsLength; // suppress compiler warnings about unused variable |
3d1f044b A |
217 | UErrorCode ec = U_ZERO_ERROR; |
218 | checkFormattedValueString(message, fv, expectedString, &ec); | |
219 | if (U_FAILURE(ec)) { return; } | |
220 | ||
221 | // Basic loop over the fields (more rigorous testing in C++) | |
222 | UConstrainedFieldPosition* ucfpos = ucfpos_open(&ec); | |
223 | int32_t i = 0; | |
224 | while (ufmtval_nextPosition(fv, ucfpos, &ec)) { | |
225 | assertIntEquals("category", | |
226 | expectedCategory, ucfpos_getCategory(ucfpos, &ec)); | |
227 | assertIntEquals("field", | |
228 | expectedFieldPositions[i].field, ucfpos_getField(ucfpos, &ec)); | |
229 | int32_t start, limit; | |
230 | ucfpos_getIndexes(ucfpos, &start, &limit, &ec); | |
231 | assertIntEquals("start", | |
232 | expectedFieldPositions[i].beginIndex, start); | |
233 | assertIntEquals("limit", | |
234 | expectedFieldPositions[i].endIndex, limit); | |
235 | i++; | |
236 | } | |
237 | assertTrue("After loop", !ufmtval_nextPosition(fv, ucfpos, &ec)); | |
238 | assertSuccess("After loop", &ec); | |
239 | ucfpos_close(ucfpos); | |
240 | } | |
241 | ||
242 | void checkMixedFormattedValue( | |
243 | const char* message, | |
244 | const UFormattedValue* fv, | |
245 | const UChar* expectedString, | |
246 | const UFieldPositionWithCategory* expectedFieldPositions, | |
247 | int32_t length) { | |
340931cb | 248 | (void)length; // suppress compiler warnings about unused variable |
3d1f044b A |
249 | UErrorCode ec = U_ZERO_ERROR; |
250 | checkFormattedValueString(message, fv, expectedString, &ec); | |
251 | if (U_FAILURE(ec)) { return; } | |
252 | ||
253 | // Basic loop over the fields (more rigorous testing in C++) | |
254 | UConstrainedFieldPosition* ucfpos = ucfpos_open(&ec); | |
255 | int32_t i = 0; | |
256 | while (ufmtval_nextPosition(fv, ucfpos, &ec)) { | |
257 | assertIntEquals("category", | |
258 | expectedFieldPositions[i].category, ucfpos_getCategory(ucfpos, &ec)); | |
259 | assertIntEquals("field", | |
260 | expectedFieldPositions[i].field, ucfpos_getField(ucfpos, &ec)); | |
261 | int32_t start, limit; | |
262 | ucfpos_getIndexes(ucfpos, &start, &limit, &ec); | |
263 | assertIntEquals("start", | |
264 | expectedFieldPositions[i].beginIndex, start); | |
265 | assertIntEquals("limit", | |
266 | expectedFieldPositions[i].endIndex, limit); | |
267 | i++; | |
268 | } | |
269 | assertTrue("After loop", !ufmtval_nextPosition(fv, ucfpos, &ec)); | |
270 | assertSuccess("After loop", &ec); | |
271 | ucfpos_close(ucfpos); | |
272 | } | |
273 | ||
274 | ||
275 | #endif /* #if !UCONFIG_NO_FORMATTING */ |