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-2010, International Business Machines Corporation and 6 * others. All Rights Reserved. 7 ********************************************************************/ 8 9/*********************************************************************** 10 * Modification history 11 * Date Name Description 12 * 07/09/2007 srl Copied from dadrcoll.cpp 13 ***********************************************************************/ 14 15#include "unicode/utypes.h" 16 17#if !UCONFIG_NO_FORMATTING 18 19#include "unicode/tstdtmod.h" 20#include "tsdate.h" 21#include "dadrcal.h" 22#include "unicode/calendar.h" 23#include "intltest.h" 24#include <string.h> 25#include "unicode/schriter.h" 26#include "unicode/regex.h" 27#include "unicode/smpdtfmt.h" 28#include "dbgutil.h" 29 30#include <stdio.h> 31 32DataDrivenCalendarTest::DataDrivenCalendarTest() { 33 UErrorCode status = U_ZERO_ERROR; 34 driver = TestDataModule::getTestDataModule("calendar", *this, status); 35} 36 37DataDrivenCalendarTest::~DataDrivenCalendarTest() { 38 delete driver; 39} 40 41void DataDrivenCalendarTest::runIndexedTest(int32_t index, UBool exec, 42 const char* &name, char* /*par */) { 43 if (driver != NULL) { 44 if (exec) { 45 // logln("Begin "); 46 } 47 const DataMap *info= NULL; 48 UErrorCode status= U_ZERO_ERROR; 49 TestData *testData = driver->createTestData(index, status); 50 if (U_SUCCESS(status)) { 51 name = testData->getName(); 52 if (testData->getInfo(info, status)) { 53 log(info->getString("Description", status)); 54 } 55 if (exec) { 56 log(name); 57 logln("---"); 58 logln(""); 59 60 processTest(testData); 61 } 62 delete testData; 63 } else { 64 name = ""; 65 } 66 } else { 67 dataerrln("format/DataDriven*Test data (calendar.res) not initialized!"); 68 name = ""; 69 } 70 71} 72 73void DataDrivenCalendarTest::testOps(TestData *testData, 74 const DataMap * /*settings*/) { 75 UErrorCode status = U_ZERO_ERROR; 76 UBool useDate = FALSE; // TODO 77 UnicodeString kMILLIS("MILLIS="); // TODO: static 78 UDate fromDate = 0; // TODO 79 UDate toDate = 0; 80 81 const DataMap *currentCase= NULL; 82 char toCalLoc[256] = ""; 83 84 // TODO: static strings? 85 const UnicodeString kADD("add", ""); 86 const UnicodeString kROLL("roll", ""); 87 88 // Get 'from' time 89 CalendarFieldsSet fromSet, toSet, paramsSet, diffSet; 90 SimpleDateFormat fmt(UnicodeString("EEE MMM dd yyyy / YYYY'-W'ww-ee"), 91 status); 92 if (U_FAILURE(status)) { 93 dataerrln("FAIL: Couldn't create SimpleDateFormat: %s", 94 u_errorName(status)); 95 return; 96 } 97 // Start the processing 98 int n = 0; 99 while (testData->nextCase(currentCase, status)) { 100 ++n; 101 Calendar *toCalendar= NULL; 102 Calendar *fromCalendar= NULL; 103 104 // load parameters 105 char theCase[200]; 106 sprintf(theCase, "[case %d]", n); 107 UnicodeString caseString(theCase, ""); 108 // build to calendar 109 // Headers { "locale","from","operation","params","to" } 110 // #1 locale 111 const char *param = "locale"; 112 UnicodeString locale; 113 UnicodeString testSetting = currentCase->getString(param, status); 114 if (U_FAILURE(status)) { 115 errln(caseString+": Unable to get param '"+param+"' " 116 + UnicodeString(" - ")); 117 continue; 118 } 119 testSetting.extract(0, testSetting.length(), toCalLoc, (const char*)0); 120 fromCalendar = Calendar::createInstance(toCalLoc, status); 121 if (U_FAILURE(status)) { 122 errln(caseString+": Unable to instantiate calendar for " 123 +testSetting); 124 continue; 125 } 126 127 fromSet.clear(); 128 // #2 'from' info 129 param = "from"; 130 UnicodeString from = testSetting=currentCase->getString(param, status); 131 if (U_FAILURE(status)) { 132 errln(caseString+": Unable to get parameter '"+param+"' " 133 + UnicodeString(" - ")); 134 continue; 135 } 136 137 if(from.startsWith(kMILLIS)){ 138 UnicodeString millis = UnicodeString(from, kMILLIS.length()); 139 useDate = TRUE; 140 fromDate = udbg_stod(millis); 141 } else if(fromSet.parseFrom(testSetting, status)<0 || U_FAILURE(status)){ 142 errln(caseString+": Failed to parse '"+param+"' parameter: " 143 +testSetting); 144 continue; 145 } 146 147 // #4 'operation' info 148 param = "operation"; 149 UnicodeString operation = testSetting=currentCase->getString(param, 150 status); 151 if (U_FAILURE(status)) { 152 errln(caseString+": Unable to get parameter '"+param+"' " 153 + UnicodeString(" - ")); 154 continue; 155 } 156 if (U_FAILURE(status)) { 157 errln(caseString+": Failed to parse '"+param+"' parameter: " 158 +testSetting); 159 continue; 160 } 161 162 paramsSet.clear(); 163 // #3 'params' info 164 param = "params"; 165 UnicodeString params = testSetting 166 =currentCase->getString(param, status); 167 if (U_FAILURE(status)) { 168 errln(caseString+": Unable to get parameter '"+param+"' " 169 + UnicodeString(" - ")); 170 continue; 171 } 172 paramsSet.parseFrom(testSetting, status); // parse with inheritance. 173 if (U_FAILURE(status)) { 174 errln(caseString+": Failed to parse '"+param+"' parameter: " 175 +testSetting); 176 continue; 177 } 178 179 toSet.clear(); 180 // #4 'to' info 181 param = "to"; 182 UnicodeString to = testSetting=currentCase->getString(param, status); 183 if (U_FAILURE(status)) { 184 errln(caseString+": Unable to get parameter '"+param+"' " 185 + UnicodeString(" - ")); 186 continue; 187 } 188 if(to.startsWith(kMILLIS)){ 189 UnicodeString millis = UnicodeString(to, kMILLIS.length()); 190 useDate = TRUE; 191 toDate = udbg_stod(millis); 192 } else if(toSet.parseFrom(testSetting, &fromSet, status)<0 || U_FAILURE(status)){ 193 errln(caseString+": Failed to parse '"+param+"' parameter: " 194 +testSetting); 195 continue; 196 } 197 198 UnicodeString caseContentsString = locale+": from "+from+": " 199 +operation +" [[[ "+params+" ]]] >>> "+to; 200 logln(caseString+": "+caseContentsString); 201 202 // ------ 203 // now, do it. 204 205 /// prepare calendar 206 if(useDate){ 207 fromCalendar->setTime(fromDate, status); 208 if (U_FAILURE(status)) { 209 errln(caseString+" FAIL: Failed to set time on Source calendar: " 210 + u_errorName(status)); 211 return; 212 } 213 } else { 214 fromSet.setOnCalendar(fromCalendar, status); 215 if (U_FAILURE(status)) { 216 errln(caseString+" FAIL: Failed to set on Source calendar: " 217 + u_errorName(status)); 218 return; 219 } 220 } 221 222 diffSet.clear(); 223 // Is the calendar sane after being set? 224 if (!fromSet.matches(fromCalendar, diffSet, status)) { 225 UnicodeString diffs = diffSet.diffFrom(fromSet, status); 226 errln((UnicodeString)"FAIL: "+caseString 227 +", SET SOURCE calendar was not set: Differences: "+ diffs 228 +"', status: "+ u_errorName(status)); 229 } else if (U_FAILURE(status)) { 230 errln("FAIL: "+caseString+" SET SOURCE calendar Failed to match: " 231 +u_errorName(status)); 232 } else { 233 logln("PASS: "+caseString+" SET SOURCE calendar match."); 234 } 235 236 // to calendar - copy of from calendar 237 toCalendar = fromCalendar->clone(); 238 239 /// perform op 240 for (int q=0; q<UCAL_FIELD_COUNT; q++) { 241 if (paramsSet.isSet((UCalendarDateFields)q)) { 242 if (operation == kROLL) { 243 toCalendar->roll((UCalendarDateFields)q, 244 paramsSet.get((UCalendarDateFields)q), status); 245 } else if (operation == kADD) { 246 toCalendar->add((UCalendarDateFields)q, 247 paramsSet.get((UCalendarDateFields)q), status); 248 } else { 249 errln(caseString+ " FAIL: unknown operation "+ operation); 250 } 251 logln(operation + " of "+ paramsSet.get((UCalendarDateFields)q) 252 +" -> "+u_errorName(status)); 253 } 254 } 255 if (U_FAILURE(status)) { 256 errln(caseString+" FAIL: after "+operation+" of "+params+" -> " 257 +u_errorName(status)); 258 continue; 259 } 260 261 // now - what's the result? 262 diffSet.clear(); 263 264 if(useDate){ 265 if(!(toCalendar->getTime(status)==toDate) || U_FAILURE(status)){ 266 errln("FAIL: "+caseString+" Match operation had an error: " 267 +u_errorName(status)); 268 }else{ 269 logln(caseString + " SUCCESS: got=expected="+toDate); 270 logln("PASS: "+caseString+" matched!"); 271 } 272 } else if (!toSet.matches(toCalendar, diffSet, status)) { 273 UnicodeString diffs = diffSet.diffFrom(toSet, status); 274 errln((UnicodeString)"FAIL: "+caseString+" - , "+caseContentsString 275 +" Differences: "+ diffs +"', status: " 276 + u_errorName(status)); 277 }else if (U_FAILURE(status)) { 278 errln("FAIL: "+caseString+" Match operation had an error: " 279 +u_errorName(status)); 280 }else { 281 logln("PASS: "+caseString+" matched!"); 282 } 283 284 delete fromCalendar; 285 delete toCalendar; 286 } 287} 288 289void DataDrivenCalendarTest::testConvert(int32_t n, 290 const CalendarFieldsSet &fromSet, Calendar *fromCalendar, 291 const CalendarFieldsSet &toSet, Calendar *toCalendar, UBool forward) { 292 UErrorCode status = U_ZERO_ERROR; 293 UnicodeString thisString = (UnicodeString)"#"+n+" "+(forward ? "forward" 294 : "reverse")+" "+fromCalendar->getType()+"->"+toCalendar->getType(); 295 296 fromCalendar->clear(); 297 298 fromSet.setOnCalendar(fromCalendar, status); 299 if (U_FAILURE(status)) { 300 errln("FAIL: Failed to set on Source calendar: %s", u_errorName(status)); 301 return; 302 } 303 304 CalendarFieldsSet diffSet; 305 306 diffSet.clear(); 307 // Is the calendar sane at the first? 308 if (!fromSet.matches(fromCalendar, diffSet, status)) { 309 UnicodeString diffs = diffSet.diffFrom(fromSet, status); 310 errln((UnicodeString)"FAIL: "+thisString 311 +", SOURCE calendar was not set: Differences: "+ diffs 312 +"', status: "+ u_errorName(status)); 313 } else if (U_FAILURE(status)) { 314 errln("FAIL: "+thisString+" SOURCE calendar Failed to match: " 315 +u_errorName(status)); 316 } else { 317 logln("PASS: "+thisString+" SOURCE calendar match."); 318 } 319 320 //logln("Set Source calendar: " + from); 321 322 UDate fromTime = fromCalendar->getTime(status); 323 if (U_FAILURE(status)) { 324 errln("FAIL: Failed to get Source time: %s", u_errorName(status)); 325 return; 326 } 327 328 diffSet.clear(); 329 // Is the calendar sane after being set? 330 if (!fromSet.matches(fromCalendar, diffSet, status)) { 331 UnicodeString diffs = diffSet.diffFrom(fromSet, status); 332 errln((UnicodeString)"FAIL: "+thisString 333 +", SET SOURCE calendar was not set: Differences: "+ diffs 334 +"', status: "+ u_errorName(status)); 335 } else if (U_FAILURE(status)) { 336 errln("FAIL: "+thisString+" SET SOURCE calendar Failed to match: " 337 +u_errorName(status)); 338 } else { 339 logln("PASS: "+thisString+" SET SOURCE calendar match."); 340 } 341 342 toCalendar->clear(); 343 toCalendar->setTime(fromTime, status); 344 if (U_FAILURE(status)) { 345 errln("FAIL: Failed to set Target time: %s", u_errorName(status)); 346 return; 347 } 348 349 diffSet.clear(); 350 if (!toSet.matches(toCalendar, diffSet, status)) { 351 UnicodeString diffs = diffSet.diffFrom(toSet, status); 352 errln((UnicodeString)"FAIL: "+thisString+", Differences: "+ diffs 353 +"', status: "+ u_errorName(status)); 354 SimpleDateFormat fmt(UnicodeString("EEE MMM dd yyyy G"), status); 355 UnicodeString fromString; 356 fmt.format(fromTime, fromString); 357 logln("Source Time: "+fromString+", Source Calendar: " 358 +fromCalendar->getType()); 359 } else if (U_FAILURE(status)) { 360 errln("FAIL: "+thisString+" Failed to match: "+u_errorName(status)); 361 } else { 362 logln("PASS: "+thisString+" match."); 363 } 364} 365 366void DataDrivenCalendarTest::testConvert(TestData *testData, 367 const DataMap *settings, UBool forward) { 368 UErrorCode status = U_ZERO_ERROR; 369 Calendar *toCalendar= NULL; 370 const DataMap *currentCase= NULL; 371 char toCalLoc[256] = ""; 372 char fromCalLoc[256] = ""; 373 // build to calendar 374 UnicodeString testSetting = settings->getString("ToCalendar", status); 375 if (U_SUCCESS(status)) { 376 testSetting.extract(0, testSetting.length(), toCalLoc, (const char*)0); 377 toCalendar = Calendar::createInstance(toCalLoc, status); 378 if (U_FAILURE(status)) { 379 dataerrln(UnicodeString("Unable to instantiate ToCalendar for ")+testSetting); 380 return; 381 } 382 } 383 384 CalendarFieldsSet fromSet, toSet, diffSet; 385 SimpleDateFormat fmt(UnicodeString("EEE MMM dd yyyy / YYYY'-W'ww-ee"), 386 status); 387 if (U_FAILURE(status)) { 388 errcheckln(status, "FAIL: Couldn't create SimpleDateFormat: %s", 389 u_errorName(status)); 390 return; 391 } 392 // Start the processing 393 int n = 0; 394 while (testData->nextCase(currentCase, status)) { 395 ++n; 396 Calendar *fromCalendar= NULL; 397 UnicodeString locale = currentCase->getString("locale", status); 398 if (U_SUCCESS(status)) { 399 locale.extract(0, locale.length(), fromCalLoc, (const char*)0); // default codepage. Invariant codepage doesn't have '@'! 400 fromCalendar = Calendar::createInstance(fromCalLoc, status); 401 if (U_FAILURE(status)) { 402 errln("Unable to instantiate fromCalendar for "+locale); 403 return; 404 } 405 } else { 406 errln("No 'locale' line."); 407 continue; 408 } 409 410 fromSet.clear(); 411 toSet.clear(); 412 413 UnicodeString from = currentCase->getString("from", status); 414 if (U_FAILURE(status)) { 415 errln("No 'from' line."); 416 continue; 417 } 418 fromSet.parseFrom(from, status); 419 if (U_FAILURE(status)) { 420 errln("Failed to parse 'from' parameter: "+from); 421 continue; 422 } 423 UnicodeString to = currentCase->getString("to", status); 424 if (U_FAILURE(status)) { 425 errln("No 'to' line."); 426 continue; 427 } 428 toSet.parseFrom(to, &fromSet, status); 429 if (U_FAILURE(status)) { 430 errln("Failed to parse 'to' parameter: "+to); 431 continue; 432 } 433 434 // now, do it. 435 if (forward) { 436 logln((UnicodeString)"#"+n+" "+locale+"/"+from+" >>> "+toCalLoc+"/" 437 +to); 438 testConvert(n, fromSet, fromCalendar, toSet, toCalendar, forward); 439 } else { 440 logln((UnicodeString)"#"+n+" "+locale+"/"+from+" <<< "+toCalLoc+"/" 441 +to); 442 testConvert(n, toSet, toCalendar, fromSet, fromCalendar, forward); 443 } 444 445 delete fromCalendar; 446 } 447 delete toCalendar; 448} 449 450void DataDrivenCalendarTest::processTest(TestData *testData) { 451 //Calendar *cal= NULL; 452 //const UChar *arguments= NULL; 453 //int32_t argLen = 0; 454 char testType[256]; 455 const DataMap *settings= NULL; 456 //const UChar *type= NULL; 457 UErrorCode status = U_ZERO_ERROR; 458 UnicodeString testSetting; 459 int n = 0; 460 while (testData->nextSettings(settings, status)) { 461 status = U_ZERO_ERROR; 462 // try to get a locale 463 testSetting = settings->getString("Type", status); 464 if (U_SUCCESS(status)) { 465 if ((++n)>0) { 466 logln("---"); 467 } 468 logln(testSetting + "---"); 469 testSetting.extract(0, testSetting.length(), testType, ""); 470 } else { 471 errln("Unable to extract 'Type'. Skipping.."); 472 continue; 473 } 474 475 if (!strcmp(testType, "convert_fwd")) { 476 testConvert(testData, settings, true); 477 } else if (!strcmp(testType, "convert_rev")) { 478 testConvert(testData, settings, false); 479 } else if (!strcmp(testType, "ops")) { 480 testOps(testData, settings); 481 } else { 482 errln("Unknown type: %s", testType); 483 } 484 } 485} 486 487#endif 488