Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1393)

Unified Diff: tests/lib/i18n/date_time_format_test.dart

Issue 10807096: Add date formatting and parsing code. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: tests/lib/i18n/date_time_format_test.dart
===================================================================
--- tests/lib/i18n/date_time_format_test.dart (revision 8510)
+++ tests/lib/i18n/date_time_format_test.dart (working copy)
@@ -4,32 +4,290 @@
* BSD-style license that can be found in the LICENSE file.
*/
-#library('date_time_format_test');
-
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
#import('../../../lib/i18n/date_format.dart');
#import('../../../lib/unittest/unittest.dart');
+#import('../../../lib/i18n/date_time_patterns.dart');
+#import('../../../lib/i18n/date_symbol_data.dart');
+#import('../../../lib/i18n/intl.dart');
+#source('date_time_format_test_data.dart');
+
/**
* Tests the DateFormat library in dart.
*/
+var formatsToTest =
+ 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.
+ DateFormat.DAY,
+ DateFormat.ABBR_WEEKDAY,
+ DateFormat.WEEKDAY,
+ DateFormat.ABBR_STANDALONE_MONTH,
+ DateFormat.STANDALONE_MONTH,
+ DateFormat.NUM_MONTH,
+ DateFormat.NUM_MONTH_DAY,
+ DateFormat.NUM_MONTH_WEEKDAY_DAY,
+ DateFormat.ABBR_MONTH,
+ DateFormat.ABBR_MONTH_DAY,
+ DateFormat.ABBR_MONTH_WEEKDAY_DAY,
+ DateFormat.MONTH,
+ DateFormat.MONTH_DAY,
+ DateFormat.MONTH_WEEKDAY_DAY,
+ DateFormat.ABBR_QUARTER,
+ DateFormat.QUARTER,
+ DateFormat.YEAR,
+ DateFormat.YEAR_NUM_MONTH,
+ DateFormat.YEAR_NUM_MONTH_DAY,
+ DateFormat.YEAR_NUM_MONTH_WEEKDAY_DAY,
+ DateFormat.YEAR_ABBR_MONTH,
+ DateFormat.YEAR_ABBR_MONTH_DAY,
+ DateFormat.YEAR_ABBR_MONTH_WEEKDAY_DAY,
+ DateFormat.YEAR_MONTH,
+ DateFormat.YEAR_MONTH_DAY,
+ DateFormat.YEAR_MONTH_WEEKDAY_DAY,
+//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.
+// DateFormat.YEAR_ABBR_QUARTER,
+// DateFormat.YEAR_QUARTER,
+ DateFormat.HOUR24,
+ DateFormat.HOUR24_MINUTE,
+ DateFormat.HOUR24_MINUTE_SECOND,
+ DateFormat.HOUR,
+ DateFormat.HOUR_MINUTE,
+ DateFormat.HOUR_MINUTE_SECOND,
+// TODO(alanknight): Time zone support
+// DateFormat.HOUR_MINUTE_GENERIC_TZ,
+// DateFormat.HOUR_MINUTE_TZ,
+// DateFormat.HOUR_GENERIC_TZ,
+// DateFormat.HOUR_TZ,
+ DateFormat.MINUTE,
+ DateFormat.MINUTE_SECOND,
+ DateFormat.SECOND
+// ABBR_GENERIC_TZ,
+// GENERIC_TZ,
+// ABBR_SPECIFIC_TZ,
+// SPECIFIC_TZ,
+// ABBR_UTC_TZ
+ ];
+
+var icuFormatNamesToTest =
+// It would be really nice to not have to duplicate this and just be able
+// to use the names to get reflective access.
+ const [
+ "DAY",
+ "ABBR_WEEKDAY",
+ "WEEKDAY",
+ "ABBR_STANDALONE_MONTH",
+ "STANDALONE_MONTH",
+ "NUM_MONTH",
+ "NUM_MONTH_DAY",
+ "NUM_MONTH_WEEKDAY_DAY",
+ "ABBR_MONTH",
+ "ABBR_MONTH_DAY",
+ "ABBR_MONTH_WEEKDAY_DAY",
+ "MONTH",
+ "MONTH_DAY",
+ "MONTH_WEEKDAY_DAY",
+ "ABBR_QUARTER",
+ "QUARTER",
+ "YEAR",
+ "YEAR_NUM_MONTH",
+ "YEAR_NUM_MONTH_DAY",
+ "YEAR_NUM_MONTH_WEEKDAY_DAY",
+ "YEAR_ABBR_MONTH",
+ "YEAR_ABBR_MONTH_DAY",
+ "YEAR_ABBR_MONTH_WEEKDAY_DAY",
+ "YEAR_MONTH",
+ "YEAR_MONTH_DAY",
+ "YEAR_MONTH_WEEKDAY_DAY",
+//TODO(alanknight): CLDR and ICU appear to disagree on these for Japanese.
+// omit for the time being
+// "YEAR_ABBR_QUARTER",
+// "YEAR_QUARTER",
+ "HOUR24",
+ "HOUR24_MINUTE",
+ "HOUR24_MINUTE_SECOND",
+ "HOUR",
+ "HOUR_MINUTE",
+ "HOUR_MINUTE_SECOND",
+// TODO(alanknight): Time zone support
+// "HOUR_MINUTE_GENERIC_TZ",
+// "HOUR_MINUTE_TZ",
+// "HOUR_GENERIC_TZ",
+// "HOUR_TZ",
+ "MINUTE",
+ "MINUTE_SECOND",
+ "SECOND"
+// ABBR_GENERIC_TZ,
+// GENERIC_TZ,
+// ABBR_SPECIFIC_TZ,
+// SPECIFIC_TZ,
+// ABBR_UTC_TZ
+ ];
+
+
main() {
- test('Date formatting', () {
- var date_format = new DateFormat.fullDate();
- Date date = new Date.now();
- // TODO(efortuna): Change the expectation once we have a functioning date
- // formatting class.
- Expect.stringEquals(date.toString(), date_format.format(date));
-
- date_format = new DateFormat("hh:mm:ss");
- Expect.stringEquals(date.toString(), date_format.format(date));
+
Emily Fortuna 2012/07/31 05:52:53 extra whitespace
Alan Knight 2012/08/03 23:02:15 Done.
+ test('Basic date format parsing', () {
+ var date_format = new DateFormat();
Emily Fortuna 2012/07/31 05:52:53 indentation. please!
Alan Knight 2012/08/03 23:02:15 Done.
+ // With the apparent removal of recursivelyMatches these don't work.
+ expect(
+ (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.
+ orderedEquals(["hh",":", "mm",":","ss"]));
+ expect(
+ (date_format.parsePattern("hh:mm:ss")).map((x)=>x.string),
+ orderedEquals(["hh",":", "mm",":","ss"]));
+ var types = ['FIELD', 'LITERAL', 'FIELD' ,'LITERAL' ,'FIELD'];
+ expect(date_format.parsePattern("hh:mm:ss").map((x)=>x.type),
+ 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
});
- test('Date parsing', () {
- var date_format = new DateFormat.fullDate();
- Date date = new Date.now();
- // TODO(efortuna): Change the expectation once we have a functioning date
- // formatting class.
- Expect.stringEquals(date_format.parse(date.toString()), date.toString());
+ test('Test ALL the supported formats on representative locales', () {
+ var aDate = new Date(2012,1,27,20,58,59,0,false);
+ testLocale("en_US", English, aDate);
+ testLocale("de_DE", German, aDate);
+ testLocale("fr_FR", French, aDate);
+ testLocale("ja_JP", Japanese, aDate);
+ testLocale("el_GR", Greek, aDate);
+ testLocale("de_AT", Austrian, aDate);
});
+
+ test('Test round-trip parsing of dates', () {
+ var hours = [0, 1, 11, 12, 13, 23];
+ var months = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
+ var locales = dateTimePatterns.getKeys();
+ for (var locale in locales) {
+ for (var month in months) {
+ var aDate = new Date(2012,month,27,13,58,59,012,false);
+ testRoundTripParsing(locale, aDate);
+ }
+ for (var hour in hours) {
+ var aDate = new Date(2012,1,27,hour,58,59,123,false);
+ testRoundTripParsing(locale, aDate);
+ }
+ }
+ });
+
+ test('Patterns and symbols have the same coverage',() {
+ var patterns = ["en_ISO"];
+ patterns.addAll(dateTimePatterns.getKeys());
+ var compare = (a,b) => a.compareTo(b);
+ patterns.sort(compare);
+ var symbols = dateTimeSymbols.getKeys() as List;
+ symbols.sort(compare);
+ expect(patterns.length, equals(symbols.length));
+ for (var i = 0; i < patterns.length; i++)
+ expect(patterns[i], equals(symbols[i]));
+ });
+
+ test('Test malformed locales', () {
+ var aDate = new Date(2012,1,27,20,58,59,0,false);
+ // Austrian is a useful test locale here because it differs slightly
+ // from the generic "de" locale so we can tell the difference between
+ // correcting to "de_AT" and falling back to just "de".
+ testLocale('de-AT', Austrian, aDate);
+ testLocale('de_at', Austrian,aDate);
+ testLocale('de-at', Austrian,aDate);
+ // testLocale('fr-fr', French, aDate);
+ });
+
+ test('Test format creation via Intl', () {
+ var staticDefaultLocale = Intl.Date('jms');
+ var staticWithLocale = Intl.Date('jms','ja_JP');
+ var intl = new Intl('ja_JP');
+ var instanceJP = intl.date('jms');
+ var instanceUS = intl.date('jms', 'en_US');
+ var blank = intl.date();
+ blank.pattern = 'jms';
+ var date = new Date(2012,1,27,20,58,59,0,false);
+ expect(staticDefaultLocale.format(date),equals("8:58:59 PM"));
+ expect(staticWithLocale.format(date),equals("20:58:59"));
+ expect(instanceJP.format(date),equals("20:58:59"));
+ expect(instanceUS.format(date),equals("8:58:59 PM"));
+ expect(blank.format(date), equals("20:58:59"));
+ });
+
+ test('Test explicit format string', () {
+ var aDate = new Date(2012,1,27,20,58,59,0,false);
+ // An explicit format that doesn't conform to any skeleton
+ var us = new DateFormat('yy //// :D \\\\ dd:ss ^&@ M');
+ expect(us.format(aDate), equals("12 //// :D \\\\ 27:59 ^&@ 1"));
+ // The result won't change with locale unless we use fields that are words.
+ var greek = new DateFormat('yy //// :D \\\\ dd:ss ^&@ M', 'el_GR');
+ expect(greek.format(aDate), equals("12 //// :D \\\\ 27:59 ^&@ 1"));
+ var usWithWords = new DateFormat('yy / :D \ dd:ss ^&@ MMM', 'en_US');
+ var greekWithWords = new DateFormat('yy / :D \ dd:ss ^&@ MMM', 'el_GR');
+ expect(
+ usWithWords.format(aDate),
+ equals("12 / :D \ 27:59 ^&@ Jan"));
+ expect(
+ greekWithWords.format(aDate),
+ equals("12 / :D \ 27:59 ^&@ Ιαν"));
+ var escaped = new DateFormat("hh 'o''clock'");
+ expect(escaped.format(aDate),equals("08 o'clock"));
+ var reParsed = escaped.parse(escaped.format(aDate));
+ expect(escaped.format(reParsed), equals(escaped.format(aDate)));
+ });
+
+ test('Test fractional seconds padding', () {
+ var one = new Date(2012,1,27,20,58,59,1,false);
+ var oneHundred = new Date(2012,1,27,20,58,59,100,false);
+ var fractional = new DateFormat('hh:mm:ss.SSS', 'en_US');
+ expect(fractional.format(one),equals('08:58:59.001'));
+ expect(fractional.format(oneHundred),equals('08:58:59.100'));
+ var long = new DateFormat('ss.SSSSSSSS', 'en_US');
+ expect(long.format(oneHundred),equals('59.10000000'));
+ expect(long.format(one),equals('59.00100000'));
+ });
}
+
+/**
+ * Exercise all of the formats we have explicitly defined on a particular
+ * 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.
+ * expected result.
+ */
+testLocale(String localeName, Map expectedResults, Date date) {
+ var intl = new Intl(localeName);
+ 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.
+ var skeleton = formatsToTest[i];
+ var format = intl.date(skeleton);
+ var icuName = icuFormatNamesToTest[i];
+//Some useful statements to uncomment if you have to debug incorrect results.
+// 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.
+// "($formatString) which resolves to ");
+// print("${dateTimePatterns[format.locale][formatString]}");
+// print("Actual Result: ${format.format(date)}");
+ var actualResult = format.format(date);
+ expect(expectedResults[icuName],equals(actualResult));
Emily Fortuna 2012/07/31 05:52:53 spacing after ,
Alan Knight 2012/08/03 23:02:15 Done.
+ }
+}
+
+testRoundTripParsing(String localeName, Date date) {
+ // In order to test parsing, we can't just read back the date, because
+ // printing in most formats loses information. But we can test that
+ // what we parsed back prints the same as what we originally printed.
+ // At least in most cases. In some cases, we can't even do that. e.g.
+ // the skeleton WEEKDAY can't be reconstructed at all, and YEAR_MONTH
+ // formats don't give us enough information to construct a valid date.
+ var badSkeletons = [
+ DateFormat.ABBR_WEEKDAY,
+ DateFormat.WEEKDAY,
+ DateFormat.QUARTER,
+ DateFormat.ABBR_QUARTER,
+ DateFormat.YEAR,
+ DateFormat.YEAR_NUM_MONTH,
+ DateFormat.YEAR_ABBR_MONTH,
+ DateFormat.YEAR_MONTH];
+ for(int i=0; i<formatsToTest.length;i++) {
+ var skeleton = formatsToTest[i];
+ 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.
+ var badPatterns = badSkeletons.map(
+ (x) => new DateFormat(x,format.locale).pattern);
+ 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
+ var actualResult = format.format(date);
+ var parsed = format.parse(actualResult);
+ var thenPrintAgain = format.format(parsed);
+ expect(thenPrintAgain,equals(actualResult));
Emily Fortuna 2012/07/31 05:52:53 space after , .
Alan Knight 2012/08/03 23:02:15 Done.
+ }
+ }
+}
+
+

Powered by Google App Engine
This is Rietveld 408576698