• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
DataDrivenCalendarTest()32 DataDrivenCalendarTest::DataDrivenCalendarTest() {
33     UErrorCode status = U_ZERO_ERROR;
34     driver = TestDataModule::getTestDataModule("calendar", *this, status);
35 }
36 
~DataDrivenCalendarTest()37 DataDrivenCalendarTest::~DataDrivenCalendarTest() {
38     delete driver;
39 }
40 
runIndexedTest(int32_t index,UBool exec,const char * & name,char *)41 void 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 
testOps(TestData * testData,const DataMap *)73 void 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 
testConvert(int32_t n,const CalendarFieldsSet & fromSet,Calendar * fromCalendar,const CalendarFieldsSet & toSet,Calendar * toCalendar,UBool forward)289 void 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 
testConvert(TestData * testData,const DataMap * settings,UBool forward)366 void DataDrivenCalendarTest::testConvert(TestData *testData,
367         const DataMap *settings, UBool forward) {
368     UErrorCode status = U_ZERO_ERROR;
369     LocalPointer<Calendar> toCalendar;
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.adoptInstead(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         LocalPointer<Calendar> fromCalendar;
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.adoptInstead(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.getAlias(), toSet, toCalendar.getAlias(), forward);
439         } else {
440             logln((UnicodeString)"#"+n+" "+locale+"/"+from+" <<< "+toCalLoc+"/"
441                     +to);
442             testConvert(n, toSet, toCalendar.getAlias(), fromSet, fromCalendar.getAlias(), forward);
443         }
444     }
445 }
446 
processTest(TestData * testData)447 void DataDrivenCalendarTest::processTest(TestData *testData) {
448     //Calendar *cal= NULL;
449     //const UChar *arguments= NULL;
450     //int32_t argLen = 0;
451     char testType[256] = "";
452     const DataMap *settings= NULL;
453     //const UChar *type= NULL;
454     UErrorCode status = U_ZERO_ERROR;
455     UnicodeString testSetting;
456     int n = 0;
457     while (testData->nextSettings(settings, status)) {
458         status = U_ZERO_ERROR;
459         // try to get a locale
460         testSetting = settings->getString("Type", status);
461         if (U_SUCCESS(status)) {
462             if ((++n)>0) {
463                 logln("---");
464             }
465             logln(testSetting + "---");
466             testSetting.extract(0, testSetting.length(), testType, "");
467         } else {
468             errln("Unable to extract 'Type'. Skipping..");
469             continue;
470         }
471 
472         if (!strcmp(testType, "convert_fwd")) {
473             testConvert(testData, settings, true);
474         } else if (!strcmp(testType, "convert_rev")) {
475             testConvert(testData, settings, false);
476         } else if (!strcmp(testType, "ops")) {
477             testOps(testData, settings);
478         } else {
479             errln("Unknown type: %s", testType);
480         }
481     }
482 }
483 
484 #endif
485