]> git.saurik.com Git - apple/icu.git/blame - icuSources/test/intltest/dadrfmt.cpp
ICU-66108.tar.gz
[apple/icu.git] / icuSources / test / intltest / dadrfmt.cpp
CommitLineData
f3c0d7a5
A
1// © 2016 and later: Unicode, Inc. and others.
2// License & terms of use: http://www.unicode.org/copyright.html
46f4442e
A
3/********************************************************************
4 * COPYRIGHT:
57a6839d 5 * Copyright (c) 1997-2013 International Business Machines Corporation and
46f4442e
A
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 "dadrfmt.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"
729e4ab9 28#include "dbgutil.h"
46f4442e
A
29#include "fldset.h"
30
31
32#include <stdio.h>
33
34DataDrivenFormatTest::DataDrivenFormatTest() {
35 UErrorCode status = U_ZERO_ERROR;
36 driver = TestDataModule::getTestDataModule("format", *this, status);
37}
38
39DataDrivenFormatTest::~DataDrivenFormatTest() {
40 delete driver;
41}
42
43void DataDrivenFormatTest::runIndexedTest(int32_t index, UBool exec,
44 const char* &name, char* /*par */) {
45 if (driver != NULL) {
46 if (exec) {
47 // logln("Begin ");
48 }
49 const DataMap *info= NULL;
50 UErrorCode status= U_ZERO_ERROR;
51 TestData *testData = driver->createTestData(index, status);
52 if (U_SUCCESS(status)) {
53 name = testData->getName();
54 if (testData->getInfo(info, status)) {
55 log(info->getString("Description", status));
56 }
57 if (exec) {
58 log(name);
59 logln("---");
60 logln("");
61
62 processTest(testData);
63 }
64 delete testData;
65 } else {
66 name = "";
67 }
68 } else {
729e4ab9 69 dataerrln("format/DataDriven*Test data (format.res) not initialized!");
46f4442e
A
70 name = "";
71 }
72
73}
74
75
76
77/*
51004dcb 78 * Headers { "locale", "zone", "spec", "date", "str"}
46f4442e 79 // locale: locale including calendar type
51004dcb 80 // zone: time zone name, or "" to not explicitly set zone
46f4442e
A
81 // spec: either 'PATTERN=y mm h' etc, or 'DATE=SHORT,TIME=LONG'
82 // date: either an unsigned long (millis), or a calendar spec ERA=0,YEAR=1, etc.. applied to the calendar type specified by the locale
83 // str: the expected unicode string
84 Cases {
85 {
51004dcb
A
86 "en_US@calendar=gregorian",
87 "",
46f4442e
A
88 "DATE=SHORT,TIME=SHORT",
89 "ERA=1,YEAR=2007,MONTH=AUGUST,DATE=8,HOUR=18,MINUTE=54,SECOND=12",
90 "8/8/2007 6:54pm"
91 },
92 * */
93
94
95void DataDrivenFormatTest::testConvertDate(TestData *testData,
96 const DataMap * /* settings */, UBool fmt) {
97 UnicodeString kPATTERN("PATTERN="); // TODO: static
98 UnicodeString kMILLIS("MILLIS="); // TODO: static
99 UnicodeString kRELATIVE_MILLIS("RELATIVE_MILLIS="); // TODO: static
100 UnicodeString kRELATIVE_ADD("RELATIVE_ADD:"); // TODO: static
101
102 UErrorCode status = U_ZERO_ERROR;
103 SimpleDateFormat basicFmt(UnicodeString("EEE MMM dd yyyy / YYYY'-W'ww-ee"),
104 status);
105 if (U_FAILURE(status)) {
729e4ab9 106 dataerrln("FAIL: Couldn't create basic SimpleDateFormat: %s",
46f4442e
A
107 u_errorName(status));
108 return;
109 }
110
111 const DataMap *currentCase= NULL;
112 // Start the processing
113 int n = 0;
114 while (testData->nextCase(currentCase, status)) {
115 char calLoc[256] = "";
116 DateTimeStyleSet styleSet;
117 UnicodeString pattern;
118 UBool usePattern = FALSE;
57a6839d 119 (void)usePattern; // Suppress unused warning.
46f4442e
A
120 CalendarFieldsSet fromSet;
121 UDate fromDate = 0;
122 UBool useDate = FALSE;
123
124 UDate now = Calendar::getNow();
125
126 ++n;
127
128 char theCase[200];
129 sprintf(theCase, "case %d:", n);
130 UnicodeString caseString(theCase, "");
131
132 // load params
133 UnicodeString locale = currentCase->getString("locale", status);
134 if (U_FAILURE(status)) {
135 errln("case %d: No 'locale' line.", n);
136 continue;
137 }
51004dcb
A
138 UnicodeString zone = currentCase->getString("zone", status);
139 if (U_FAILURE(status)) {
140 errln("case %d: No 'zone' line.", n);
141 continue;
142 }
46f4442e
A
143 UnicodeString spec = currentCase->getString("spec", status);
144 if(U_FAILURE(status)) {
145 errln("case %d: No 'spec' line.", n);
146 continue;
147 }
148 UnicodeString date = currentCase->getString("date", status);
149 if(U_FAILURE(status)) {
150 errln("case %d: No 'date' line.", n);
151 continue;
152 }
153 UnicodeString expectStr= currentCase->getString("str", status);
154 if(U_FAILURE(status)) {
155 errln("case %d: No 'str' line.", n);
156 continue;
157 }
158
159 DateFormat *format = NULL;
160
161 // Process: 'locale'
162 locale.extract(0, locale.length(), calLoc, (const char*)0); // default codepage. Invariant codepage doesn't have '@'!
163 Locale loc(calLoc);
164 if(spec.startsWith(kPATTERN)) {
165 pattern = UnicodeString(spec,kPATTERN.length());
166 usePattern = TRUE;
167 format = new SimpleDateFormat(pattern, loc, status);
168 if(U_FAILURE(status)) {
169 errln("case %d: could not create SimpleDateFormat from pattern: %s", n, u_errorName(status));
170 continue;
171 }
172 } else {
173 if(styleSet.parseFrom(spec, status)<0 || U_FAILURE(status)) {
174 errln("case %d: could not parse spec as style fields: %s", n, u_errorName(status));
175 continue;
176 }
177 format = DateFormat::createDateTimeInstance((DateFormat::EStyle)styleSet.getDateStyle(), (DateFormat::EStyle)styleSet.getTimeStyle(), loc);
178 if(format == NULL ) {
179 errln("case %d: could not create SimpleDateFormat from styles.", n);
180 continue;
181 }
182 }
183
184 Calendar *cal = Calendar::createInstance(loc, status);
185 if(U_FAILURE(status)) {
186 errln("case %d: could not create calendar from %s", n, calLoc);
187 }
51004dcb
A
188
189 if (zone.length() > 0) {
190 TimeZone * tz = TimeZone::createTimeZone(zone);
191 cal->setTimeZone(*tz);
192 format->setTimeZone(*tz);
193 delete tz;
194 }
46f4442e
A
195
196 // parse 'date'
197 if(date.startsWith(kMILLIS)) {
198 UnicodeString millis = UnicodeString(date, kMILLIS.length());
199 useDate = TRUE;
729e4ab9 200 fromDate = udbg_stod(millis);
46f4442e
A
201 } else if(date.startsWith(kRELATIVE_MILLIS)) {
202 UnicodeString millis = UnicodeString(date, kRELATIVE_MILLIS.length());
203 useDate = TRUE;
729e4ab9 204 fromDate = udbg_stod(millis) + now;
46f4442e
A
205 } else if(date.startsWith(kRELATIVE_ADD)) {
206 UnicodeString add = UnicodeString(date, kRELATIVE_ADD.length()); // "add" is a string indicating which fields to add
207 if(fromSet.parseFrom(add, status)<0 || U_FAILURE(status)) {
208 errln("case %d: could not parse date as RELATIVE_ADD calendar fields: %s", n, u_errorName(status));
209 continue;
210 }
211 useDate=TRUE;
212 cal->clear();
213 cal->setTime(now, status);
214 for (int q=0; q<UCAL_FIELD_COUNT; q++) {
215 if (fromSet.isSet((UCalendarDateFields)q)) {
729e4ab9 216 //int32_t oldv = cal->get((UCalendarDateFields)q, status);
51004dcb
A
217 if (q == UCAL_DATE) {
218 cal->add((UCalendarDateFields)q,
219 fromSet.get((UCalendarDateFields)q), status);
220 } else {
221 cal->set((UCalendarDateFields)q,
222 fromSet.get((UCalendarDateFields)q));
223 }
729e4ab9 224 //int32_t newv = cal->get((UCalendarDateFields)q, status);
46f4442e
A
225 }
226 }
227 fromDate = cal->getTime(status);
228 if(U_FAILURE(status)) {
229 errln("case %d: could not apply date as RELATIVE_ADD calendar fields: %s", n, u_errorName(status));
230 continue;
231 }
232 } else if(fromSet.parseFrom(date, status)<0 || U_FAILURE(status)) {
233 errln("case %d: could not parse date as calendar fields: %s", n, u_errorName(status));
234 continue;
235 }
236
237 // now, do it.
238 if (fmt) {
239 FieldPosition pos;
240// logln((UnicodeString)"#"+n+" "+locale+"/"+from+" >>> "+toCalLoc+"/"
241// +to);
242 cal->clear();
243 UnicodeString output;
244 output.remove();
245
246 if(useDate) {
247// cal->setTime(fromDate, status);
248// if(U_FAILURE(status)) {
249// errln("case %d: could not set time on calendar: %s", n, u_errorName(status));
250// continue;
251// }
252 format->format(fromDate, output, pos, status);
253 } else {
254 fromSet.setOnCalendar(cal, status);
255 if(U_FAILURE(status)) {
256 errln("case %d: could not set fields on calendar: %s", n, u_errorName(status));
257 continue;
258 }
259 format->format(*cal, output, pos);
260 }
261
262 // check erro result from 'format'
263 if(U_FAILURE(status)) {
264 errln("case %d: could not format(): %s", n, u_errorName(status)); // TODO: use 'pos'
265 }
266// if(pos.getBeginIndex()==0 && pos.getEndIndex()==0) { // TODO: more precise error?
267// errln("WARNING: case %d: format's pos returned (0,0) - error ??", n);
268// }
269
270 if(output == expectStr) {
271 logln(caseString+": format: SUCCESS! "+UnicodeString("expect=output=")+output);
272 } else {
273 UnicodeString result;
274 UnicodeString result2;
275 errln(caseString+": format: output!=expectStr, got " + *udbg_escape(output, &result) + " expected " + *udbg_escape(expectStr, &result2));
276 }
277 } else {
278 cal->clear();
279 ParsePosition pos;
280 format->parse(expectStr,*cal,pos);
281 if(useDate) {
282 UDate gotDate = cal->getTime(status);
283 if(U_FAILURE(status)) {
284 errln(caseString+": parse: could not get time on calendar: "+UnicodeString(u_errorName(status)));
285 continue;
286 }
287 if(gotDate == fromDate) {
288 logln(caseString+": parse: SUCCESS! "+UnicodeString("gotDate=parseDate=")+expectStr);
289 } else {
290 UnicodeString expectDateStr, gotDateStr;
291 basicFmt.format(fromDate,expectDateStr);
292 basicFmt.format(gotDate,gotDateStr);
293 errln(caseString+": parse: FAIL. parsed '"+expectStr+"' and got "+gotDateStr+", expected " + expectDateStr);
294 }
295 } else {
296// Calendar *cal2 = cal->clone();
297// cal2->clear();
298// fromSet.setOnCalendar(cal2, status);
299 if(U_FAILURE(status)) {
300 errln("case %d: parse: could not set fields on calendar: %s", n, u_errorName(status));
301 continue;
302 }
303
304 CalendarFieldsSet diffSet;
305// diffSet.clear();
306 if (!fromSet.matches(cal, diffSet, status)) {
307 UnicodeString diffs = diffSet.diffFrom(fromSet, status);
308 errln((UnicodeString)"FAIL: "+caseString
309 +", Differences: '"+ diffs
310 +"', status: "+ u_errorName(status));
311 } else if (U_FAILURE(status)) {
312 errln("FAIL: "+caseString+" parse SET SOURCE calendar Failed to match: "
313 +u_errorName(status));
314 } else {
315 logln("PASS: "+caseString+" parse.");
316 }
317
318
319
320 }
321 }
322 delete cal;
323 delete format;
324
325 }
326// delete basicFmt;
327}
328
329void DataDrivenFormatTest::processTest(TestData *testData) {
330 //Format *cal= NULL;
331 //const UChar *arguments= NULL;
332 //int32_t argLen = 0;
333 char testType[256];
334 const DataMap *settings= NULL;
335 //const UChar *type= NULL;
336 UErrorCode status = U_ZERO_ERROR;
337 UnicodeString testSetting;
338 int n = 0;
339 while (testData->nextSettings(settings, status)) {
340 status = U_ZERO_ERROR;
341 // try to get a locale
342 testSetting = settings->getString("Type", status);
343 if (U_SUCCESS(status)) {
344 if ((++n)>0) {
345 logln("---");
346 }
347 logln(testSetting + "---");
348 testSetting.extract(0, testSetting.length(), testType, "");
349 } else {
350 errln("Unable to extract 'Type'. Skipping..");
351 continue;
352 }
353
354 if (!strcmp(testType, "date_format")) {
355 testConvertDate(testData, settings, true);
356 } else if (!strcmp(testType, "date_parse")) {
357 testConvertDate(testData, settings, false);
358 } else {
359 errln("Unknown type: %s", testType);
360 }
361 }
362}
363
364#endif