• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
runIndexedTest(int32_t index,UBool exec,const char * & name,char *)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 
testBasic()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 
testSetters()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 
testLocalPointer()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  */
assertAllPartsEqual(UnicodeString messagePrefix,const ConstrainedFieldPosition & cfpos,int32_t matching,UFieldCategory category,int32_t field,int32_t start,int32_t limit,int64_t context)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 
checkFormattedValue(const char16_t * message,const FormattedValue & fv,UnicodeString expectedString,UFieldCategory expectedCategory,const UFieldPosition * expectedFieldPositions,int32_t length)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 
CFPosToUnicodeString(const ConstrainedFieldPosition & cfpos)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 
checkMixedFormattedValue(const char16_t * message,const FormattedValue & fv,UnicodeString expectedString,const UFieldPositionWithCategory * expectedFieldPositions,int32_t length)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     afterLoopResult = fv.nextPosition(cfpos, status);
241     assertFalse(baseMessage + u"A after loop again: " + CFPosToUnicodeString(cfpos), afterLoopResult);
242 
243     // Check nextPosition constrained over each category one at a time
244     for (int32_t category=0; category<=UFIELD_CATEGORY_COUNT+1; category++) {
245         if (category == UFIELD_CATEGORY_COUNT+1) {
246             category = UFIELD_CATEGORY_LIST_SPAN;
247         }
248         cfpos.reset();
249         cfpos.constrainCategory(static_cast<UFieldCategory>(category));
250         for (int32_t i = 0; i < length; i++) {
251             if (expectedFieldPositions[i].category != category) {
252                 continue;
253             }
254             assertTrue(baseMessage + u"B has next position @ " + Int64ToUnicodeString(i),
255                 fv.nextPosition(cfpos, status));
256             int32_t expectedCategory = expectedFieldPositions[i].category;
257             int32_t expectedField = expectedFieldPositions[i].field;
258             int32_t expectedStart = expectedFieldPositions[i].beginIndex;
259             int32_t expectedLimit = expectedFieldPositions[i].endIndex;
260             assertEquals(baseMessage + u"B category @ " + Int64ToUnicodeString(i),
261                 expectedCategory, cfpos.getCategory());
262             assertEquals(baseMessage + u"B field @ " + Int64ToUnicodeString(i),
263                 expectedField, cfpos.getField());
264             assertEquals(baseMessage + u"B start @ " + Int64ToUnicodeString(i),
265                 expectedStart, cfpos.getStart());
266             assertEquals(baseMessage + u"B limit @ " + Int64ToUnicodeString(i),
267                 expectedLimit, cfpos.getLimit());
268         }
269         UBool afterLoopResult = fv.nextPosition(cfpos, status);
270         assertFalse(baseMessage + u"B after loop @ " + CFPosToUnicodeString(cfpos), afterLoopResult);
271         afterLoopResult = fv.nextPosition(cfpos, status);
272         assertFalse(baseMessage + u"B after loop again @ " + CFPosToUnicodeString(cfpos), afterLoopResult);
273     }
274 
275     // Check nextPosition constrained over each field one at a time
276     std::set<std::pair<UFieldCategory, int32_t>> uniqueFields;
277     for (int32_t i = 0; i < length; i++) {
278         uniqueFields.insert({expectedFieldPositions[i].category, expectedFieldPositions[i].field});
279     }
280     for (std::pair<UFieldCategory, int32_t> categoryAndField : uniqueFields) {
281         cfpos.reset();
282         cfpos.constrainField(categoryAndField.first, categoryAndField.second);
283         for (int32_t i = 0; i < length; i++) {
284             if (expectedFieldPositions[i].category != categoryAndField.first) {
285                 continue;
286             }
287             if (expectedFieldPositions[i].field != categoryAndField.second) {
288                 continue;
289             }
290             assertTrue(baseMessage + u"C has next position @ " + Int64ToUnicodeString(i),
291                 fv.nextPosition(cfpos, status));
292             int32_t expectedCategory = expectedFieldPositions[i].category;
293             int32_t expectedField = expectedFieldPositions[i].field;
294             int32_t expectedStart = expectedFieldPositions[i].beginIndex;
295             int32_t expectedLimit = expectedFieldPositions[i].endIndex;
296             assertEquals(baseMessage + u"C category @ " + Int64ToUnicodeString(i),
297                 expectedCategory, cfpos.getCategory());
298             assertEquals(baseMessage + u"C field @ " + Int64ToUnicodeString(i),
299                 expectedField, cfpos.getField());
300             assertEquals(baseMessage + u"C start @ " + Int64ToUnicodeString(i),
301                 expectedStart, cfpos.getStart());
302             assertEquals(baseMessage + u"C limit @ " + Int64ToUnicodeString(i),
303                 expectedLimit, cfpos.getLimit());
304         }
305         UBool afterLoopResult = fv.nextPosition(cfpos, status);
306         assertFalse(baseMessage + u"C after loop: " + CFPosToUnicodeString(cfpos), afterLoopResult);
307         afterLoopResult = fv.nextPosition(cfpos, status);
308         assertFalse(baseMessage + u"C after loop again: " + CFPosToUnicodeString(cfpos), afterLoopResult);
309     }
310 }
311 
312 
createFormattedValueTest()313 extern IntlTest *createFormattedValueTest() {
314     return new FormattedValueTest();
315 }
316 
317 #endif /* !UCONFIG_NO_FORMATTING */
318