]>
Commit | Line | Data |
---|---|---|
1 | // © 2016 and later: Unicode, Inc. and others. | |
2 | // License & terms of use: http://www.unicode.org/copyright.html | |
3 | /*********************************************************************** | |
4 | * COPYRIGHT: | |
5 | * Copyright (c) 1997-2011, International Business Machines Corporation | |
6 | * and others. All Rights Reserved. | |
7 | ***********************************************************************/ | |
8 | ||
9 | #include "unicode/utypes.h" | |
10 | ||
11 | #if !UCONFIG_NO_FORMATTING | |
12 | ||
13 | #include "dtfmapts.h" | |
14 | ||
15 | #include "unicode/datefmt.h" | |
16 | #include "unicode/smpdtfmt.h" | |
17 | #include "unicode/decimfmt.h" | |
18 | #include "unicode/choicfmt.h" | |
19 | #include "unicode/msgfmt.h" | |
20 | ||
21 | ||
22 | // This is an API test, not a unit test. It doesn't test very many cases, and doesn't | |
23 | // try to test the full functionality. It just calls each function in the class and | |
24 | // verifies that it works on a basic level. | |
25 | ||
26 | void IntlTestDateFormatAPI::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ ) | |
27 | { | |
28 | if (exec) logln("TestSuite DateFormatAPI"); | |
29 | switch (index) { | |
30 | case 0: name = "DateFormat API test"; | |
31 | if (exec) { | |
32 | logln("DateFormat API test---"); logln(""); | |
33 | UErrorCode status = U_ZERO_ERROR; | |
34 | Locale saveLocale; | |
35 | Locale::setDefault(Locale::getEnglish(), status); | |
36 | if(U_FAILURE(status)) { | |
37 | errln("ERROR: Could not set default locale, test may not give correct results"); | |
38 | } | |
39 | testAPI(/*par*/); | |
40 | Locale::setDefault(saveLocale, status); | |
41 | } | |
42 | break; | |
43 | ||
44 | case 1: name = "TestEquals"; | |
45 | if (exec) { | |
46 | logln("TestEquals---"); logln(""); | |
47 | TestEquals(); | |
48 | } | |
49 | break; | |
50 | ||
51 | case 2: name = "TestNameHiding"; | |
52 | if (exec) { | |
53 | logln("TestNameHiding---"); logln(""); | |
54 | TestNameHiding(); | |
55 | } | |
56 | break; | |
57 | ||
58 | case 3: name = "TestCoverage"; | |
59 | if (exec) { | |
60 | logln("TestCoverage---"); logln(""); | |
61 | TestCoverage(); | |
62 | } | |
63 | break; | |
64 | ||
65 | default: name = ""; break; | |
66 | } | |
67 | } | |
68 | ||
69 | /** | |
70 | * Add better code coverage. | |
71 | */ | |
72 | void IntlTestDateFormatAPI::TestCoverage(void) | |
73 | { | |
74 | const char *LOCALES[] = { | |
75 | "zh_CN@calendar=chinese", | |
76 | "cop_EG@calendar=coptic", | |
77 | "hi_IN@calendar=indian", | |
78 | "am_ET@calendar=ethiopic" | |
79 | }; | |
80 | int32_t numOfLocales = 4; | |
81 | ||
82 | for (int32_t i = 0; i < numOfLocales; i++) { | |
83 | DateFormat *df = DateFormat::createDateTimeInstance(DateFormat::kMedium, DateFormat::kMedium, Locale(LOCALES[i])); | |
84 | if (df == NULL){ | |
85 | dataerrln("Error creating DateFormat instances."); | |
86 | return; | |
87 | } | |
88 | delete df; | |
89 | } | |
90 | } | |
91 | /** | |
92 | * Test that the equals method works correctly. | |
93 | */ | |
94 | void IntlTestDateFormatAPI::TestEquals(void) | |
95 | { | |
96 | UErrorCode status = U_ZERO_ERROR; | |
97 | // Create two objects at different system times | |
98 | DateFormat *a = DateFormat::createInstance(); | |
99 | UDate start = Calendar::getNow(); | |
100 | while (Calendar::getNow() == start) ; // Wait for time to change | |
101 | DateFormat *b = DateFormat::createInstance(); | |
102 | ||
103 | if (a == NULL || b == NULL){ | |
104 | dataerrln("Error calling DateFormat::createInstance()"); | |
105 | delete a; | |
106 | delete b; | |
107 | return; | |
108 | } | |
109 | ||
110 | if (!(*a == *b)) | |
111 | errln("FAIL: DateFormat objects created at different times are unequal."); | |
112 | ||
113 | SimpleDateFormat *sdtfmt = dynamic_cast<SimpleDateFormat *>(b); | |
114 | if (sdtfmt != NULL) | |
115 | { | |
116 | double ONE_YEAR = 365*24*60*60*1000.0; | |
117 | sdtfmt->set2DigitYearStart(start + 50*ONE_YEAR, status); | |
118 | if (U_FAILURE(status)) | |
119 | errln("FAIL: setTwoDigitStartDate failed."); | |
120 | else if (*a == *b) | |
121 | errln("FAIL: DateFormat objects with different two digit start dates are equal."); | |
122 | } | |
123 | delete a; | |
124 | delete b; | |
125 | } | |
126 | ||
127 | /** | |
128 | * This test checks various generic API methods in DateFormat to achieve 100% | |
129 | * API coverage. | |
130 | */ | |
131 | void IntlTestDateFormatAPI::testAPI(/* char* par */) | |
132 | { | |
133 | UErrorCode status = U_ZERO_ERROR; | |
134 | ||
135 | // ======= Test constructors | |
136 | ||
137 | logln("Testing DateFormat constructors"); | |
138 | ||
139 | DateFormat *def = DateFormat::createInstance(); | |
140 | DateFormat *fr = DateFormat::createTimeInstance(DateFormat::FULL, Locale::getFrench()); | |
141 | DateFormat *it = DateFormat::createDateInstance(DateFormat::MEDIUM, Locale::getItalian()); | |
142 | DateFormat *de = DateFormat::createDateTimeInstance(DateFormat::LONG, DateFormat::LONG, Locale::getGerman()); | |
143 | ||
144 | if (def == NULL || fr == NULL || it == NULL || de == NULL){ | |
145 | dataerrln("Error creating DateFormat instances."); | |
146 | } | |
147 | ||
148 | // ======= Test equality | |
149 | if (fr != NULL && def != NULL) | |
150 | { | |
151 | logln("Testing equality operator"); | |
152 | ||
153 | if( *fr == *it ) { | |
154 | errln("ERROR: == failed"); | |
155 | } | |
156 | } | |
157 | ||
158 | // ======= Test various format() methods | |
159 | if (fr != NULL && it != NULL && de != NULL) | |
160 | { | |
161 | logln("Testing various format() methods"); | |
162 | ||
163 | UDate d = 837039928046.0; | |
164 | Formattable fD(d, Formattable::kIsDate); | |
165 | ||
166 | UnicodeString res1, res2, res3; | |
167 | FieldPosition pos1(FieldPosition::DONT_CARE), pos2(FieldPosition::DONT_CARE); | |
168 | ||
169 | status = U_ZERO_ERROR; | |
170 | res1 = fr->format(d, res1, pos1, status); | |
171 | if(U_FAILURE(status)) { | |
172 | errln("ERROR: format() failed (French)"); | |
173 | } | |
174 | logln( (UnicodeString) "" + d + " formatted to " + res1); | |
175 | ||
176 | res2 = it->format(d, res2, pos2); | |
177 | logln( (UnicodeString) "" + d + " formatted to " + res2); | |
178 | ||
179 | res3 = de->format(d, res3); | |
180 | logln( (UnicodeString) "" + d + " formatted to " + res3); | |
181 | } | |
182 | ||
183 | // ======= Test parse() | |
184 | if (def != NULL) | |
185 | { | |
186 | logln("Testing parse()"); | |
187 | ||
188 | UnicodeString text("02/03/76 2:50 AM, CST"); | |
189 | Formattable result1; | |
190 | UDate result2, result3; | |
191 | ParsePosition pos(0), pos01(0); | |
192 | def->parseObject(text, result1, pos); | |
193 | if(result1.getType() != Formattable::kDate) { | |
194 | errln("ERROR: parseObject() failed for " + text); | |
195 | } | |
196 | logln(text + " parsed into " + result1.getDate()); | |
197 | ||
198 | status = U_ZERO_ERROR; | |
199 | result2 = def->parse(text, status); | |
200 | if(U_FAILURE(status)) { | |
201 | errln("ERROR: parse() failed, stopping testing"); | |
202 | return; | |
203 | } | |
204 | logln(text + " parsed into " + result2); | |
205 | ||
206 | result3 = def->parse(text, pos01); | |
207 | logln(text + " parsed into " + result3); | |
208 | } | |
209 | ||
210 | // ======= Test getters and setters | |
211 | if (fr != NULL && it != NULL && de != NULL) | |
212 | { | |
213 | logln("Testing getters and setters"); | |
214 | ||
215 | int32_t count = 0; | |
216 | const Locale *locales = DateFormat::getAvailableLocales(count); | |
217 | logln((UnicodeString) "Got " + count + " locales" ); | |
218 | for(int32_t i = 0; i < count; i++) { | |
219 | UnicodeString name; | |
220 | name = locales[i].getName(); | |
221 | logln(name); | |
222 | } | |
223 | ||
224 | fr->setLenient(it->isLenient()); | |
225 | if(fr->isLenient() != it->isLenient()) { | |
226 | errln("ERROR: setLenient() failed"); | |
227 | } | |
228 | ||
229 | const Calendar *cal = def->getCalendar(); | |
230 | Calendar *newCal = cal->clone(); | |
231 | de->adoptCalendar(newCal); | |
232 | it->setCalendar(*newCal); | |
233 | if( *(de->getCalendar()) != *(it->getCalendar())) { | |
234 | errln("ERROR: adopt or set Calendar() failed"); | |
235 | } | |
236 | ||
237 | const NumberFormat *nf = def->getNumberFormat(); | |
238 | NumberFormat *newNf = nf->clone(); | |
239 | de->adoptNumberFormat(newNf); | |
240 | it->setNumberFormat(*newNf); | |
241 | if( *(de->getNumberFormat()) != *(it->getNumberFormat())) { | |
242 | errln("ERROR: adopt or set NumberFormat() failed"); | |
243 | } | |
244 | ||
245 | const TimeZone& tz = def->getTimeZone(); | |
246 | TimeZone *newTz = tz.clone(); | |
247 | de->adoptTimeZone(newTz); | |
248 | it->setTimeZone(*newTz); | |
249 | if( de->getTimeZone() != it->getTimeZone()) { | |
250 | errln("ERROR: adopt or set TimeZone() failed"); | |
251 | } | |
252 | } | |
253 | // ======= Test getStaticClassID() | |
254 | ||
255 | logln("Testing getStaticClassID()"); | |
256 | ||
257 | status = U_ZERO_ERROR; | |
258 | DateFormat *test = new SimpleDateFormat(status); | |
259 | if(U_FAILURE(status)) { | |
260 | dataerrln("ERROR: Couldn't create a DateFormat - %s", u_errorName(status)); | |
261 | } | |
262 | ||
263 | if(test->getDynamicClassID() != SimpleDateFormat::getStaticClassID()) { | |
264 | errln("ERROR: getDynamicClassID() didn't return the expected value"); | |
265 | } | |
266 | ||
267 | delete test; | |
268 | delete def; | |
269 | delete fr; | |
270 | delete it; | |
271 | delete de; | |
272 | } | |
273 | ||
274 | /** | |
275 | * Test hiding of parse() and format() APIs in the Format hierarchy. | |
276 | * We test the entire hierarchy, even though this test is located in | |
277 | * the DateFormat API test. | |
278 | */ | |
279 | void | |
280 | IntlTestDateFormatAPI::TestNameHiding(void) { | |
281 | ||
282 | // N.B.: This test passes if it COMPILES, since it's a test of | |
283 | // compile-time name hiding. | |
284 | ||
285 | UErrorCode status = U_ZERO_ERROR; | |
286 | Formattable dateObj(0, Formattable::kIsDate); | |
287 | Formattable numObj(3.1415926535897932384626433832795); | |
288 | Formattable obj; | |
289 | UnicodeString str; | |
290 | FieldPosition fpos; | |
291 | ParsePosition ppos; | |
292 | ||
293 | // DateFormat calling Format API | |
294 | { | |
295 | logln("DateFormat"); | |
296 | DateFormat *dateFmt = DateFormat::createInstance(); | |
297 | if (dateFmt) { | |
298 | dateFmt->format(dateObj, str, status); | |
299 | dateFmt->format(dateObj, str, fpos, status); | |
300 | delete dateFmt; | |
301 | } else { | |
302 | dataerrln("FAIL: Can't create DateFormat"); | |
303 | } | |
304 | } | |
305 | ||
306 | // SimpleDateFormat calling Format & DateFormat API | |
307 | { | |
308 | logln("SimpleDateFormat"); | |
309 | status = U_ZERO_ERROR; | |
310 | SimpleDateFormat sdf(status); | |
311 | if (U_SUCCESS(status)) { | |
312 | // Format API | |
313 | sdf.format(dateObj, str, status); | |
314 | sdf.format(dateObj, str, fpos, status); | |
315 | // DateFormat API | |
316 | sdf.format((UDate)0, str, fpos); | |
317 | sdf.format((UDate)0, str); | |
318 | sdf.parse(str, status); | |
319 | sdf.parse(str, ppos); | |
320 | sdf.getNumberFormat(); | |
321 | } else { | |
322 | dataerrln("FAIL: Can't create SimpleDateFormat() - %s", u_errorName(status)); | |
323 | } | |
324 | } | |
325 | ||
326 | // NumberFormat calling Format API | |
327 | { | |
328 | logln("NumberFormat"); | |
329 | status = U_ZERO_ERROR; | |
330 | NumberFormat *fmt = NumberFormat::createInstance(status); | |
331 | if (fmt) { | |
332 | fmt->format(numObj, str, status); | |
333 | fmt->format(numObj, str, fpos, status); | |
334 | delete fmt; | |
335 | } else { | |
336 | dataerrln("FAIL: Can't create NumberFormat()"); | |
337 | } | |
338 | } | |
339 | ||
340 | // DecimalFormat calling Format & NumberFormat API | |
341 | { | |
342 | logln("DecimalFormat"); | |
343 | status = U_ZERO_ERROR; | |
344 | DecimalFormat fmt(status); | |
345 | if(U_SUCCESS(status)) { | |
346 | // Format API | |
347 | fmt.format(numObj, str, status); | |
348 | fmt.format(numObj, str, fpos, status); | |
349 | // NumberFormat API | |
350 | fmt.format(2.71828, str); | |
351 | fmt.format((int32_t)1234567, str); | |
352 | fmt.format(1.41421, str, fpos); | |
353 | fmt.format((int32_t)9876543, str, fpos); | |
354 | fmt.parse(str, obj, ppos); | |
355 | fmt.parse(str, obj, status); | |
356 | } else { | |
357 | errcheckln(status, "FAIL: Couldn't instantiate DecimalFormat, error %s. Quitting test", u_errorName(status)); | |
358 | } | |
359 | } | |
360 | ||
361 | // ChoiceFormat calling Format & NumberFormat API | |
362 | { | |
363 | logln("ChoiceFormat"); | |
364 | status = U_ZERO_ERROR; | |
365 | ChoiceFormat fmt("0#foo|1#foos|2#foos", status); | |
366 | // Format API | |
367 | fmt.format(numObj, str, status); | |
368 | fmt.format(numObj, str, fpos, status); | |
369 | // NumberFormat API | |
370 | fmt.format(2.71828, str); | |
371 | fmt.format((int32_t)1234567, str); | |
372 | fmt.format(1.41421, str, fpos); | |
373 | fmt.format((int32_t)9876543, str, fpos); | |
374 | fmt.parse(str, obj, ppos); | |
375 | fmt.parse(str, obj, status); | |
376 | } | |
377 | ||
378 | // MessageFormat calling Format API | |
379 | { | |
380 | logln("MessageFormat"); | |
381 | status = U_ZERO_ERROR; | |
382 | MessageFormat fmt("", status); | |
383 | // Format API | |
384 | // We use dateObj, which MessageFormat should reject. | |
385 | // We're testing name hiding, not the format method. | |
386 | fmt.format(dateObj, str, status); | |
387 | fmt.format(dateObj, str, fpos, status); | |
388 | } | |
389 | } | |
390 | ||
391 | #endif /* #if !UCONFIG_NO_FORMATTING */ |