1// © 2016 and later: Unicode, Inc. and others.
2// License & terms of use: http://www.unicode.org/copyright.html#License
3/*
4 *******************************************************************************
5 * Copyright (C) 2007-2012, International Business Machines Corporation and         *
6 * others. All Rights Reserved.                                                *
7 *******************************************************************************
8 */
9package com.ibm.icu.dev.test.format;
10
11import java.text.FieldPosition;
12import java.text.ParsePosition;
13import java.util.Date;
14import java.util.Iterator;
15import java.util.List;
16
17import org.junit.Test;
18import org.junit.runner.RunWith;
19
20import com.ibm.icu.dev.test.ModuleTest;
21import com.ibm.icu.dev.test.ModuleTest.TestDataPair;
22import com.ibm.icu.dev.test.TestDataModule;
23import com.ibm.icu.dev.test.TestDataModule.DataMap;
24import com.ibm.icu.dev.test.TestDataModule.TestData;
25import com.ibm.icu.dev.test.TestFmwk;
26import com.ibm.icu.dev.test.util.CalendarFieldsSet;
27import com.ibm.icu.dev.test.util.DateTimeStyleSet;
28import com.ibm.icu.text.DateFormat;
29import com.ibm.icu.text.SimpleDateFormat;
30import com.ibm.icu.util.Calendar;
31import com.ibm.icu.util.TimeZone;
32import com.ibm.icu.util.ULocale;
33
34import junitparams.JUnitParamsRunner;
35import junitparams.Parameters;
36
37/**
38 * @author srl
39 * @author sgill
40 *
41 */
42@RunWith(JUnitParamsRunner.class)
43public class DataDrivenFormatTest extends TestFmwk {
44
45    /**
46     * @param baseName
47     * @param locName
48     */
49    public DataDrivenFormatTest() {
50        //super("com/ibm/icu/dev/data/testdata/", "format");
51    }
52
53    @SuppressWarnings("unused")
54    private List<TestDataPair> getTestData() throws Exception {
55        return ModuleTest.getTestData("com/ibm/icu/dev/data/testdata/", "format");
56    }
57
58    /* (non-Javadoc)
59     * @see com.ibm.icu.dev.test.ModuleTest#processModules()
60     */
61    @Test
62    @Parameters(method="getTestData")
63    public void formatTest(TestDataPair pair) {
64        TestData td = pair.td;
65        DataMap settings = pair.dm;
66
67
68        String type = settings.getString("Type");
69
70        if(type.equals("date_format")) {
71            testConvertDate(td, settings, true);
72        } else if(type.equals("date_parse")) {
73            testConvertDate(td, settings, false);
74        } else {
75            errln("Unknown type: " + type);
76        }
77    }
78
79
80    private static final String kPATTERN = "PATTERN=";
81    private static final String kMILLIS = "MILLIS=";
82    private static final String kRELATIVE_MILLIS = "RELATIVE_MILLIS=";
83    private static final String kRELATIVE_ADD = "RELATIVE_ADD:";
84
85    private void testConvertDate(TestDataModule.TestData testData, DataMap  settings, boolean fmt) {
86        DateFormat basicFmt = new SimpleDateFormat("EEE MMM dd yyyy / YYYY'-W'ww-ee");
87
88        int n = 0;
89        for (Iterator iter = testData.getDataIterator(); iter.hasNext();) {
90            ++n;
91            long now = System.currentTimeMillis();
92            DataMap currentCase = (DataMap) iter.next();
93            String caseString = "["+testData.getName()+"#"+n+(fmt?"format":"parse")+"]";
94
95            String locale = currentCase.getString("locale");
96            String zone = currentCase.getString("zone");
97            String spec = currentCase.getString("spec");
98            String date = currentCase.getString("date");
99            String str = currentCase.getString("str");
100
101            Date fromDate = null;
102            boolean useDate = false;
103
104            ULocale loc = new ULocale(locale);
105            String pattern = null;
106//            boolean usePattern = false;
107            DateFormat format = null;
108            DateTimeStyleSet styleSet;
109            CalendarFieldsSet fromSet = null;
110
111            // parse 'spec'  - either 'PATTERN=yy mm dd' or 'DATE=x,TIME=y'
112            if(spec.startsWith(kPATTERN)) {
113                pattern = spec.substring(kPATTERN.length());
114//                usePattern = true;
115                format = new SimpleDateFormat(pattern, loc);
116            } else {
117                styleSet = new DateTimeStyleSet();
118                styleSet.parseFrom(spec);
119                format = DateFormat.getDateTimeInstance(styleSet.getDateStyle(), styleSet.getTimeStyle(), loc);
120            }
121
122            Calendar cal = Calendar.getInstance(loc);
123
124            if (zone.length() > 0) {
125                TimeZone tz = TimeZone.getFrozenTimeZone(zone);
126                cal.setTimeZone(tz);
127                format.setTimeZone(tz);
128            }
129
130            // parse 'date' - either 'MILLIS=12345' or  a CalendarFieldsSet
131            if(date.startsWith(kMILLIS)) {
132                useDate = true;
133                fromDate = new Date(Long.parseLong(date.substring(kMILLIS.length())));
134            } else if(date.startsWith(kRELATIVE_MILLIS)) {
135                useDate = true;
136                fromDate = new Date(now+Long.parseLong(date.substring(kRELATIVE_MILLIS.length())));
137            } else if(date.startsWith(kRELATIVE_ADD)) {
138                String add = date.substring(kRELATIVE_ADD.length()); // "add" is a string indicating which fields to add
139                CalendarFieldsSet addSet = new CalendarFieldsSet();
140                addSet.parseFrom(add);
141                useDate = true;
142                cal.clear();
143                cal.setTimeInMillis(now);
144
145                /// perform op on 'to calendar'
146                for (int q=0; q<addSet.fieldCount(); q++) {
147                    if (addSet.isSet(q)) {
148                        if (q == Calendar.DATE) {
149                            cal.add(q,addSet.get(q));
150                        } else {
151                            cal.set(q,addSet.get(q));
152                        }
153                    }
154                }
155
156                fromDate = cal.getTime();
157            } else {
158                fromSet = new CalendarFieldsSet();
159                fromSet.parseFrom(date);
160            }
161
162            // run the test
163            if(fmt) {
164                StringBuffer output = new StringBuffer();
165                cal.clear();
166                FieldPosition pos = new FieldPosition(0);
167                if(useDate) {
168                    output = format.format(fromDate, output, pos);
169                } else {
170                    fromSet.setOnCalendar(cal);
171                    format.format(cal, output, pos);
172                }
173
174                if(output.toString().equals(str)) {
175                    logln(caseString + " Success - strings match: " + output);
176                } else {
177                    errln(caseString + " FAIL: got " + output + " expected " + str);
178                }
179            } else { // parse
180                cal.clear();
181                ParsePosition pos = new ParsePosition(0);
182                format.parse(str, cal, pos);
183                if(useDate) {
184                    Date gotDate = cal.getTime();
185                    if(gotDate.equals(fromDate)) {
186                        logln(caseString + " SUCCESS: got=parse="+str);
187                    } else {
188                        errln(caseString + " FAIL: parsed " + str + " but got " +
189                                basicFmt.format(gotDate) + " - " + gotDate + "  expected " +
190                                basicFmt.format(fromDate));
191                    }
192                } else  {
193                    CalendarFieldsSet diffSet = new CalendarFieldsSet();
194                    if(!fromSet.matches(cal, diffSet)) {
195                        String diffs = diffSet.diffFrom(fromSet);
196                        errln(caseString + " FAIL:  differences: " + diffs);
197                    } else {
198                        logln(caseString + " SUCCESS: got=parse: " + str + " - " + fromSet.toString());
199                    }
200                }
201            }
202        }
203    }
204}
205