1 /********************************************************************
3 * Copyright (c) 1997-2008, International Business Machines Corporation and
4 * others. All Rights Reserved.
5 ********************************************************************/
7 /***********************************************************************
9 * Date Name Description
10 * 07/09/2007 srl Copied from dadrcoll.cpp
11 ***********************************************************************/
13 #include "unicode/utypes.h"
15 #if !UCONFIG_NO_FORMATTING
17 #include "unicode/tstdtmod.h"
20 #include "unicode/calendar.h"
23 #include "unicode/schriter.h"
24 #include "unicode/regex.h"
25 #include "unicode/smpdtfmt.h"
26 #include "unicode/dbgutil.h"
32 DataDrivenFormatTest::DataDrivenFormatTest() {
33 UErrorCode status
= U_ZERO_ERROR
;
34 driver
= TestDataModule::getTestDataModule("format", *this, status
);
37 DataDrivenFormatTest::~DataDrivenFormatTest() {
41 void DataDrivenFormatTest::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("[DATA] format/DataDriven*Test data (format.res) not initialized!");
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
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",
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 UnicodeString
kRELATIVE_ADD("RELATIVE_ADD:"); // TODO: static
98 UErrorCode status
= U_ZERO_ERROR
;
99 SimpleDateFormat
basicFmt(UnicodeString("EEE MMM dd yyyy / YYYY'-W'ww-ee"),
101 if (U_FAILURE(status
)) {
102 errln("FAIL: Couldn't create basic SimpleDateFormat: %s\n",
103 u_errorName(status
));
107 const DataMap
*currentCase
= NULL
;
108 // Start the processing
110 while (testData
->nextCase(currentCase
, status
)) {
111 char calLoc
[256] = "";
112 DateTimeStyleSet styleSet
;
113 UnicodeString pattern
;
114 UBool usePattern
= FALSE
;
115 CalendarFieldsSet fromSet
;
117 UBool useDate
= FALSE
;
119 UDate now
= Calendar::getNow();
124 sprintf(theCase
, "case %d:", n
);
125 UnicodeString
caseString(theCase
, "");
128 UnicodeString locale
= currentCase
->getString("locale", status
);
129 if (U_FAILURE(status
)) {
130 errln("case %d: No 'locale' line.", n
);
133 UnicodeString spec
= currentCase
->getString("spec", status
);
134 if(U_FAILURE(status
)) {
135 errln("case %d: No 'spec' line.", n
);
138 UnicodeString date
= currentCase
->getString("date", status
);
139 if(U_FAILURE(status
)) {
140 errln("case %d: No 'date' line.", n
);
143 UnicodeString expectStr
= currentCase
->getString("str", status
);
144 if(U_FAILURE(status
)) {
145 errln("case %d: No 'str' line.", n
);
149 DateFormat
*format
= NULL
;
152 locale
.extract(0, locale
.length(), calLoc
, (const char*)0); // default codepage. Invariant codepage doesn't have '@'!
154 if(spec
.startsWith(kPATTERN
)) {
155 pattern
= UnicodeString(spec
,kPATTERN
.length());
157 format
= new SimpleDateFormat(pattern
, loc
, status
);
158 if(U_FAILURE(status
)) {
159 errln("case %d: could not create SimpleDateFormat from pattern: %s", n
, u_errorName(status
));
163 if(styleSet
.parseFrom(spec
, status
)<0 || U_FAILURE(status
)) {
164 errln("case %d: could not parse spec as style fields: %s", n
, u_errorName(status
));
167 format
= DateFormat::createDateTimeInstance((DateFormat::EStyle
)styleSet
.getDateStyle(), (DateFormat::EStyle
)styleSet
.getTimeStyle(), loc
);
168 if(format
== NULL
) {
169 errln("case %d: could not create SimpleDateFormat from styles.", n
);
174 Calendar
*cal
= Calendar::createInstance(loc
, status
);
175 if(U_FAILURE(status
)) {
176 errln("case %d: could not create calendar from %s", n
, calLoc
);
180 if(date
.startsWith(kMILLIS
)) {
181 UnicodeString millis
= UnicodeString(date
, kMILLIS
.length());
183 fromDate
= udbg_stoi(millis
);
184 } else if(date
.startsWith(kRELATIVE_MILLIS
)) {
185 UnicodeString millis
= UnicodeString(date
, kRELATIVE_MILLIS
.length());
187 fromDate
= udbg_stoi(millis
) + now
;
188 } else if(date
.startsWith(kRELATIVE_ADD
)) {
189 UnicodeString add
= UnicodeString(date
, kRELATIVE_ADD
.length()); // "add" is a string indicating which fields to add
190 if(fromSet
.parseFrom(add
, status
)<0 || U_FAILURE(status
)) {
191 errln("case %d: could not parse date as RELATIVE_ADD calendar fields: %s", n
, u_errorName(status
));
196 cal
->setTime(now
, status
);
197 for (int q
=0; q
<UCAL_FIELD_COUNT
; q
++) {
198 if (fromSet
.isSet((UCalendarDateFields
)q
)) {
199 int32_t oldv
= cal
->get((UCalendarDateFields
)q
, status
);
200 cal
->add((UCalendarDateFields
)q
,
201 fromSet
.get((UCalendarDateFields
)q
), status
);
202 int32_t newv
= cal
->get((UCalendarDateFields
)q
, status
);
205 fromDate
= cal
->getTime(status
);
206 if(U_FAILURE(status
)) {
207 errln("case %d: could not apply date as RELATIVE_ADD calendar fields: %s", n
, u_errorName(status
));
210 } else if(fromSet
.parseFrom(date
, status
)<0 || U_FAILURE(status
)) {
211 errln("case %d: could not parse date as calendar fields: %s", n
, u_errorName(status
));
218 // logln((UnicodeString)"#"+n+" "+locale+"/"+from+" >>> "+toCalLoc+"/"
221 UnicodeString output
;
225 // cal->setTime(fromDate, status);
226 // if(U_FAILURE(status)) {
227 // errln("case %d: could not set time on calendar: %s", n, u_errorName(status));
230 format
->format(fromDate
, output
, pos
, status
);
232 fromSet
.setOnCalendar(cal
, status
);
233 if(U_FAILURE(status
)) {
234 errln("case %d: could not set fields on calendar: %s", n
, u_errorName(status
));
237 format
->format(*cal
, output
, pos
);
240 // check erro result from 'format'
241 if(U_FAILURE(status
)) {
242 errln("case %d: could not format(): %s", n
, u_errorName(status
)); // TODO: use 'pos'
244 // if(pos.getBeginIndex()==0 && pos.getEndIndex()==0) { // TODO: more precise error?
245 // errln("WARNING: case %d: format's pos returned (0,0) - error ??", n);
248 if(output
== expectStr
) {
249 logln(caseString
+": format: SUCCESS! "+UnicodeString("expect=output=")+output
);
251 UnicodeString result
;
252 UnicodeString result2
;
253 errln(caseString
+": format: output!=expectStr, got " + *udbg_escape(output
, &result
) + " expected " + *udbg_escape(expectStr
, &result2
));
258 format
->parse(expectStr
,*cal
,pos
);
260 UDate gotDate
= cal
->getTime(status
);
261 if(U_FAILURE(status
)) {
262 errln(caseString
+": parse: could not get time on calendar: "+UnicodeString(u_errorName(status
)));
265 if(gotDate
== fromDate
) {
266 logln(caseString
+": parse: SUCCESS! "+UnicodeString("gotDate=parseDate=")+expectStr
);
268 UnicodeString expectDateStr
, gotDateStr
;
269 basicFmt
.format(fromDate
,expectDateStr
);
270 basicFmt
.format(gotDate
,gotDateStr
);
271 errln(caseString
+": parse: FAIL. parsed '"+expectStr
+"' and got "+gotDateStr
+", expected " + expectDateStr
);
274 // Calendar *cal2 = cal->clone();
276 // fromSet.setOnCalendar(cal2, status);
277 if(U_FAILURE(status
)) {
278 errln("case %d: parse: could not set fields on calendar: %s", n
, u_errorName(status
));
282 CalendarFieldsSet diffSet
;
284 if (!fromSet
.matches(cal
, diffSet
, status
)) {
285 UnicodeString diffs
= diffSet
.diffFrom(fromSet
, status
);
286 errln((UnicodeString
)"FAIL: "+caseString
287 +", Differences: '"+ diffs
288 +"', status: "+ u_errorName(status
));
289 } else if (U_FAILURE(status
)) {
290 errln("FAIL: "+caseString
+" parse SET SOURCE calendar Failed to match: "
291 +u_errorName(status
));
293 logln("PASS: "+caseString
+" parse.");
307 void DataDrivenFormatTest::processTest(TestData
*testData
) {
309 //const UChar *arguments= NULL;
310 //int32_t argLen = 0;
312 const DataMap
*settings
= NULL
;
313 //const UChar *type= NULL;
314 UErrorCode status
= U_ZERO_ERROR
;
315 UnicodeString testSetting
;
317 while (testData
->nextSettings(settings
, status
)) {
318 status
= U_ZERO_ERROR
;
319 // try to get a locale
320 testSetting
= settings
->getString("Type", status
);
321 if (U_SUCCESS(status
)) {
325 logln(testSetting
+ "---");
326 testSetting
.extract(0, testSetting
.length(), testType
, "");
328 errln("Unable to extract 'Type'. Skipping..");
332 if (!strcmp(testType
, "date_format")) {
333 testConvertDate(testData
, settings
, true);
334 } else if (!strcmp(testType
, "date_parse")) {
335 testConvertDate(testData
, settings
, false);
337 errln("Unknown type: %s", testType
);