1 // Copyright (C) 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /********************************************************************
5 * Copyright (c) 1997-2010, International Business Machines Corporation and
6 * others. All Rights Reserved.
7 ********************************************************************/
9 /***********************************************************************
10 * Modification history
11 * Date Name Description
12 * 07/09/2007 srl Copied from dadrcoll.cpp
13 ***********************************************************************/
15 #include "unicode/utypes.h"
17 #if !UCONFIG_NO_FORMATTING
19 #include "unicode/tstdtmod.h"
22 #include "unicode/calendar.h"
25 #include "unicode/schriter.h"
26 #include "unicode/regex.h"
27 #include "unicode/smpdtfmt.h"
32 DataDrivenCalendarTest::DataDrivenCalendarTest() {
33 UErrorCode status = U_ZERO_ERROR;
34 driver = TestDataModule::getTestDataModule("calendar", *this, status);
37 DataDrivenCalendarTest::~DataDrivenCalendarTest() {
41 void DataDrivenCalendarTest::runIndexedTest(int32_t index, UBool exec,
42 const char* &name, char* /*par */) {
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));
60 processTest(testData);
67 dataerrln("format/DataDriven*Test data (calendar.res) not initialized!");
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
81 const DataMap *currentCase= NULL;
82 char toCalLoc[256] = "";
84 // TODO: static strings?
85 const UnicodeString kADD("add", "");
86 const UnicodeString kROLL("roll", "");
89 CalendarFieldsSet fromSet, toSet, paramsSet, diffSet;
90 SimpleDateFormat fmt(UnicodeString("EEE MMM dd yyyy / YYYY'-W'ww-ee"),
92 if (U_FAILURE(status)) {
93 dataerrln("FAIL: Couldn't create SimpleDateFormat: %s",
97 // Start the processing
99 while (testData->nextCase(currentCase, status)) {
101 Calendar *toCalendar= NULL;
102 Calendar *fromCalendar= NULL;
106 sprintf(theCase, "[case %d]", n);
107 UnicodeString caseString(theCase, "");
109 // Headers { "locale","from","operation","params","to" }
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(" - "));
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 "
130 UnicodeString from = testSetting=currentCase->getString(param, status);
131 if (U_FAILURE(status)) {
132 errln(caseString+": Unable to get parameter '"+param+"' "
133 + UnicodeString(" - "));
137 if(from.startsWith(kMILLIS)){
138 UnicodeString millis = UnicodeString(from, kMILLIS.length());
140 fromDate = udbg_stod(millis);
141 } else if(fromSet.parseFrom(testSetting, status)<0 || U_FAILURE(status)){
142 errln(caseString+": Failed to parse '"+param+"' parameter: "
147 // #4 'operation' info
149 UnicodeString operation = testSetting=currentCase->getString(param,
151 if (U_FAILURE(status)) {
152 errln(caseString+": Unable to get parameter '"+param+"' "
153 + UnicodeString(" - "));
156 if (U_FAILURE(status)) {
157 errln(caseString+": Failed to parse '"+param+"' parameter: "
165 UnicodeString params = testSetting
166 =currentCase->getString(param, status);
167 if (U_FAILURE(status)) {
168 errln(caseString+": Unable to get parameter '"+param+"' "
169 + UnicodeString(" - "));
172 paramsSet.parseFrom(testSetting, status); // parse with inheritance.
173 if (U_FAILURE(status)) {
174 errln(caseString+": Failed to parse '"+param+"' parameter: "
182 UnicodeString to = testSetting=currentCase->getString(param, status);
183 if (U_FAILURE(status)) {
184 errln(caseString+": Unable to get parameter '"+param+"' "
185 + UnicodeString(" - "));
188 if(to.startsWith(kMILLIS)){
189 UnicodeString millis = UnicodeString(to, kMILLIS.length());
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: "
198 UnicodeString caseContentsString = locale+": from "+from+": "
199 +operation +" [[[ "+params+" ]]] >>> "+to;
200 logln(caseString+": "+caseContentsString);
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));
214 fromSet.setOnCalendar(fromCalendar, status);
215 if (U_FAILURE(status)) {
216 errln(caseString+" FAIL: Failed to set on Source calendar: "
217 + u_errorName(status));
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));
233 logln("PASS: "+caseString+" SET SOURCE calendar match.");
236 // to calendar - copy of from calendar
237 toCalendar = fromCalendar->clone();
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);
249 errln(caseString+ " FAIL: unknown operation "+ operation);
251 logln(operation + " of "+ paramsSet.get((UCalendarDateFields)q)
252 +" -> "+u_errorName(status));
255 if (U_FAILURE(status)) {
256 errln(caseString+" FAIL: after "+operation+" of "+params+" -> "
257 +u_errorName(status));
261 // now - what's the result?
265 if(!(toCalendar->getTime(status)==toDate) || U_FAILURE(status)){
266 errln("FAIL: "+caseString+" Match operation had an error: "
267 +u_errorName(status));
269 logln(caseString + " SUCCESS: got=expected="+toDate);
270 logln("PASS: "+caseString+" matched!");
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));
281 logln("PASS: "+caseString+" matched!");
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();
296 fromCalendar->clear();
298 fromSet.setOnCalendar(fromCalendar, status);
299 if (U_FAILURE(status)) {
300 errln("FAIL: Failed to set on Source calendar: %s", u_errorName(status));
304 CalendarFieldsSet diffSet;
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));
317 logln("PASS: "+thisString+" SOURCE calendar match.");
320 //logln("Set Source calendar: " + from);
322 UDate fromTime = fromCalendar->getTime(status);
323 if (U_FAILURE(status)) {
324 errln("FAIL: Failed to get Source time: %s", u_errorName(status));
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));
339 logln("PASS: "+thisString+" SET SOURCE calendar match.");
343 toCalendar->setTime(fromTime, status);
344 if (U_FAILURE(status)) {
345 errln("FAIL: Failed to set Target time: %s", u_errorName(status));
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));
362 logln("PASS: "+thisString+" match.");
366 void 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] = "";
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);
384 CalendarFieldsSet fromSet, toSet, diffSet;
385 SimpleDateFormat fmt(UnicodeString("EEE MMM dd yyyy / YYYY'-W'ww-ee"),
387 if (U_FAILURE(status)) {
388 errcheckln(status, "FAIL: Couldn't create SimpleDateFormat: %s",
389 u_errorName(status));
392 // Start the processing
394 while (testData->nextCase(currentCase, status)) {
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);
406 errln("No 'locale' line.");
413 UnicodeString from = currentCase->getString("from", status);
414 if (U_FAILURE(status)) {
415 errln("No 'from' line.");
418 fromSet.parseFrom(from, status);
419 if (U_FAILURE(status)) {
420 errln("Failed to parse 'from' parameter: "+from);
423 UnicodeString to = currentCase->getString("to", status);
424 if (U_FAILURE(status)) {
425 errln("No 'to' line.");
428 toSet.parseFrom(to, &fromSet, status);
429 if (U_FAILURE(status)) {
430 errln("Failed to parse 'to' parameter: "+to);
436 logln((UnicodeString)"#"+n+" "+locale+"/"+from+" >>> "+toCalLoc+"/"
438 testConvert(n, fromSet, fromCalendar, toSet, toCalendar, forward);
440 logln((UnicodeString)"#"+n+" "+locale+"/"+from+" <<< "+toCalLoc+"/"
442 testConvert(n, toSet, toCalendar, fromSet, fromCalendar, forward);
450 void DataDrivenCalendarTest::processTest(TestData *testData) {
451 //Calendar *cal= NULL;
452 //const UChar *arguments= NULL;
453 //int32_t argLen = 0;
455 const DataMap *settings= NULL;
456 //const UChar *type= NULL;
457 UErrorCode status = U_ZERO_ERROR;
458 UnicodeString testSetting;
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)) {
468 logln(testSetting + "---");
469 testSetting.extract(0, testSetting.length(), testType, "");
471 errln("Unable to extract 'Type'. Skipping..");
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);
482 errln("Unknown type: %s", testType);