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