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