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
DataDrivenCalendarTest()30 DataDrivenCalendarTest::DataDrivenCalendarTest() {
31 UErrorCode status = U_ZERO_ERROR;
32 driver = TestDataModule::getTestDataModule("calendar", *this, status);
33 }
34
~DataDrivenCalendarTest()35 DataDrivenCalendarTest::~DataDrivenCalendarTest() {
36 delete driver;
37 }
38
runIndexedTest(int32_t index,UBool exec,const char * & name,char *)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
testOps(TestData * testData,const DataMap *)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
testConvert(int32_t n,const CalendarFieldsSet & fromSet,Calendar * fromCalendar,const CalendarFieldsSet & toSet,Calendar * toCalendar,UBool forward)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
testConvert(TestData * testData,const DataMap * settings,UBool forward)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
processTest(TestData * testData)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