• 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  * 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 
runIndexedTest(int32_t index,UBool exec,const char * & name,char *)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  */
TestCoverage(void)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  */
TestEquals(void)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  */
testAPI()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
TestNameHiding(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 */
392