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 24 void 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 */ 70 void 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 */ 92 void 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 SimpleDateFormat *sdtfmt = dynamic_cast<SimpleDateFormat *>(b); 112 if (sdtfmt != NULL) 113 { 114 double ONE_YEAR = 365*24*60*60*1000.0; 115 sdtfmt->set2DigitYearStart(start + 50*ONE_YEAR, status); 116 if (U_FAILURE(status)) 117 errln("FAIL: setTwoDigitStartDate failed."); 118 else if (*a == *b) 119 errln("FAIL: DateFormat objects with different two digit start dates are equal."); 120 } 121 delete a; 122 delete b; 123 } 124 125 /** 126 * This test checks various generic API methods in DateFormat to achieve 100% 127 * API coverage. 128 */ 129 void IntlTestDateFormatAPI::testAPI(/* char* par */) 130 { 131 UErrorCode status = U_ZERO_ERROR; 132 133 // ======= Test constructors 134 135 logln("Testing DateFormat constructors"); 136 137 DateFormat *def = DateFormat::createInstance(); 138 DateFormat *fr = DateFormat::createTimeInstance(DateFormat::FULL, Locale::getFrench()); 139 DateFormat *it = DateFormat::createDateInstance(DateFormat::MEDIUM, Locale::getItalian()); 140 DateFormat *de = DateFormat::createDateTimeInstance(DateFormat::LONG, DateFormat::LONG, Locale::getGerman()); 141 142 if (def == NULL || fr == NULL || it == NULL || de == NULL){ 143 dataerrln("Error creating DateFormat instances."); 144 } 145 146 // ======= Test equality 147 if (fr != NULL && def != NULL) 148 { 149 logln("Testing equality operator"); 150 151 if( *fr == *it ) { 152 errln("ERROR: == failed"); 153 } 154 } 155 156 // ======= Test various format() methods 157 if (fr != NULL && it != NULL && de != NULL) 158 { 159 logln("Testing various format() methods"); 160 161 UDate d = 837039928046.0; 162 Formattable fD(d, Formattable::kIsDate); 163 164 UnicodeString res1, res2, res3; 165 FieldPosition pos1(0), pos2(0); 166 167 status = U_ZERO_ERROR; 168 res1 = fr->format(d, res1, pos1, status); 169 if(U_FAILURE(status)) { 170 errln("ERROR: format() failed (French)"); 171 } 172 logln( (UnicodeString) "" + d + " formatted to " + res1); 173 174 res2 = it->format(d, res2, pos2); 175 logln( (UnicodeString) "" + d + " formatted to " + res2); 176 177 res3 = de->format(d, res3); 178 logln( (UnicodeString) "" + d + " formatted to " + res3); 179 } 180 181 // ======= Test parse() 182 if (def != NULL) 183 { 184 logln("Testing parse()"); 185 186 UnicodeString text("02/03/76 2:50 AM, CST"); 187 Formattable result1; 188 UDate result2, result3; 189 ParsePosition pos(0), pos01(0); 190 def->parseObject(text, result1, pos); 191 if(result1.getType() != Formattable::kDate) { 192 errln("ERROR: parseObject() failed for " + text); 193 } 194 logln(text + " parsed into " + result1.getDate()); 195 196 status = U_ZERO_ERROR; 197 result2 = def->parse(text, status); 198 if(U_FAILURE(status)) { 199 errln("ERROR: parse() failed, stopping testing"); 200 return; 201 } 202 logln(text + " parsed into " + result2); 203 204 result3 = def->parse(text, pos01); 205 logln(text + " parsed into " + result3); 206 } 207 208 // ======= Test getters and setters 209 if (fr != NULL && it != NULL && de != NULL) 210 { 211 logln("Testing getters and setters"); 212 213 int32_t count = 0; 214 const Locale *locales = DateFormat::getAvailableLocales(count); 215 logln((UnicodeString) "Got " + count + " locales" ); 216 for(int32_t i = 0; i < count; i++) { 217 UnicodeString name; 218 name = locales[i].getName(); 219 logln(name); 220 } 221 222 fr->setLenient(it->isLenient()); 223 if(fr->isLenient() != it->isLenient()) { 224 errln("ERROR: setLenient() failed"); 225 } 226 227 const Calendar *cal = def->getCalendar(); 228 Calendar *newCal = cal->clone(); 229 de->adoptCalendar(newCal); 230 it->setCalendar(*newCal); 231 if( *(de->getCalendar()) != *(it->getCalendar())) { 232 errln("ERROR: adopt or set Calendar() failed"); 233 } 234 235 const NumberFormat *nf = def->getNumberFormat(); 236 NumberFormat *newNf = (NumberFormat*) nf->clone(); 237 de->adoptNumberFormat(newNf); 238 it->setNumberFormat(*newNf); 239 if( *(de->getNumberFormat()) != *(it->getNumberFormat())) { 240 errln("ERROR: adopt or set NumberFormat() failed"); 241 } 242 243 const TimeZone& tz = def->getTimeZone(); 244 TimeZone *newTz = tz.clone(); 245 de->adoptTimeZone(newTz); 246 it->setTimeZone(*newTz); 247 if( de->getTimeZone() != it->getTimeZone()) { 248 errln("ERROR: adopt or set TimeZone() failed"); 249 } 250 } 251 // ======= Test getStaticClassID() 252 253 logln("Testing getStaticClassID()"); 254 255 status = U_ZERO_ERROR; 256 DateFormat *test = new SimpleDateFormat(status); 257 if(U_FAILURE(status)) { 258 dataerrln("ERROR: Couldn't create a DateFormat - %s", u_errorName(status)); 259 } 260 261 if(test->getDynamicClassID() != SimpleDateFormat::getStaticClassID()) { 262 errln("ERROR: getDynamicClassID() didn't return the expected value"); 263 } 264 265 delete test; 266 delete def; 267 delete fr; 268 delete it; 269 delete de; 270 } 271 272 /** 273 * Test hiding of parse() and format() APIs in the Format hierarchy. 274 * We test the entire hierarchy, even though this test is located in 275 * the DateFormat API test. 276 */ 277 void 278 IntlTestDateFormatAPI::TestNameHiding(void) { 279 280 // N.B.: This test passes if it COMPILES, since it's a test of 281 // compile-time name hiding. 282 283 UErrorCode status = U_ZERO_ERROR; 284 Formattable dateObj(0, Formattable::kIsDate); 285 Formattable numObj(3.1415926535897932384626433832795); 286 Formattable obj; 287 UnicodeString str; 288 FieldPosition fpos; 289 ParsePosition ppos; 290 291 // DateFormat calling Format API 292 { 293 logln("DateFormat"); 294 DateFormat *dateFmt = DateFormat::createInstance(); 295 if (dateFmt) { 296 dateFmt->format(dateObj, str, status); 297 dateFmt->format(dateObj, str, fpos, status); 298 delete dateFmt; 299 } else { 300 dataerrln("FAIL: Can't create DateFormat"); 301 } 302 } 303 304 // SimpleDateFormat calling Format & DateFormat API 305 { 306 logln("SimpleDateFormat"); 307 status = U_ZERO_ERROR; 308 SimpleDateFormat sdf(status); 309 // Format API 310 sdf.format(dateObj, str, status); 311 sdf.format(dateObj, str, fpos, status); 312 // DateFormat API 313 sdf.format((UDate)0, str, fpos); 314 sdf.format((UDate)0, str); 315 sdf.parse(str, status); 316 sdf.parse(str, ppos); 317 sdf.getNumberFormat(); 318 } 319 320 // NumberFormat calling Format API 321 { 322 logln("NumberFormat"); 323 status = U_ZERO_ERROR; 324 NumberFormat *fmt = NumberFormat::createInstance(status); 325 if (fmt) { 326 fmt->format(numObj, str, status); 327 fmt->format(numObj, str, fpos, status); 328 delete fmt; 329 } else { 330 dataerrln("FAIL: Can't create NumberFormat()"); 331 } 332 } 333 334 // DecimalFormat calling Format & NumberFormat API 335 { 336 logln("DecimalFormat"); 337 status = U_ZERO_ERROR; 338 DecimalFormat fmt(status); 339 if(U_SUCCESS(status)) { 340 // Format API 341 fmt.format(numObj, str, status); 342 fmt.format(numObj, str, fpos, status); 343 // NumberFormat API 344 fmt.format(2.71828, str); 345 fmt.format((int32_t)1234567, str); 346 fmt.format(1.41421, str, fpos); 347 fmt.format((int32_t)9876543, str, fpos); 348 fmt.parse(str, obj, ppos); 349 fmt.parse(str, obj, status); 350 } else { 351 errcheckln(status, "FAIL: Couldn't instantiate DecimalFormat, error %s. Quitting test", u_errorName(status)); 352 } 353 } 354 355 // ChoiceFormat calling Format & NumberFormat API 356 { 357 logln("ChoiceFormat"); 358 status = U_ZERO_ERROR; 359 ChoiceFormat fmt("0#foo|1#foos|2#foos", status); 360 // Format API 361 fmt.format(numObj, str, status); 362 fmt.format(numObj, str, fpos, status); 363 // NumberFormat API 364 fmt.format(2.71828, str); 365 fmt.format((int32_t)1234567, str); 366 fmt.format(1.41421, str, fpos); 367 fmt.format((int32_t)9876543, str, fpos); 368 fmt.parse(str, obj, ppos); 369 fmt.parse(str, obj, status); 370 } 371 372 // MessageFormat calling Format API 373 { 374 logln("MessageFormat"); 375 status = U_ZERO_ERROR; 376 MessageFormat fmt("", status); 377 // Format API 378 // We use dateObj, which MessageFormat should reject. 379 // We're testing name hiding, not the format method. 380 fmt.format(dateObj, str, status); 381 fmt.format(dateObj, str, fpos, status); 382 } 383 } 384 385 #endif /* #if !UCONFIG_NO_FORMATTING */ 386