Imported Upstream version 58.1
[platform/upstream/icu.git] / source / test / intltest / dadrcal.cpp
1 // Copyright (C) 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
32 DataDrivenCalendarTest::DataDrivenCalendarTest() {
33     UErrorCode status = U_ZERO_ERROR;
34     driver = TestDataModule::getTestDataModule("calendar", *this, status);
35 }
36
37 DataDrivenCalendarTest::~DataDrivenCalendarTest() {
38     delete driver;
39 }
40
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
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
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
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] = "";
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
450 void 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