]>
Commit | Line | Data |
---|---|---|
2ca993e8 A |
1 | /******************************************************************** |
2 | * Copyright (c) 2016, International Business Machines Corporation | |
3 | * and others. All Rights Reserved. | |
4 | ********************************************************************/ | |
5 | /* C API TEST FOR DATE INTERVAL FORMAT */ | |
6 | ||
7 | #include "unicode/utypes.h" | |
8 | ||
9 | #if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_BREAK_ITERATION | |
10 | ||
11 | #include "unicode/ureldatefmt.h" | |
12 | #include "unicode/unum.h" | |
13 | #include "unicode/udisplaycontext.h" | |
14 | #include "unicode/ustring.h" | |
15 | #include "cintltst.h" | |
16 | #include "cmemory.h" | |
17 | ||
18 | static void TestRelDateFmt(void); | |
19 | static void TestCombineDateTime(void); | |
20 | ||
21 | void addRelativeDateFormatTest(TestNode** root); | |
22 | ||
23 | #define TESTCASE(x) addTest(root, &x, "tsformat/crelativedateformattest/" #x) | |
24 | ||
25 | void addRelativeDateFormatTest(TestNode** root) | |
26 | { | |
27 | TESTCASE(TestRelDateFmt); | |
28 | TESTCASE(TestCombineDateTime); | |
29 | } | |
30 | ||
31 | static const double offsets[] = { -5.0, -2.2, -2.0, -1.0, -0.7, 0.0, 0.7, 1.0, 2.0, 5.0 }; | |
32 | enum { kNumOffsets = UPRV_LENGTHOF(offsets) }; | |
33 | ||
34 | static const char* en_decDef_long_midSent_week[kNumOffsets*2] = { | |
35 | /* text numeric */ | |
36 | "5 weeks ago", "5 weeks ago", /* -5 */ | |
37 | "2.2 weeks ago", "2.2 weeks ago", /* -2.2 */ | |
38 | "2 weeks ago", "2 weeks ago", /* -2 */ | |
39 | "last week", "1 week ago", /* -1 */ | |
40 | "0.7 weeks ago", "0.7 weeks ago", /* -0.7 */ | |
41 | "this week", "in 0 weeks", /* 0 */ | |
42 | "in 0.7 weeks", "in 0.7 weeks", /* 0.7 */ | |
43 | "next week", "in 1 week", /* 1 */ | |
44 | "in 2 weeks", "in 2 weeks", /* 2 */ | |
45 | "in 5 weeks", "in 5 weeks" /* 5 */ | |
46 | }; | |
47 | ||
48 | static const char* en_dec0_long_midSent_week[kNumOffsets*2] = { | |
49 | /* text numeric */ | |
50 | "5 weeks ago", "5 weeks ago", /* -5 */ | |
51 | "2 weeks ago", "2 weeks ago", /* -2.2 */ | |
52 | "2 weeks ago", "2 weeks ago", /* -2 */ | |
53 | "last week", "1 week ago", /* -1 */ | |
54 | "0 weeks ago", "0 weeks ago", /* -0.7 */ | |
55 | "this week", "in 0 weeks", /* 0 */ | |
56 | "in 0 weeks", "in 0 weeks", /* 0.7 */ | |
57 | "next week", "in 1 week", /* 1 */ | |
58 | "in 2 weeks", "in 2 weeks", /* 2 */ | |
59 | "in 5 weeks", "in 5 weeks" /* 5 */ | |
60 | }; | |
61 | ||
62 | static const char* en_decDef_short_midSent_week[kNumOffsets*2] = { | |
63 | /* text numeric */ | |
64 | "5 wk. ago", "5 wk. ago", /* -5 */ | |
65 | "2.2 wk. ago", "2.2 wk. ago", /* -2.2 */ | |
66 | "2 wk. ago", "2 wk. ago", /* -2 */ | |
67 | "last wk.", "1 wk. ago", /* -1 */ | |
68 | "0.7 wk. ago", "0.7 wk. ago", /* -0.7 */ | |
69 | "this wk.", "in 0 wk.", /* 0 */ | |
70 | "in 0.7 wk.", "in 0.7 wk.", /* 0.7 */ | |
71 | "next wk.", "in 1 wk.", /* 1 */ | |
72 | "in 2 wk.", "in 2 wk.", /* 2 */ | |
73 | "in 5 wk.", "in 5 wk." /* 5 */ | |
74 | }; | |
75 | ||
76 | static const char* en_decDef_long_midSent_min[kNumOffsets*2] = { | |
77 | /* text numeric */ | |
78 | "5 minutes ago", "5 minutes ago", /* -5 */ | |
79 | "2.2 minutes ago", "2.2 minutes ago", /* -2.2 */ | |
80 | "2 minutes ago", "2 minutes ago", /* -2 */ | |
81 | "1 minute ago", "1 minute ago", /* -1 */ | |
82 | "0.7 minutes ago", "0.7 minutes ago", /* -0.7 */ | |
83 | "in 0 minutes", "in 0 minutes", /* 0 */ | |
84 | "in 0.7 minutes", "in 0.7 minutes", /* 0.7 */ | |
85 | "in 1 minute", "in 1 minute", /* 1 */ | |
86 | "in 2 minutes", "in 2 minutes", /* 2 */ | |
87 | "in 5 minutes", "in 5 minutes" /* 5 */ | |
88 | }; | |
89 | ||
90 | static const char* en_dec0_long_midSent_tues[kNumOffsets*2] = { | |
91 | /* text numeric */ | |
92 | ""/*no data */, ""/*no data */, /* -5 */ | |
93 | ""/*no data */, ""/*no data */, /* -2.2 */ | |
94 | ""/*no data */, ""/*no data */, /* -2 */ | |
95 | "last Tuesday", ""/*no data */, /* -1 */ | |
96 | ""/*no data */, ""/*no data */, /* -0.7 */ | |
97 | "this Tuesday", ""/*no data */, /* 0 */ | |
98 | ""/*no data */, ""/*no data */, /* 0.7 */ | |
99 | "next Tuesday", ""/*no data */, /* 1 */ | |
100 | ""/*no data */, ""/*no data */, /* 2 */ | |
101 | ""/*no data */, ""/*no data */, /* 5 */ | |
102 | }; | |
103 | ||
104 | static const char* fr_decDef_long_midSent_day[kNumOffsets*2] = { | |
105 | /* text numeric */ | |
106 | "il y a 5 jours", "il y a 5 jours", /* -5 */ | |
107 | "il y a 2,2 jours", "il y a 2,2 jours", /* -2.2 */ | |
108 | "avant-hier", "il y a 2 jours", /* -2 */ | |
109 | "hier", "il y a 1 jour", /* -1 */ | |
110 | "il y a 0,7 jour", "il y a 0,7 jour", /* -0.7 */ | |
111 | "aujourd\\u2019hui", "dans 0 jour", /* 0 */ | |
112 | "dans 0,7 jour", "dans 0,7 jour", /* 0.7 */ | |
113 | "demain", "dans 1 jour", /* 1 */ | |
114 | "apr\\u00E8s-demain", "dans 2 jours", /* 2 */ | |
115 | "dans 5 jours", "dans 5 jours" /* 5 */ | |
116 | }; | |
117 | ||
118 | ||
119 | typedef struct { | |
120 | const char* locale; | |
121 | int32_t decPlaces; /* fixed decimal places; -1 to use default num formatter */ | |
122 | UDateRelativeDateTimeFormatterStyle width; | |
123 | UDisplayContext capContext; | |
124 | URelativeDateTimeUnit unit; | |
125 | const char ** expectedResults; /* for the various offsets */ | |
126 | } RelDateTimeFormatTestItem; | |
127 | ||
128 | static const RelDateTimeFormatTestItem fmtTestItems[] = { | |
129 | { "en", -1, UDAT_STYLE_LONG, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, UDAT_REL_UNIT_WEEK, en_decDef_long_midSent_week }, | |
130 | { "en", 0, UDAT_STYLE_LONG, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, UDAT_REL_UNIT_WEEK, en_dec0_long_midSent_week }, | |
131 | { "en", -1, UDAT_STYLE_SHORT, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, UDAT_REL_UNIT_WEEK, en_decDef_short_midSent_week }, | |
132 | { "en", -1, UDAT_STYLE_LONG, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, UDAT_REL_UNIT_MINUTE, en_decDef_long_midSent_min }, | |
133 | { "en", -1, UDAT_STYLE_LONG, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, UDAT_REL_UNIT_TUESDAY, en_dec0_long_midSent_tues }, | |
134 | { "fr", -1, UDAT_STYLE_LONG, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, UDAT_REL_UNIT_DAY, fr_decDef_long_midSent_day }, | |
135 | { NULL, 0, (UDateRelativeDateTimeFormatterStyle)0, (UDisplayContext)0, (URelativeDateTimeUnit)0, NULL } /* terminator */ | |
136 | }; | |
137 | ||
138 | enum { kUBufMax = 64, kBBufMax = 256 }; | |
139 | ||
140 | static void TestRelDateFmt() | |
141 | { | |
142 | const RelDateTimeFormatTestItem *itemPtr; | |
143 | log_verbose("\nTesting ureldatefmt_open(), ureldatefmt_format(), ureldatefmt_formatNumeric() with various parameters\n"); | |
144 | for (itemPtr = fmtTestItems; itemPtr->locale != NULL; itemPtr++) { | |
145 | URelativeDateTimeFormatter *reldatefmt = NULL; | |
146 | UNumberFormat* nfToAdopt = NULL; | |
147 | UErrorCode status = U_ZERO_ERROR; | |
148 | int32_t iOffset; | |
149 | ||
150 | if (itemPtr->decPlaces >= 0) { | |
151 | nfToAdopt = unum_open(UNUM_DECIMAL, NULL, 0, itemPtr->locale, NULL, &status); | |
152 | if ( U_FAILURE(status) ) { | |
153 | log_data_err("FAIL: unum_open(UNUM_DECIMAL, ...) for locale %s: %s\n", itemPtr->locale, myErrorName(status)); | |
154 | continue; | |
155 | } | |
156 | unum_setAttribute(nfToAdopt, UNUM_MIN_FRACTION_DIGITS, itemPtr->decPlaces); | |
157 | unum_setAttribute(nfToAdopt, UNUM_MAX_FRACTION_DIGITS, itemPtr->decPlaces); | |
158 | unum_setAttribute(nfToAdopt, UNUM_ROUNDING_MODE, UNUM_ROUND_DOWN); | |
159 | } | |
160 | reldatefmt = ureldatefmt_open(itemPtr->locale, nfToAdopt, itemPtr->width, itemPtr->capContext, &status); | |
161 | if ( U_FAILURE(status) ) { | |
162 | log_data_err("FAIL: ureldatefmt_open() for locale %s, decPlaces %d, width %d, capContext %d: %s\n", | |
163 | itemPtr->locale, itemPtr->decPlaces, (int)itemPtr->width, (int)itemPtr->capContext, | |
164 | myErrorName(status) ); | |
165 | continue; | |
166 | } | |
167 | ||
168 | for (iOffset = 0; iOffset < kNumOffsets; iOffset++) { | |
169 | UChar ubufget[kUBufMax]; | |
170 | int32_t ulenget; | |
171 | ||
172 | if (itemPtr->unit >= UDAT_REL_UNIT_SUNDAY && offsets[iOffset] != -1.0 && offsets[iOffset] != 0.0 && offsets[iOffset] != 1.0) { | |
173 | continue; /* we do not currently have data for this */ | |
174 | } | |
175 | ||
176 | status = U_ZERO_ERROR; | |
177 | ulenget = ureldatefmt_format(reldatefmt, offsets[iOffset], itemPtr->unit, ubufget, kUBufMax, &status); | |
178 | if ( U_FAILURE(status) ) { | |
179 | log_err("FAIL: ureldatefmt_format() for locale %s, decPlaces %d, width %d, capContext %d, offset %.2f, unit %d: %s\n", | |
180 | itemPtr->locale, itemPtr->decPlaces, (int)itemPtr->width, (int)itemPtr->capContext, | |
181 | offsets[iOffset], (int)itemPtr->unit, myErrorName(status) ); | |
182 | } else { | |
183 | UChar ubufexp[kUBufMax]; | |
184 | int32_t ulenexp = u_unescape(itemPtr->expectedResults[iOffset*2], ubufexp, kUBufMax); | |
185 | if (ulenget != ulenexp || u_strncmp(ubufget, ubufexp, ulenexp) != 0) { | |
186 | char bbufget[kBBufMax]; | |
187 | u_austrncpy(bbufget, ubufget, kUBufMax); | |
188 | log_err("ERROR: ureldatefmt_format() for locale %s, decPlaces %d, width %d, capContext %d, offset %.2f, unit %d;\n expected %s\n get %s\n", | |
189 | itemPtr->locale, itemPtr->decPlaces, (int)itemPtr->width, (int)itemPtr->capContext, | |
190 | offsets[iOffset], (int)itemPtr->unit, itemPtr->expectedResults[iOffset*2], bbufget ); | |
191 | } | |
192 | } | |
193 | ||
194 | if (itemPtr->unit >= UDAT_REL_UNIT_SUNDAY) { | |
195 | continue; /* we do not currently have numeric-style data for this */ | |
196 | } | |
197 | ||
198 | status = U_ZERO_ERROR; | |
199 | ulenget = ureldatefmt_formatNumeric(reldatefmt, offsets[iOffset], itemPtr->unit, ubufget, kUBufMax, &status); | |
200 | if ( U_FAILURE(status) ) { | |
201 | log_err("FAIL: ureldatefmt_formatNumeric() for locale %s, decPlaces %d, width %d, capContext %d, offset %.2f, unit %d: %s\n", | |
202 | itemPtr->locale, itemPtr->decPlaces, (int)itemPtr->width, (int)itemPtr->capContext, | |
203 | offsets[iOffset], (int)itemPtr->unit, myErrorName(status) ); | |
204 | } else { | |
205 | UChar ubufexp[kUBufMax]; | |
206 | int32_t ulenexp = u_unescape(itemPtr->expectedResults[iOffset*2 + 1], ubufexp, kUBufMax); | |
207 | if (ulenget != ulenexp || u_strncmp(ubufget, ubufexp, ulenexp) != 0) { | |
208 | char bbufget[kBBufMax]; | |
209 | u_austrncpy(bbufget, ubufget, kUBufMax); | |
210 | log_err("ERROR: ureldatefmt_formatNumeric() for locale %s, decPlaces %d, width %d, capContext %d, offset %.2f, unit %d;\n expected %s\n get %s\n", | |
211 | itemPtr->locale, itemPtr->decPlaces, (int)itemPtr->width, (int)itemPtr->capContext, | |
212 | offsets[iOffset], (int)itemPtr->unit, itemPtr->expectedResults[iOffset*2 + 1], bbufget ); | |
213 | } | |
214 | } | |
215 | } | |
216 | ||
217 | ureldatefmt_close(reldatefmt); | |
218 | } | |
219 | } | |
220 | ||
221 | typedef struct { | |
222 | const char* locale; | |
223 | UDateRelativeDateTimeFormatterStyle width; | |
224 | UDisplayContext capContext; | |
225 | const char * relativeDateString; | |
226 | const char * timeString; | |
227 | const char * expectedResult; | |
228 | } CombineDateTimeTestItem; | |
229 | ||
230 | static const CombineDateTimeTestItem combTestItems[] = { | |
231 | { "en", UDAT_STYLE_LONG, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, "yesterday", "3:45 PM", "yesterday, 3:45 PM" }, | |
232 | { NULL, (UDateRelativeDateTimeFormatterStyle)0, (UDisplayContext)0, NULL, NULL, NULL } /* terminator */ | |
233 | }; | |
234 | ||
235 | static void TestCombineDateTime() | |
236 | { | |
237 | const CombineDateTimeTestItem *itemPtr; | |
238 | log_verbose("\nTesting ureldatefmt_combineDateAndTime() with various parameters\n"); | |
239 | for (itemPtr = combTestItems; itemPtr->locale != NULL; itemPtr++) { | |
240 | URelativeDateTimeFormatter *reldatefmt = NULL; | |
241 | UErrorCode status = U_ZERO_ERROR; | |
242 | UChar ubufreldate[kUBufMax]; | |
243 | UChar ubuftime[kUBufMax]; | |
244 | UChar ubufget[kUBufMax]; | |
245 | int32_t ulenreldate, ulentime, ulenget; | |
246 | ||
247 | reldatefmt = ureldatefmt_open(itemPtr->locale, NULL, itemPtr->width, itemPtr->capContext, &status); | |
248 | if ( U_FAILURE(status) ) { | |
249 | log_data_err("FAIL: ureldatefmt_open() for locale %s, width %d, capContext %d: %s\n", | |
250 | itemPtr->locale, (int)itemPtr->width, (int)itemPtr->capContext, myErrorName(status) ); | |
251 | continue; | |
252 | } | |
253 | ||
254 | ulenreldate = u_unescape(itemPtr->relativeDateString, ubufreldate, kUBufMax); | |
255 | ulentime = u_unescape(itemPtr->timeString, ubuftime, kUBufMax); | |
256 | ulenget = ureldatefmt_combineDateAndTime(reldatefmt, ubufreldate, ulenreldate, ubuftime, ulentime, ubufget, kUBufMax, &status); | |
257 | if ( U_FAILURE(status) ) { | |
258 | log_err("FAIL: ureldatefmt_combineDateAndTime() for locale %s, width %d, capContext %d: %s\n", | |
259 | itemPtr->locale, (int)itemPtr->width, (int)itemPtr->capContext, myErrorName(status) ); | |
260 | } else { | |
261 | UChar ubufexp[kUBufMax]; | |
262 | int32_t ulenexp = u_unescape(itemPtr->expectedResult, ubufexp, kUBufMax); | |
263 | if (ulenget != ulenexp || u_strncmp(ubufget, ubufexp, ulenexp) != 0) { | |
264 | char bbufget[kBBufMax]; | |
265 | u_austrncpy(bbufget, ubufget, kUBufMax); | |
266 | log_err("ERROR: ureldatefmt_combineDateAndTime() for locale %s, width %d, capContext %d;\n expected %s\n get %s\n", | |
267 | itemPtr->locale, (int)itemPtr->width, (int)itemPtr->capContext, itemPtr->expectedResult, bbufget ); | |
268 | } | |
269 | } | |
270 | // preflight test | |
271 | status = U_ZERO_ERROR; | |
272 | ulenget = ureldatefmt_combineDateAndTime(reldatefmt, ubufreldate, ulenreldate, ubuftime, ulentime, NULL, 0, &status); | |
273 | if ( status != U_BUFFER_OVERFLOW_ERROR) { | |
274 | log_err("FAIL: ureldatefmt_combineDateAndTime() preflight for locale %s, width %d, capContext %d: expected U_BUFFER_OVERFLOW_ERROR, got %s\n", | |
275 | itemPtr->locale, (int)itemPtr->width, (int)itemPtr->capContext, myErrorName(status) ); | |
276 | } else { | |
277 | UChar ubufexp[kUBufMax]; | |
278 | int32_t ulenexp = u_unescape(itemPtr->expectedResult, ubufexp, kUBufMax); | |
279 | if (ulenget != ulenexp) { | |
280 | log_err("ERROR: ureldatefmt_combineDateAndTime() preflight for locale %s, width %d, capContext %d;\n expected len %d, get len %d\n", | |
281 | itemPtr->locale, (int)itemPtr->width, (int)itemPtr->capContext, ulenexp, ulenget ); | |
282 | } | |
283 | } | |
284 | ||
285 | ureldatefmt_close(reldatefmt); | |
286 | } | |
287 | } | |
288 | ||
289 | #endif /* #if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_BREAK_ITERATION */ |