OLD | NEW |
---|---|
1 /** | 1 /** |
2 * Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 2 * Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
3 * for details. All rights reserved. Use of this source code is governed by a | 3 * for details. All rights reserved. Use of this source code is governed by a |
4 * BSD-style license that can be found in the LICENSE file. | 4 * BSD-style license that can be found in the LICENSE file. |
5 */ | 5 */ |
6 | 6 |
7 #library('date_time_format_test'); | |
8 | |
Emily Fortuna
2012/07/31 05:52:53
keep this in.
Alan Knight
2012/08/03 23:02:15
OK. Why do we define libraries for things that don
| |
9 #import('../../../lib/i18n/date_format.dart'); | 7 #import('../../../lib/i18n/date_format.dart'); |
10 #import('../../../lib/unittest/unittest.dart'); | 8 #import('../../../lib/unittest/unittest.dart'); |
9 #import('../../../lib/i18n/date_time_patterns.dart'); | |
10 #import('../../../lib/i18n/date_symbol_data.dart'); | |
11 #import('../../../lib/i18n/intl.dart'); | |
12 | |
13 #source('date_time_format_test_data.dart'); | |
11 | 14 |
12 /** | 15 /** |
13 * Tests the DateFormat library in dart. | 16 * Tests the DateFormat library in dart. |
14 */ | 17 */ |
15 | 18 |
19 var formatsToTest = | |
20 const [ | |
Emily Fortuna
2012/07/31 05:52:53
move this up to the previous line
Alan Knight
2012/08/03 23:02:15
Done.
| |
21 DateFormat.DAY, | |
22 DateFormat.ABBR_WEEKDAY, | |
23 DateFormat.WEEKDAY, | |
24 DateFormat.ABBR_STANDALONE_MONTH, | |
25 DateFormat.STANDALONE_MONTH, | |
26 DateFormat.NUM_MONTH, | |
27 DateFormat.NUM_MONTH_DAY, | |
28 DateFormat.NUM_MONTH_WEEKDAY_DAY, | |
29 DateFormat.ABBR_MONTH, | |
30 DateFormat.ABBR_MONTH_DAY, | |
31 DateFormat.ABBR_MONTH_WEEKDAY_DAY, | |
32 DateFormat.MONTH, | |
33 DateFormat.MONTH_DAY, | |
34 DateFormat.MONTH_WEEKDAY_DAY, | |
35 DateFormat.ABBR_QUARTER, | |
36 DateFormat.QUARTER, | |
37 DateFormat.YEAR, | |
38 DateFormat.YEAR_NUM_MONTH, | |
39 DateFormat.YEAR_NUM_MONTH_DAY, | |
40 DateFormat.YEAR_NUM_MONTH_WEEKDAY_DAY, | |
41 DateFormat.YEAR_ABBR_MONTH, | |
42 DateFormat.YEAR_ABBR_MONTH_DAY, | |
43 DateFormat.YEAR_ABBR_MONTH_WEEKDAY_DAY, | |
44 DateFormat.YEAR_MONTH, | |
45 DateFormat.YEAR_MONTH_DAY, | |
46 DateFormat.YEAR_MONTH_WEEKDAY_DAY, | |
47 //TODO(alanknight): CLDR and ICU appear to disagree on these for Japanese | |
Emily Fortuna
2012/07/31 05:52:53
indentation
Alan Knight
2012/08/03 23:02:15
Done.
| |
48 // DateFormat.YEAR_ABBR_QUARTER, | |
49 // DateFormat.YEAR_QUARTER, | |
50 DateFormat.HOUR24, | |
51 DateFormat.HOUR24_MINUTE, | |
52 DateFormat.HOUR24_MINUTE_SECOND, | |
53 DateFormat.HOUR, | |
54 DateFormat.HOUR_MINUTE, | |
55 DateFormat.HOUR_MINUTE_SECOND, | |
56 // TODO(alanknight): Time zone support | |
57 // DateFormat.HOUR_MINUTE_GENERIC_TZ, | |
58 // DateFormat.HOUR_MINUTE_TZ, | |
59 // DateFormat.HOUR_GENERIC_TZ, | |
60 // DateFormat.HOUR_TZ, | |
61 DateFormat.MINUTE, | |
62 DateFormat.MINUTE_SECOND, | |
63 DateFormat.SECOND | |
64 // ABBR_GENERIC_TZ, | |
65 // GENERIC_TZ, | |
66 // ABBR_SPECIFIC_TZ, | |
67 // SPECIFIC_TZ, | |
68 // ABBR_UTC_TZ | |
69 ]; | |
70 | |
71 var icuFormatNamesToTest = | |
72 // It would be really nice to not have to duplicate this and just be able | |
73 // to use the names to get reflective access. | |
74 const [ | |
75 "DAY", | |
76 "ABBR_WEEKDAY", | |
77 "WEEKDAY", | |
78 "ABBR_STANDALONE_MONTH", | |
79 "STANDALONE_MONTH", | |
80 "NUM_MONTH", | |
81 "NUM_MONTH_DAY", | |
82 "NUM_MONTH_WEEKDAY_DAY", | |
83 "ABBR_MONTH", | |
84 "ABBR_MONTH_DAY", | |
85 "ABBR_MONTH_WEEKDAY_DAY", | |
86 "MONTH", | |
87 "MONTH_DAY", | |
88 "MONTH_WEEKDAY_DAY", | |
89 "ABBR_QUARTER", | |
90 "QUARTER", | |
91 "YEAR", | |
92 "YEAR_NUM_MONTH", | |
93 "YEAR_NUM_MONTH_DAY", | |
94 "YEAR_NUM_MONTH_WEEKDAY_DAY", | |
95 "YEAR_ABBR_MONTH", | |
96 "YEAR_ABBR_MONTH_DAY", | |
97 "YEAR_ABBR_MONTH_WEEKDAY_DAY", | |
98 "YEAR_MONTH", | |
99 "YEAR_MONTH_DAY", | |
100 "YEAR_MONTH_WEEKDAY_DAY", | |
101 //TODO(alanknight): CLDR and ICU appear to disagree on these for Japanese. | |
102 // omit for the time being | |
103 // "YEAR_ABBR_QUARTER", | |
104 // "YEAR_QUARTER", | |
105 "HOUR24", | |
106 "HOUR24_MINUTE", | |
107 "HOUR24_MINUTE_SECOND", | |
108 "HOUR", | |
109 "HOUR_MINUTE", | |
110 "HOUR_MINUTE_SECOND", | |
111 // TODO(alanknight): Time zone support | |
112 // "HOUR_MINUTE_GENERIC_TZ", | |
113 // "HOUR_MINUTE_TZ", | |
114 // "HOUR_GENERIC_TZ", | |
115 // "HOUR_TZ", | |
116 "MINUTE", | |
117 "MINUTE_SECOND", | |
118 "SECOND" | |
119 // ABBR_GENERIC_TZ, | |
120 // GENERIC_TZ, | |
121 // ABBR_SPECIFIC_TZ, | |
122 // SPECIFIC_TZ, | |
123 // ABBR_UTC_TZ | |
124 ]; | |
125 | |
126 | |
16 main() { | 127 main() { |
17 test('Date formatting', () { | 128 |
Emily Fortuna
2012/07/31 05:52:53
extra whitespace
Alan Knight
2012/08/03 23:02:15
Done.
| |
18 var date_format = new DateFormat.fullDate(); | 129 test('Basic date format parsing', () { |
19 Date date = new Date.now(); | 130 var date_format = new DateFormat(); |
Emily Fortuna
2012/07/31 05:52:53
indentation. please!
Alan Knight
2012/08/03 23:02:15
Done.
| |
20 // TODO(efortuna): Change the expectation once we have a functioning date | 131 // With the apparent removal of recursivelyMatches these don't work. |
21 // formatting class. | 132 expect( |
22 Expect.stringEquals(date.toString(), date_format.format(date)); | 133 (date_format.parsePattern("hh:mm:ss")).map((x)=>x.string), |
Emily Fortuna
2012/07/31 05:52:53
extra paren here starting
Alan Knight
2012/08/03 23:02:15
Done.
| |
23 | 134 orderedEquals(["hh",":", "mm",":","ss"])); |
24 date_format = new DateFormat("hh:mm:ss"); | 135 expect( |
25 Expect.stringEquals(date.toString(), date_format.format(date)); | 136 (date_format.parsePattern("hh:mm:ss")).map((x)=>x.string), |
26 }); | 137 orderedEquals(["hh",":", "mm",":","ss"])); |
27 | 138 var types = ['FIELD', 'LITERAL', 'FIELD' ,'LITERAL' ,'FIELD']; |
28 test('Date parsing', () { | 139 expect(date_format.parsePattern("hh:mm:ss").map((x)=>x.type), |
29 var date_format = new DateFormat.fullDate(); | 140 orderedEquals(types)); |
Emily Fortuna
2012/07/31 05:52:53
test some other cases for parsing?
Alan Knight
2012/08/03 23:02:15
Possible, although this functionality is also well
| |
30 Date date = new Date.now(); | 141 }); |
31 // TODO(efortuna): Change the expectation once we have a functioning date | 142 |
32 // formatting class. | 143 test('Test ALL the supported formats on representative locales', () { |
33 Expect.stringEquals(date_format.parse(date.toString()), date.toString()); | 144 var aDate = new Date(2012,1,27,20,58,59,0,false); |
145 testLocale("en_US", English, aDate); | |
146 testLocale("de_DE", German, aDate); | |
147 testLocale("fr_FR", French, aDate); | |
148 testLocale("ja_JP", Japanese, aDate); | |
149 testLocale("el_GR", Greek, aDate); | |
150 testLocale("de_AT", Austrian, aDate); | |
151 }); | |
152 | |
153 test('Test round-trip parsing of dates', () { | |
154 var hours = [0, 1, 11, 12, 13, 23]; | |
155 var months = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]; | |
156 var locales = dateTimePatterns.getKeys(); | |
157 for (var locale in locales) { | |
158 for (var month in months) { | |
159 var aDate = new Date(2012,month,27,13,58,59,012,false); | |
160 testRoundTripParsing(locale, aDate); | |
161 } | |
162 for (var hour in hours) { | |
163 var aDate = new Date(2012,1,27,hour,58,59,123,false); | |
164 testRoundTripParsing(locale, aDate); | |
165 } | |
166 } | |
167 }); | |
168 | |
169 test('Patterns and symbols have the same coverage',() { | |
170 var patterns = ["en_ISO"]; | |
171 patterns.addAll(dateTimePatterns.getKeys()); | |
172 var compare = (a,b) => a.compareTo(b); | |
173 patterns.sort(compare); | |
174 var symbols = dateTimeSymbols.getKeys() as List; | |
175 symbols.sort(compare); | |
176 expect(patterns.length, equals(symbols.length)); | |
177 for (var i = 0; i < patterns.length; i++) | |
178 expect(patterns[i], equals(symbols[i])); | |
179 }); | |
180 | |
181 test('Test malformed locales', () { | |
182 var aDate = new Date(2012,1,27,20,58,59,0,false); | |
183 // Austrian is a useful test locale here because it differs slightly | |
184 // from the generic "de" locale so we can tell the difference between | |
185 // correcting to "de_AT" and falling back to just "de". | |
186 testLocale('de-AT', Austrian, aDate); | |
187 testLocale('de_at', Austrian,aDate); | |
188 testLocale('de-at', Austrian,aDate); | |
189 // testLocale('fr-fr', French, aDate); | |
190 }); | |
191 | |
192 test('Test format creation via Intl', () { | |
193 var staticDefaultLocale = Intl.Date('jms'); | |
194 var staticWithLocale = Intl.Date('jms','ja_JP'); | |
195 var intl = new Intl('ja_JP'); | |
196 var instanceJP = intl.date('jms'); | |
197 var instanceUS = intl.date('jms', 'en_US'); | |
198 var blank = intl.date(); | |
199 blank.pattern = 'jms'; | |
200 var date = new Date(2012,1,27,20,58,59,0,false); | |
201 expect(staticDefaultLocale.format(date),equals("8:58:59 PM")); | |
202 expect(staticWithLocale.format(date),equals("20:58:59")); | |
203 expect(instanceJP.format(date),equals("20:58:59")); | |
204 expect(instanceUS.format(date),equals("8:58:59 PM")); | |
205 expect(blank.format(date), equals("20:58:59")); | |
206 }); | |
207 | |
208 test('Test explicit format string', () { | |
209 var aDate = new Date(2012,1,27,20,58,59,0,false); | |
210 // An explicit format that doesn't conform to any skeleton | |
211 var us = new DateFormat('yy //// :D \\\\ dd:ss ^&@ M'); | |
212 expect(us.format(aDate), equals("12 //// :D \\\\ 27:59 ^&@ 1")); | |
213 // The result won't change with locale unless we use fields that are words. | |
214 var greek = new DateFormat('yy //// :D \\\\ dd:ss ^&@ M', 'el_GR'); | |
215 expect(greek.format(aDate), equals("12 //// :D \\\\ 27:59 ^&@ 1")); | |
216 var usWithWords = new DateFormat('yy / :D \ dd:ss ^&@ MMM', 'en_US'); | |
217 var greekWithWords = new DateFormat('yy / :D \ dd:ss ^&@ MMM', 'el_GR'); | |
218 expect( | |
219 usWithWords.format(aDate), | |
220 equals("12 / :D \ 27:59 ^&@ Jan")); | |
221 expect( | |
222 greekWithWords.format(aDate), | |
223 equals("12 / :D \ 27:59 ^&@ Ιαν")); | |
224 var escaped = new DateFormat("hh 'o''clock'"); | |
225 expect(escaped.format(aDate),equals("08 o'clock")); | |
226 var reParsed = escaped.parse(escaped.format(aDate)); | |
227 expect(escaped.format(reParsed), equals(escaped.format(aDate))); | |
228 }); | |
229 | |
230 test('Test fractional seconds padding', () { | |
231 var one = new Date(2012,1,27,20,58,59,1,false); | |
232 var oneHundred = new Date(2012,1,27,20,58,59,100,false); | |
233 var fractional = new DateFormat('hh:mm:ss.SSS', 'en_US'); | |
234 expect(fractional.format(one),equals('08:58:59.001')); | |
235 expect(fractional.format(oneHundred),equals('08:58:59.100')); | |
236 var long = new DateFormat('ss.SSSSSSSS', 'en_US'); | |
237 expect(long.format(oneHundred),equals('59.10000000')); | |
238 expect(long.format(one),equals('59.00100000')); | |
34 }); | 239 }); |
35 } | 240 } |
241 | |
242 /** | |
243 * Exercise all of the formats we have explicitly defined on a particular | |
244 * locale. Expects to be given a Map from ICU constant names to the | |
Emily Fortuna
2012/07/31 05:52:53
info about the parameters? nit: Can this function
Alan Knight
2012/08/03 23:02:15
Done.
| |
245 * expected result. | |
246 */ | |
247 testLocale(String localeName, Map expectedResults, Date date) { | |
248 var intl = new Intl(localeName); | |
249 for(int i=0; i<formatsToTest.length;i++) { | |
Emily Fortuna
2012/07/31 05:52:53
spacing. i < formatsToTest.length; i++ here and ot
Alan Knight
2012/08/03 23:02:15
Done.
| |
250 var skeleton = formatsToTest[i]; | |
251 var format = intl.date(skeleton); | |
252 var icuName = icuFormatNamesToTest[i]; | |
253 //Some useful statements to uncomment if you have to debug incorrect results. | |
254 // print("Expect: ${expectedResults[formatName]} from format $formatName " | |
Emily Fortuna
2012/07/31 05:52:53
cut commented out code :-/
Alan Knight
2012/08/03 23:02:15
Done.
| |
255 // "($formatString) which resolves to "); | |
256 // print("${dateTimePatterns[format.locale][formatString]}"); | |
257 // print("Actual Result: ${format.format(date)}"); | |
258 var actualResult = format.format(date); | |
259 expect(expectedResults[icuName],equals(actualResult)); | |
Emily Fortuna
2012/07/31 05:52:53
spacing after ,
Alan Knight
2012/08/03 23:02:15
Done.
| |
260 } | |
261 } | |
262 | |
263 testRoundTripParsing(String localeName, Date date) { | |
264 // In order to test parsing, we can't just read back the date, because | |
265 // printing in most formats loses information. But we can test that | |
266 // what we parsed back prints the same as what we originally printed. | |
267 // At least in most cases. In some cases, we can't even do that. e.g. | |
268 // the skeleton WEEKDAY can't be reconstructed at all, and YEAR_MONTH | |
269 // formats don't give us enough information to construct a valid date. | |
270 var badSkeletons = [ | |
271 DateFormat.ABBR_WEEKDAY, | |
272 DateFormat.WEEKDAY, | |
273 DateFormat.QUARTER, | |
274 DateFormat.ABBR_QUARTER, | |
275 DateFormat.YEAR, | |
276 DateFormat.YEAR_NUM_MONTH, | |
277 DateFormat.YEAR_ABBR_MONTH, | |
278 DateFormat.YEAR_MONTH]; | |
279 for(int i=0; i<formatsToTest.length;i++) { | |
280 var skeleton = formatsToTest[i]; | |
281 var format = new DateFormat(skeleton,localeName); | |
Emily Fortuna
2012/07/31 05:52:53
space after ,
Alan Knight
2012/08/03 23:02:15
Done.
| |
282 var badPatterns = badSkeletons.map( | |
283 (x) => new DateFormat(x,format.locale).pattern); | |
284 if (!badPatterns.some((x) => x == format.pattern)) { | |
Emily Fortuna
2012/07/31 05:52:53
?
Alan Knight
2012/08/03 23:02:15
If this format's pattern is not in the list of pat
| |
285 var actualResult = format.format(date); | |
286 var parsed = format.parse(actualResult); | |
287 var thenPrintAgain = format.format(parsed); | |
288 expect(thenPrintAgain,equals(actualResult)); | |
Emily Fortuna
2012/07/31 05:52:53
space after , .
Alan Knight
2012/08/03 23:02:15
Done.
| |
289 } | |
290 } | |
291 } | |
292 | |
293 | |
OLD | NEW |