• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
addUFormattedValueTest(TestNode ** root)34 void addUFormattedValueTest(TestNode** root) {
35     TESTCASE(TestBasic);
36     TESTCASE(TestSetters);
37 }
38 
39 
TestBasic()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 
TestSetters()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  */
AssertAllPartsEqual(const char * messagePrefix,const UConstrainedFieldPosition * ucfpos,int32_t matching,UFieldCategory category,int32_t field,int32_t start,int32_t limit,int64_t context)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 
checkFormattedValueString(const char * message,const UFormattedValue * fv,const UChar * expectedString,UErrorCode * ec)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
checkFormattedValue(const char * message,const UFormattedValue * fv,const UChar * expectedString,UFieldCategory expectedCategory,const UFieldPosition * expectedFieldPositions,int32_t expectedFieldPositionsLength)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) {
216     (void)expectedFieldPositionsLength; // suppress compiler warnings about unused variable
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 
checkMixedFormattedValue(const char * message,const UFormattedValue * fv,const UChar * expectedString,const UFieldPositionWithCategory * expectedFieldPositions,int32_t length)242 void checkMixedFormattedValue(
243         const char* message,
244         const UFormattedValue* fv,
245         const UChar* expectedString,
246         const UFieldPositionWithCategory* expectedFieldPositions,
247         int32_t length) {
248     (void)length; // suppress compiler warnings about unused variable
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 */
276