1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
4 #include "unicode/utypes.h"
6 #if !UCONFIG_NO_FORMATTING
10 #include "unicode/formattedvalue.h"
11 #include "unicode/unum.h"
12 #include "unicode/udat.h"
17 class FormattedValueTest
: public IntlTest
{
19 void runIndexedTest(int32_t index
, UBool exec
, const char *&name
, char *par
=0);
23 void testLocalPointer();
25 void assertAllPartsEqual(
26 UnicodeString messagePrefix
,
27 const ConstrainedFieldPosition
& cfpos
,
29 UFieldCategory category
,
36 void FormattedValueTest::runIndexedTest(int32_t index
, UBool exec
, const char *&name
, char *) {
38 logln("TestSuite FormattedValueTest: ");
41 TESTCASE_AUTO(testBasic
);
42 TESTCASE_AUTO(testSetters
);
43 TESTCASE_AUTO(testLocalPointer
);
48 void FormattedValueTest::testBasic() {
49 IcuTestErrorCode
status(*this, "testBasic");
50 ConstrainedFieldPosition cfpos
;
55 UFIELD_CATEGORY_UNDEFINED
,
62 void FormattedValueTest::testSetters() {
63 IcuTestErrorCode
status(*this, "testSetters");
64 ConstrainedFieldPosition cfpos
;
66 cfpos
.constrainCategory(UFIELD_CATEGORY_DATE
);
77 cfpos
.constrainField(UFIELD_CATEGORY_NUMBER
, UNUM_COMPACT_FIELD
);
82 UFIELD_CATEGORY_NUMBER
,
88 cfpos
.setInt64IterationContext(42424242424242LL);
93 UFIELD_CATEGORY_NUMBER
,
99 cfpos
.setState(UFIELD_CATEGORY_NUMBER
, UNUM_COMPACT_FIELD
, 5, 10);
104 UFIELD_CATEGORY_NUMBER
,
115 UFIELD_CATEGORY_UNDEFINED
,
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",
128 ucfpos_getInt64IterationContext(ucfpos
.getAlias(), &status
));
129 assertSuccess("Using LocalUConstrainedFieldPositionPointer", status
);
132 /** For matching, turn on these bits:
134 * 1 = UNUM_INTEGER_FIELD
135 * 2 = UNUM_COMPACT_FIELD
136 * 4 = UDAT_AM_PM_FIELD
138 void FormattedValueTest::assertAllPartsEqual(
139 UnicodeString messagePrefix
,
140 const ConstrainedFieldPosition
& cfpos
,
142 UFieldCategory category
,
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());
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
));
167 void IntlTestWithFieldPosition::checkFormattedValue(
168 const char16_t* message
,
169 const FormattedValue
& fv
,
170 UnicodeString expectedString
,
171 UFieldCategory expectedCategory
,
172 const UFieldPosition
* expectedFieldPositions
,
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
;
181 checkMixedFormattedValue(message
, fv
, expectedString
, converted
.getAlias(), length
);
185 UnicodeString
CFPosToUnicodeString(const ConstrainedFieldPosition
& cfpos
) {
187 sb
.append(u
"CFPos[");
188 sb
.append(Int64ToUnicodeString(cfpos
.getStart()));
190 sb
.append(Int64ToUnicodeString(cfpos
.getLimit()));
192 sb
.append(Int64ToUnicodeString(cfpos
.getCategory()));
194 sb
.append(Int64ToUnicodeString(cfpos
.getField()));
200 void IntlTestWithFieldPosition::checkMixedFormattedValue(
201 const char16_t* message
,
202 const FormattedValue
& fv
,
203 UnicodeString expectedString
,
204 const UFieldPositionWithCategory
* expectedFieldPositions
,
206 IcuTestErrorCode
status(*this, "checkMixedFormattedValue");
207 UnicodeString baseMessage
= UnicodeString(message
) + u
": " + fv
.toString(status
) + u
": ";
209 // Check string values
210 assertEquals(baseMessage
+ u
"string", expectedString
, fv
.toString(status
));
211 assertEquals(baseMessage
+ u
"temp string", expectedString
, fv
.toTempString(status
));
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()]);
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());
238 UBool afterLoopResult
= fv
.nextPosition(cfpos
, status
);
239 assertFalse(baseMessage
+ u
"A after loop: " + CFPosToUnicodeString(cfpos
), afterLoopResult
);
241 // Check nextPosition constrained over each category one at a time
242 for (int32_t category
=0; category
<UFIELD_CATEGORY_COUNT
; category
++) {
244 cfpos
.constrainCategory(static_cast<UFieldCategory
>(category
));
245 for (int32_t i
= 0; i
< length
; i
++) {
246 if (expectedFieldPositions
[i
].category
!= category
) {
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());
264 UBool afterLoopResult
= fv
.nextPosition(cfpos
, status
);
265 assertFalse(baseMessage
+ u
"B after loop @ " + CFPosToUnicodeString(cfpos
), afterLoopResult
);
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
});
273 for (std::pair
<UFieldCategory
, int32_t> categoryAndField
: uniqueFields
) {
275 cfpos
.constrainField(categoryAndField
.first
, categoryAndField
.second
);
276 for (int32_t i
= 0; i
< length
; i
++) {
277 if (expectedFieldPositions
[i
].category
!= categoryAndField
.first
) {
280 if (expectedFieldPositions
[i
].field
!= categoryAndField
.second
) {
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());
298 UBool afterLoopResult
= fv
.nextPosition(cfpos
, status
);
299 assertFalse(baseMessage
+ u
"C after loop: " + CFPosToUnicodeString(cfpos
), afterLoopResult
);
304 extern IntlTest
*createFormattedValueTest() {
305 return new FormattedValueTest();
308 #endif /* !UCONFIG_NO_FORMATTING */