2 *******************************************************************************
4 * Copyright (C) 2007-2010, International Business Machines
5 * Corporation and others. All Rights Reserved.
7 *******************************************************************************
8 * file name: udatpg_test.c
10 * tab size: 8 (not used)
13 * created on: 2007aug01
14 * created by: Markus W. Scherer
16 * Test of the C wrapper for the DateTimePatternGenerator.
17 * Calls each C API function and exercises code paths in the wrapper,
18 * but the full functionality is tested in the C++ intltest.
20 * One item to note: C API functions which return a const UChar *
21 * should return a NUL-terminated string.
22 * (The C++ implementation needs to use getTerminatedBuffer()
23 * on UnicodeString objects which end up being returned this way.)
26 #include "unicode/utypes.h"
28 #if !UCONFIG_NO_FORMATTING
29 #include "unicode/udat.h"
30 #include "unicode/udatpg.h"
31 #include "unicode/ustring.h"
34 void addDateTimePatternGeneratorTest(TestNode
** root
);
36 #define TESTCASE(x) addTest(root, &x, "tsformat/udatpg_test/" #x)
38 static void TestOpenClose(void);
39 static void TestUsage(void);
40 static void TestBuilder(void);
41 static void TestOptions(void);
43 void addDateTimePatternGeneratorTest(TestNode
** root
) {
44 TESTCASE(TestOpenClose
);
46 TESTCASE(TestBuilder
);
47 TESTCASE(TestOptions
);
51 * Pipe symbol '|'. We pass only the first UChar without NUL-termination.
52 * The second UChar is just to verify that the API does not pick that up.
54 static const UChar pipeString
[]={ 0x7c, 0x0a };
56 static const UChar testSkeleton1
[]={ 0x48, 0x48, 0x6d, 0x6d, 0 }; /* HHmm */
57 static const UChar expectingBestPattern
[]={ 0x48, 0x2e, 0x6d, 0x6d, 0 }; /* H.mm */
58 static const UChar testPattern
[]={ 0x48, 0x48, 0x3a, 0x6d, 0x6d, 0 }; /* HH:mm */
59 static const UChar expectingSkeleton
[]= { 0x48, 0x48, 0x6d, 0x6d, 0 }; /* HHmm */
60 static const UChar expectingBaseSkeleton
[]= { 0x48, 0x6d, 0 }; /* HHmm */
61 static const UChar redundantPattern
[]={ 0x79, 0x79, 0x4d, 0x4d, 0x4d, 0 }; /* yyMMM */
62 static const UChar testFormat
[]= {0x7B, 0x31, 0x7D, 0x20, 0x7B, 0x30, 0x7D, 0}; /* {1} {0} */
63 static const UChar appendItemName
[]= {0x68, 0x72, 0}; /* hr */
64 static const UChar testPattern2
[]={ 0x48, 0x48, 0x3a, 0x6d, 0x6d, 0x20, 0x76, 0 }; /* HH:mm v */
65 static const UChar replacedStr
[]={ 0x76, 0x76, 0x76, 0x76, 0 }; /* vvvv */
66 /* results for getBaseSkeletons() - {Hmv}, {yMMM} */
67 static const UChar resultBaseSkeletons
[2][10] = {{0x48,0x6d, 0x76, 0}, {0x79, 0x4d, 0x4d, 0x4d, 0 } };
68 static const UChar sampleFormatted
[] = {0x31, 0x30, 0x20, 0x6A, 0x75, 0x69, 0x6C, 0x2E, 0}; /* 10 juil. */
69 static const UChar skeleton
[]= {0x4d, 0x4d, 0x4d, 0x64, 0}; /* MMMd */
70 static const UChar timeZoneGMT
[] = { 0x0047, 0x004d, 0x0054, 0x0000 }; /* "GMT" */
72 static void TestOpenClose() {
73 UErrorCode errorCode
=U_ZERO_ERROR
;
74 UDateTimePatternGenerator
*dtpg
, *dtpg2
;
78 /* Open a DateTimePatternGenerator for the default locale. */
79 dtpg
=udatpg_open(NULL
, &errorCode
);
80 if(U_FAILURE(errorCode
)) {
81 log_err_status(errorCode
, "udatpg_open(NULL) failed - %s\n", u_errorName(errorCode
));
86 /* Now one for German. */
87 dtpg
=udatpg_open("de", &errorCode
);
88 if(U_FAILURE(errorCode
)) {
89 log_err("udatpg_open(de) failed - %s\n", u_errorName(errorCode
));
93 /* Make some modification which we verify gets passed on to the clone. */
94 udatpg_setDecimal(dtpg
, pipeString
, 1);
96 /* Clone the generator. */
97 dtpg2
=udatpg_clone(dtpg
, &errorCode
);
98 if(U_FAILURE(errorCode
) || dtpg2
==NULL
) {
99 log_err("udatpg_clone() failed - %s\n", u_errorName(errorCode
));
103 /* Verify that the clone has the custom decimal symbol. */
104 s
=udatpg_getDecimal(dtpg2
, &length
);
105 if(s
==pipeString
|| length
!=1 || 0!=u_memcmp(s
, pipeString
, length
) || s
[length
]!=0) {
106 log_err("udatpg_getDecimal(cloned object) did not return the expected string\n");
114 static void TestUsage() {
115 UErrorCode errorCode
=U_ZERO_ERROR
;
116 UDateTimePatternGenerator
*dtpg
;
117 UChar bestPattern
[20];
123 dtpg
=udatpg_open("fi", &errorCode
);
124 if(U_FAILURE(errorCode
)) {
125 log_err_status(errorCode
, "udatpg_open(fi) failed - %s\n", u_errorName(errorCode
));
128 length
= udatpg_getBestPattern(dtpg
, testSkeleton1
, 4,
129 bestPattern
, 20, &errorCode
);
130 if(U_FAILURE(errorCode
)) {
131 log_err("udatpg_getBestPattern failed - %s\n", u_errorName(errorCode
));
134 if((u_memcmp(bestPattern
, expectingBestPattern
, length
)!=0) || bestPattern
[length
]!=0) {
135 log_err("udatpg_getBestPattern did not return the expected string\n");
140 /* Test skeleton == NULL */
142 length
= udatpg_getBestPattern(dtpg
, s
, 0, bestPattern
, 20, &errorCode
);
143 if(!U_FAILURE(errorCode
)&&(length
!=0) ) {
144 log_err("udatpg_getBestPattern failed in illegal argument - skeleton is NULL.\n");
148 /* Test udatpg_getSkeleton */
149 length
= udatpg_getSkeleton(dtpg
, testPattern
, 5, result
, 20, &errorCode
);
150 if(U_FAILURE(errorCode
)) {
151 log_err("udatpg_getSkeleton failed - %s\n", u_errorName(errorCode
));
154 if((u_memcmp(result
, expectingSkeleton
, length
)!=0) || result
[length
]!=0) {
155 log_err("udatpg_getSkeleton did not return the expected string\n");
159 /* Test pattern == NULL */
161 length
= udatpg_getSkeleton(dtpg
, s
, 0, result
, 20, &errorCode
);
162 if(!U_FAILURE(errorCode
)&&(length
!=0) ) {
163 log_err("udatpg_getSkeleton failed in illegal argument - pattern is NULL.\n");
167 /* Test udatpg_getBaseSkeleton */
168 length
= udatpg_getBaseSkeleton(dtpg
, testPattern
, 5, result
, 20, &errorCode
);
169 if(U_FAILURE(errorCode
)) {
170 log_err("udatpg_getBaseSkeleton failed - %s\n", u_errorName(errorCode
));
173 if((u_memcmp(result
, expectingBaseSkeleton
, length
)!=0) || result
[length
]!=0) {
174 log_err("udatpg_getBaseSkeleton did not return the expected string\n");
178 /* Test pattern == NULL */
180 length
= udatpg_getBaseSkeleton(dtpg
, s
, 0, result
, 20, &errorCode
);
181 if(!U_FAILURE(errorCode
)&&(length
!=0) ) {
182 log_err("udatpg_getBaseSkeleton failed in illegal argument - pattern is NULL.\n");
186 /* set append format to {1}{0} */
187 udatpg_setAppendItemFormat( dtpg
, UDATPG_MONTH_FIELD
, testFormat
, 7 );
188 r
= udatpg_getAppendItemFormat(dtpg
, UDATPG_MONTH_FIELD
, &length
);
191 if(length
!=7 || 0!=u_memcmp(r
, testFormat
, length
) || r
[length
]!=0) {
192 log_err("udatpg_setAppendItemFormat did not return the expected string\n");
196 /* set append name to hr */
197 udatpg_setAppendItemName( dtpg
, UDATPG_HOUR_FIELD
, appendItemName
, 7 );
198 r
= udatpg_getAppendItemName(dtpg
, UDATPG_HOUR_FIELD
, &length
);
200 if(length
!=7 || 0!=u_memcmp(r
, appendItemName
, length
) || r
[length
]!=0) {
201 log_err("udatpg_setAppendItemName did not return the expected string\n");
205 /* set date time format to {1}{0} */
206 udatpg_setDateTimeFormat( dtpg
, testFormat
, 7 );
207 r
= udatpg_getDateTimeFormat(dtpg
, &length
);
209 if(length
!=7 || 0!=u_memcmp(r
, testFormat
, length
) || r
[length
]!=0) {
210 log_err("udatpg_setDateTimeFormat did not return the expected string\n");
216 static void TestBuilder() {
217 UErrorCode errorCode
=U_ZERO_ERROR
;
218 UDateTimePatternGenerator
*dtpg
;
219 UDateTimePatternConflict conflict
;
222 int32_t length
, pLength
;
224 const UChar
* ptrResult
[2];
226 UDateTimePatternGenerator
*generator
;
227 int32_t formattedCapacity
, resultLen
,patternCapacity
;
228 UChar pattern
[40], formatted
[40];
229 UDateFormat
*formatter
;
230 UDate sampleDate
= 837039928046.0;
231 static const char locale
[]= "fr";
232 UErrorCode status
=U_ZERO_ERROR
;
234 /* test create an empty DateTimePatternGenerator */
235 dtpg
=udatpg_openEmpty(&errorCode
);
236 if(U_FAILURE(errorCode
)) {
237 log_err("udatpg_openEmpty() failed - %s\n", u_errorName(errorCode
));
242 conflict
= udatpg_addPattern(dtpg
, redundantPattern
, 5, FALSE
, result
, 20,
243 &length
, &errorCode
);
244 if(U_FAILURE(errorCode
)) {
245 log_err("udatpg_addPattern() failed - %s\n", u_errorName(errorCode
));
248 /* Add a redundant pattern */
249 conflict
= udatpg_addPattern(dtpg
, redundantPattern
, 5, FALSE
, result
, 20,
250 &length
, &errorCode
);
251 if(conflict
== UDATPG_NO_CONFLICT
) {
252 log_err("udatpg_addPattern() failed to find the duplicate pattern.\n");
255 /* Test pattern == NULL */
257 length
= udatpg_addPattern(dtpg
, s
, 0, FALSE
, result
, 20,
258 &length
, &errorCode
);
259 if(!U_FAILURE(errorCode
)&&(length
!=0) ) {
260 log_err("udatpg_addPattern failed in illegal argument - pattern is NULL.\n");
264 /* replace field type */
265 errorCode
=U_ZERO_ERROR
;
266 conflict
= udatpg_addPattern(dtpg
, testPattern2
, 7, FALSE
, result
, 20,
267 &length
, &errorCode
);
268 if((conflict
!= UDATPG_NO_CONFLICT
)||U_FAILURE(errorCode
)) {
269 log_err("udatpg_addPattern() failed to add HH:mm v. - %s\n", u_errorName(errorCode
));
272 length
= udatpg_replaceFieldTypes(dtpg
, testPattern2
, 7, replacedStr
, 4,
273 result
, 20, &errorCode
);
274 if (U_FAILURE(errorCode
) || (length
==0) ) {
275 log_err("udatpg_replaceFieldTypes failed!\n");
279 /* Get all skeletons and the crroespong pattern for each skeleton. */
280 ptrResult
[0] = testPattern2
;
281 ptrResult
[1] = redundantPattern
;
283 en
= udatpg_openSkeletons(dtpg
, &errorCode
);
284 if (U_FAILURE(errorCode
) || (length
==0) ) {
285 log_err("udatpg_openSkeletons failed!\n");
288 while ( (s
=uenum_unext(en
, &length
, &errorCode
))!= NULL
) {
289 p
= udatpg_getPatternForSkeleton(dtpg
, s
, length
, &pLength
);
290 if (U_FAILURE(errorCode
) || p
==NULL
|| u_memcmp(p
, ptrResult
[count
], pLength
)!=0 ) {
291 log_err("udatpg_getPatternForSkeleton failed!\n");
298 /* Get all baseSkeletons */
299 en
= udatpg_openBaseSkeletons(dtpg
, &errorCode
);
301 while ( (s
=uenum_unext(en
, &length
, &errorCode
))!= NULL
) {
302 p
= udatpg_getPatternForSkeleton(dtpg
, s
, length
, &pLength
);
303 if (U_FAILURE(errorCode
) || p
==NULL
|| u_memcmp(p
, resultBaseSkeletons
[count
], pLength
)!=0 ) {
304 log_err("udatpg_getPatternForSkeleton failed!\n");
309 if (U_FAILURE(errorCode
) || (length
==0) ) {
310 log_err("udatpg_openSkeletons failed!\n");
317 /* sample code in Userguide */
318 patternCapacity
= (int32_t)(sizeof(pattern
)/sizeof((pattern
)[0]));
320 generator
=udatpg_open(locale
, &status
);
321 if(U_FAILURE(status
)) {
325 /* get a pattern for an abbreviated month and day */
326 length
= udatpg_getBestPattern(generator
, skeleton
, 4,
327 pattern
, patternCapacity
, &status
);
328 formatter
= udat_open(UDAT_IGNORE
, UDAT_DEFAULT
, locale
, timeZoneGMT
, -1,
329 pattern
, length
, &status
);
330 if (formatter
==NULL
) {
331 log_err("Failed to initialize the UDateFormat of the sample code in Userguide.\n");
332 udatpg_close(generator
);
336 /* use it to format (or parse) */
337 formattedCapacity
= (int32_t)(sizeof(formatted
)/sizeof((formatted
)[0]));
338 resultLen
=udat_format(formatter
, ucal_getNow(), formatted
, formattedCapacity
,
340 /* for French, the result is "13 sept." */
342 /* cannot use the result from ucal_getNow() because the value change evreyday. */
343 resultLen
=udat_format(formatter
, sampleDate
, formatted
, formattedCapacity
,
345 if ( u_memcmp(sampleFormatted
, formatted
, resultLen
) != 0 ) {
346 log_err("Failed udat_format() of sample code in Userguide.\n");
348 udatpg_close(generator
);
349 udat_close(formatter
);
352 typedef struct DTPtnGenOptionsData
{
355 UDateTimePatternMatchOptions options
;
356 const UChar
* expectedPattern
;
357 } DTPtnGenOptionsData
;
358 enum { kTestOptionsPatLenMax
= 32 };
360 static const UChar skel_Hmm
[] = { 0x0048, 0x006D, 0x006D, 0 };
361 static const UChar skel_HHmm
[] = { 0x0048, 0x0048, 0x006D, 0x006D, 0 };
362 static const UChar skel_hhmm
[] = { 0x0068, 0x0068, 0x006D, 0x006D, 0 };
363 static const UChar patn_Hcmm
[] = { 0x0048, 0x003A, 0x006D, 0x006D, 0 }; /* H:mm */
364 static const UChar patn_hcmm_a
[] = { 0x0068, 0x003A, 0x006D, 0x006D, 0x0020, 0x0061, 0 }; /* h:mm a */
365 static const UChar patn_HHcmm
[] = { 0x0048, 0x0048, 0x003A, 0x006D, 0x006D, 0 }; /* HH:mm */
366 static const UChar patn_hhcmm_a
[] = { 0x0068, 0x0068, 0x003A, 0x006D, 0x006D, 0x0020, 0x0061, 0 }; /* hh:mm a */
367 static const UChar patn_HHpmm
[] = { 0x0048, 0x0048, 0x002E, 0x006D, 0x006D, 0 }; /* HH.mm */
368 static const UChar patn_hpmm_a
[] = { 0x0068, 0x002E, 0x006D, 0x006D, 0x0020, 0x0061, 0 }; /* h.mm a */
369 static const UChar patn_Hpmm
[] = { 0x0048, 0x002E, 0x006D, 0x006D, 0 }; /* H.mm */
370 static const UChar patn_hhpmm_a
[] = { 0x0068, 0x0068, 0x002E, 0x006D, 0x006D, 0x0020, 0x0061, 0 }; /* hh.mm a */
372 static void TestOptions() {
373 const DTPtnGenOptionsData testData
[] = {
374 /*loc skel options expectedPattern */
375 { "en", skel_Hmm
, UDATPG_MATCH_NO_OPTIONS
, patn_HHcmm
},
376 { "en", skel_HHmm
, UDATPG_MATCH_NO_OPTIONS
, patn_HHcmm
},
377 { "en", skel_hhmm
, UDATPG_MATCH_NO_OPTIONS
, patn_hcmm_a
},
378 { "en", skel_Hmm
, UDATPG_MATCH_HOUR_FIELD_LENGTH
, patn_HHcmm
},
379 { "en", skel_HHmm
, UDATPG_MATCH_HOUR_FIELD_LENGTH
, patn_HHcmm
},
380 { "en", skel_hhmm
, UDATPG_MATCH_HOUR_FIELD_LENGTH
, patn_hhcmm_a
},
381 { "be", skel_Hmm
, UDATPG_MATCH_NO_OPTIONS
, patn_HHpmm
},
382 { "be", skel_HHmm
, UDATPG_MATCH_NO_OPTIONS
, patn_HHpmm
},
383 { "be", skel_hhmm
, UDATPG_MATCH_NO_OPTIONS
, patn_hpmm_a
},
384 { "be", skel_Hmm
, UDATPG_MATCH_HOUR_FIELD_LENGTH
, patn_Hpmm
},
385 { "be", skel_HHmm
, UDATPG_MATCH_HOUR_FIELD_LENGTH
, patn_HHpmm
},
386 { "be", skel_hhmm
, UDATPG_MATCH_HOUR_FIELD_LENGTH
, patn_hhpmm_a
},
389 int count
= sizeof(testData
) / sizeof(testData
[0]);
390 const DTPtnGenOptionsData
* testDataPtr
= testData
;
392 for (; count
-- > 0; ++testDataPtr
) {
393 UErrorCode status
= U_ZERO_ERROR
;
394 UDateTimePatternGenerator
* dtpgen
= udatpg_open(testDataPtr
->locale
, &status
);
395 if ( U_SUCCESS(status
) ) {
396 UChar pattern
[kTestOptionsPatLenMax
];
397 int32_t patLen
= udatpg_getBestPatternWithOptions(dtpgen
, testDataPtr
->skel
, -1,
398 testDataPtr
->options
, pattern
,
399 kTestOptionsPatLenMax
, &status
);
400 if ( U_FAILURE(status
) || u_strncmp(pattern
, testDataPtr
->expectedPattern
, patLen
+1) != 0 ) {
401 char skelBytes
[kTestOptionsPatLenMax
];
402 char expectedPatternBytes
[kTestOptionsPatLenMax
];
403 char patternBytes
[kTestOptionsPatLenMax
];
404 log_err("ERROR udatpg_getBestPatternWithOptions, locale %s, skeleton %s, options 0x%04X, expected pattern %s, got %s, status %d\n",
405 testDataPtr
->locale
, u_austrncpy(skelBytes
,testDataPtr
->skel
,kTestOptionsPatLenMax
), testDataPtr
->options
,
406 u_austrncpy(expectedPatternBytes
,testDataPtr
->expectedPattern
,kTestOptionsPatLenMax
),
407 u_austrncpy(patternBytes
,pattern
,kTestOptionsPatLenMax
), status
);
409 udatpg_close(dtpgen
);
411 log_data_err("ERROR udatpg_open failed for locale %s : %s - (Are you missing data?)\n", testDataPtr
->locale
, myErrorName(status
));