v8/test/intl/date-format/format-range-to-parts.js
Frank Tang 8034b0568b [Intl] Implement Intl.DateTimeFormat.prototype.formatRangeToParts
Design Doc: https://goo.gl/PGUQ1d

Use template to share code between formatRange and formatRangeToParts
Lazy crate DateIntervalFormat inside formatRange/formatRangeToParts to
reduce performance impact.

Bug: v8:7729
Change-Id: I130748a5ff7ca11235e6608195d365e58d440580
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1556573
Commit-Queue: Frank Tang <ftang@chromium.org>
Reviewed-by: Sathya Gunasekaran <gsathya@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60930}
2019-04-19 01:58:36 +00:00

84 lines
3.3 KiB
JavaScript

// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-intl-date-format-range
let descriptor = Object.getOwnPropertyDescriptor(
Intl.DateTimeFormat.prototype, "formatRangeToParts");
assertTrue(descriptor.writable);
assertFalse(descriptor.enumerable);
assertTrue(descriptor.configurable);
const date1 = new Date("2019-1-3");
const date2 = new Date("2019-1-5");
const date3 = new Date("2019-3-4");
const date4 = new Date("2020-3-4");
let dtf = new Intl.DateTimeFormat();
assertThrows(() => dtf.formatRangeToParts(), RangeError);
assertThrows(() => dtf.formatRangeToParts(date1), RangeError);
assertThrows(() => dtf.formatRangeToParts(undefined, date2), RangeError);
assertThrows(() => dtf.formatRangeToParts(date1, undefined), RangeError);
assertThrows(() => dtf.formatRangeToParts("2019-1-3", date2), RangeError);
assertThrows(() => dtf.formatRangeToParts(date1, "2019-5-4"), RangeError);
assertThrows(() => dtf.formatRangeToParts(date2, date1), RangeError);
assertDoesNotThrow(() =>dtf.formatRangeToParts(date1, date2));
function partsToString(parts) {
return parts.map(x => x.value).join("");
}
const validSources = ["startRange", "endRange", "shared"];
const validTypes = ["literal", "year", "month", "day", "hour", "minute", "second",
"weekday", "dayPeriod", "timeZoneName", "era"];
function assertParts(parts) {
const str = partsToString(parts);
parts.forEach(function(part) {
// Check the range of part.source
assertTrue(validSources.includes(part.source),
"Invalid source '" + part.source + "' in '" + str + "' for '" + part.value + "'");
// Check the range of part.type
assertTrue(validTypes.includes(part.type),
"Invalid type '" + part.type + "' in '" + str + "' for '" + part.value + "'");
// Check the part.value is a string
assertEquals("string", typeof part.value, "Invalid value for '" + str + "'");
});
}
function verifyFormatRangeToParts(a, b, dtf) {
var parts = dtf.formatRangeToParts(a, b);
// Check each parts fulfill basic property of the parts.
assertParts(parts);
// ensure the 'value' in the parts is the same as the output of
// the formatRange.
assertEquals(dtf.formatRange(a, b), partsToString(parts));
}
verifyFormatRangeToParts(date1, date2, dtf);
verifyFormatRangeToParts(date1, date3, dtf);
verifyFormatRangeToParts(date1, date4, dtf);
verifyFormatRangeToParts(date2, date3, dtf);
verifyFormatRangeToParts(date2, date4, dtf);
verifyFormatRangeToParts(date3, date4, dtf);
dtf = new Intl.DateTimeFormat(["en"], {year: "numeric", month: "short", day: "numeric"});
verifyFormatRangeToParts(date1, date2, dtf);
verifyFormatRangeToParts(date1, date3, dtf);
verifyFormatRangeToParts(date1, date4, dtf);
verifyFormatRangeToParts(date2, date3, dtf);
verifyFormatRangeToParts(date2, date4, dtf);
verifyFormatRangeToParts(date3, date4, dtf);
// Test the sequence of ToNumber and TimeClip
var secondDateAccessed = false;
assertThrows(
() =>
dtf.formatRangeToParts(
new Date(864000000*10000000 + 1), // a date will cause TimeClip return NaN
{ get [Symbol.toPrimitive]() { secondDateAccessed = true; return {}} }),
TypeError);
assertTrue(secondDateAccessed);