• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /********************************************************************
2  * COPYRIGHT:
3  * Copyright (c) 1997-2007, 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 "dadrfmt.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 "unicode/dbgutil.h"
27 #include "fldset.h"
28 
29 
30 #include <stdio.h>
31 
DataDrivenFormatTest()32 DataDrivenFormatTest::DataDrivenFormatTest() {
33     UErrorCode status = U_ZERO_ERROR;
34     driver = TestDataModule::getTestDataModule("format", *this, status);
35 }
36 
~DataDrivenFormatTest()37 DataDrivenFormatTest::~DataDrivenFormatTest() {
38     delete driver;
39 }
40 
runIndexedTest(int32_t index,UBool exec,const char * & name,char *)41 void DataDrivenFormatTest::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         errln("format/DataDriven*Test data (format.res) not initialized!");
68         name = "";
69     }
70 
71 }
72 
73 
74 
75 /*
76  *             Headers { "locale","spec", "date", "str"}
77             // locale: locale including calendar type
78             // spec:   either 'PATTERN=y mm h' etc, or 'DATE=SHORT,TIME=LONG'
79             // date:   either an unsigned long (millis), or a calendar spec ERA=0,YEAR=1, etc.. applied to the calendar type specified by the locale
80             // str:   the expected unicode string
81             Cases {
82                {
83                     "en_US@calendar=gregorian",
84                     "DATE=SHORT,TIME=SHORT",
85                     "ERA=1,YEAR=2007,MONTH=AUGUST,DATE=8,HOUR=18,MINUTE=54,SECOND=12",
86                     "8/8/2007 6:54pm"
87                },
88  * */
89 
90 
testConvertDate(TestData * testData,const DataMap *,UBool fmt)91 void DataDrivenFormatTest::testConvertDate(TestData *testData,
92         const DataMap * /* settings */, UBool fmt) {
93     UnicodeString kPATTERN("PATTERN="); // TODO: static
94     UnicodeString kMILLIS("MILLIS="); // TODO: static
95     UnicodeString kRELATIVE_MILLIS("RELATIVE_MILLIS="); // TODO: static
96 
97     UErrorCode status = U_ZERO_ERROR;
98     SimpleDateFormat basicFmt(UnicodeString("EEE MMM dd yyyy / YYYY'-W'ww-ee"),
99             status);
100     if (U_FAILURE(status)) {
101         errln("FAIL: Couldn't create basic SimpleDateFormat: %s\n",
102                 u_errorName(status));
103         return;
104     }
105 
106     const DataMap *currentCase= NULL;
107     // Start the processing
108     int n = 0;
109     while (testData->nextCase(currentCase, status)) {
110         char calLoc[256] = "";
111         DateTimeStyleSet styleSet;
112         UnicodeString pattern;
113         UBool usePattern = FALSE;
114         CalendarFieldsSet fromSet;
115         UDate fromDate = 0;
116         UBool useDate = FALSE;
117 
118         UDate now = Calendar::getNow();
119 
120         ++n;
121 
122         char theCase[200];
123         sprintf(theCase, "case %d:", n);
124         UnicodeString caseString(theCase, "");
125 
126         // load params
127         UnicodeString locale = currentCase->getString("locale", status);
128         if (U_FAILURE(status)) {
129             errln("case %d: No 'locale' line.", n);
130             continue;
131         }
132         UnicodeString spec = currentCase->getString("spec", status);
133         if(U_FAILURE(status)) {
134             errln("case %d: No 'spec' line.", n);
135             continue;
136         }
137         UnicodeString date = currentCase->getString("date", status);
138         if(U_FAILURE(status)) {
139             errln("case %d: No 'date' line.", n);
140             continue;
141         }
142         UnicodeString expectStr= currentCase->getString("str", status);
143         if(U_FAILURE(status)) {
144             errln("case %d: No 'str' line.", n);
145             continue;
146         }
147 
148         DateFormat *format = NULL;
149 
150         // Process: 'locale'
151         locale.extract(0, locale.length(), calLoc, (const char*)0); // default codepage.  Invariant codepage doesn't have '@'!
152         Locale loc(calLoc);
153         if(spec.startsWith(kPATTERN)) {
154             pattern = UnicodeString(spec,kPATTERN.length());
155             usePattern = TRUE;
156             format = new SimpleDateFormat(pattern, loc, status);
157             if(U_FAILURE(status)) {
158                 errln("case %d: could not create SimpleDateFormat from pattern: %s", n, u_errorName(status));
159                 continue;
160             }
161         } else {
162             if(styleSet.parseFrom(spec, status)<0 || U_FAILURE(status)) {
163                 errln("case %d: could not parse spec as style fields: %s", n, u_errorName(status));
164                 continue;
165             }
166             format = DateFormat::createDateTimeInstance((DateFormat::EStyle)styleSet.getDateStyle(), (DateFormat::EStyle)styleSet.getTimeStyle(), loc);
167             if(format == NULL ) {
168                 errln("case %d: could not create SimpleDateFormat from styles.", n);
169                 continue;
170             }
171         }
172 
173         // parse 'date'
174         if(date.startsWith(kMILLIS)) {
175             UnicodeString millis = UnicodeString(date, kMILLIS.length());
176             useDate = TRUE;
177             fromDate = udbg_stoi(millis);
178         } else if(date.startsWith(kRELATIVE_MILLIS)) {
179             UnicodeString millis = UnicodeString(date, kRELATIVE_MILLIS.length());
180             useDate = TRUE;
181             fromDate = udbg_stoi(millis) + now;
182         } else if(fromSet.parseFrom(date, status)<0 || U_FAILURE(status)) {
183             errln("case %d: could not parse date as calendar fields: %s", n, u_errorName(status));
184             continue;
185         }
186 
187         Calendar *cal = Calendar::createInstance(loc, status);
188         if(U_FAILURE(status)) {
189             errln("case %d: could not create calendar from %s", n, calLoc);
190         }
191         // now, do it.
192         if (fmt) {
193             FieldPosition pos;
194 //            logln((UnicodeString)"#"+n+" "+locale+"/"+from+" >>> "+toCalLoc+"/"
195 //                    +to);
196             cal->clear();
197             UnicodeString output;
198             output.remove();
199 
200             if(useDate) {
201 //                cal->setTime(fromDate, status);
202 //                if(U_FAILURE(status)) {
203 //                    errln("case %d: could not set time on calendar: %s", n, u_errorName(status));
204 //                    continue;
205 //                }
206                 format->format(fromDate, output, pos, status);
207             } else {
208                 fromSet.setOnCalendar(cal, status);
209                 if(U_FAILURE(status)) {
210                     errln("case %d: could not set fields on calendar: %s", n, u_errorName(status));
211                     continue;
212                 }
213                 format->format(*cal, output, pos);
214             }
215 
216             // check erro result from 'format'
217             if(U_FAILURE(status)) {
218                 errln("case %d: could not format(): %s", n, u_errorName(status)); // TODO: use 'pos'
219             }
220 //            if(pos.getBeginIndex()==0 && pos.getEndIndex()==0) { // TODO: more precise error?
221 //                errln("WARNING: case %d: format's pos returned (0,0) - error ??", n);
222 //            }
223 
224             if(output == expectStr) {
225                 logln(caseString+": format: SUCCESS! "+UnicodeString("expect=output=")+output);
226             } else {
227                 UnicodeString result;
228                 UnicodeString result2;
229                 errln(caseString+": format:  output!=expectStr, got " + *udbg_escape(output, &result) + " expected " + *udbg_escape(expectStr, &result2));
230             }
231         } else {
232             cal->clear();
233             ParsePosition pos;
234             format->parse(expectStr,*cal,pos);
235             if(useDate) {
236                 UDate gotDate = cal->getTime(status);
237                 if(U_FAILURE(status)) {
238                     errln(caseString+": parse: could not get time on calendar: "+UnicodeString(u_errorName(status)));
239                     continue;
240                 }
241                 if(gotDate == fromDate) {
242                     logln(caseString+": parse: SUCCESS! "+UnicodeString("gotDate=parseDate=")+expectStr);
243                 } else {
244                     UnicodeString expectDateStr, gotDateStr;
245                     basicFmt.format(fromDate,expectDateStr);
246                     basicFmt.format(gotDate,gotDateStr);
247                     errln(caseString+": parse: FAIL. parsed '"+expectStr+"' and got "+gotDateStr+", expected " + expectDateStr);
248                 }
249             } else {
250 //                Calendar *cal2 = cal->clone();
251 //                cal2->clear();
252 //                fromSet.setOnCalendar(cal2, status);
253                 if(U_FAILURE(status)) {
254                     errln("case %d: parse: could not set fields on calendar: %s", n, u_errorName(status));
255                     continue;
256                 }
257 
258                 CalendarFieldsSet diffSet;
259 //                diffSet.clear();
260                 if (!fromSet.matches(cal, diffSet, status)) {
261                     UnicodeString diffs = diffSet.diffFrom(fromSet, status);
262                     errln((UnicodeString)"FAIL: "+caseString
263                             +", Differences: '"+ diffs
264                             +"', status: "+ u_errorName(status));
265                 } else if (U_FAILURE(status)) {
266                     errln("FAIL: "+caseString+" parse SET SOURCE calendar Failed to match: "
267                             +u_errorName(status));
268                 } else {
269                     logln("PASS: "+caseString+" parse.");
270                 }
271 
272 
273 
274             }
275         }
276         delete cal;
277         delete format;
278 
279     }
280 //    delete basicFmt;
281 }
282 
processTest(TestData * testData)283 void DataDrivenFormatTest::processTest(TestData *testData) {
284     //Format *cal= NULL;
285     //const UChar *arguments= NULL;
286     //int32_t argLen = 0;
287     char testType[256];
288     const DataMap *settings= NULL;
289     //const UChar *type= NULL;
290     UErrorCode status = U_ZERO_ERROR;
291     UnicodeString testSetting;
292     int n = 0;
293     while (testData->nextSettings(settings, status)) {
294         status = U_ZERO_ERROR;
295         // try to get a locale
296         testSetting = settings->getString("Type", status);
297         if (U_SUCCESS(status)) {
298             if ((++n)>0) {
299                 logln("---");
300             }
301             logln(testSetting + "---");
302             testSetting.extract(0, testSetting.length(), testType, "");
303         } else {
304             errln("Unable to extract 'Type'. Skipping..");
305             continue;
306         }
307 
308         if (!strcmp(testType, "date_format")) {
309             testConvertDate(testData, settings, true);
310         } else if (!strcmp(testType, "date_parse")) {
311             testConvertDate(testData, settings, false);
312         } else {
313             errln("Unknown type: %s", testType);
314         }
315     }
316 }
317 
318 #endif
319