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