summaryrefslogtreecommitdiffstats
path: root/js/src/tests/test262/intl402/DateTimeFormat
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/tests/test262/intl402/DateTimeFormat')
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/browser.js0
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/builtin.js21
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/casing-numbering-system-calendar-options.js45
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/constructor-calendar-numberingSystem-order.js51
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/constructor-default-value.js25
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/constructor-options-calendar-invalid.js42
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/constructor-options-dateStyle-invalid.js31
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/constructor-options-dateStyle-valid.js39
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/constructor-options-dayPeriod-invalid.js31
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/constructor-options-dayPeriod-valid.js37
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/constructor-options-fractionalSecondDigits-invalid.js37
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/constructor-options-fractionalSecondDigits-valid.js40
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/constructor-options-numberingSystem-invalid.js42
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/constructor-options-order-dayPeriod.js51
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/constructor-options-order-fractionalSecondDigits.js69
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/constructor-options-order-timedate-style.js136
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/constructor-options-order.js116
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/constructor-options-throwing-getters-dayPeriod.js27
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/constructor-options-throwing-getters-fractionalSecondDigits.js26
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/constructor-options-throwing-getters-timedate-style.js31
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/constructor-options-throwing-getters.js33
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/constructor-options-timeStyle-invalid.js31
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/constructor-options-timeStyle-valid.js38
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/constructor-options-toobject.js44
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/date-time-options.js106
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/default-options-object-prototype.js22
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/ignore-invalid-unicode-ext-values.js39
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/instance-proto-and-extensible.js19
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/intl-legacy-constructed-symbol-on-unwrap.js34
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/intl-legacy-constructed-symbol.js20
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/legacy-regexp-statics-not-modified.js21
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/length.js33
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/name.js28
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/numbering-system-calendar-options.js69
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prop-desc.js31
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/proto-from-ctor-realm.js60
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/browser.js0
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/builtin.js18
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/constructor/browser.js0
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/constructor/prop-desc.js31
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/constructor/shell.js0
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/constructor/value.js14
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/format/bound-to-datetimeformat-instance.js30
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/format/browser.js0
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/format/builtin.js33
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/format/date-constructor-not-called.js38
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/format/dayPeriod-long-en.js96
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/format/dayPeriod-narrow-en.js96
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/format/dayPeriod-short-en.js96
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/format/format-function-builtin.js33
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/format/format-function-length.js30
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/format/format-function-name.js28
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/format/fractionalSecondDigits.js34
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/format/length.js35
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/format/name.js30
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/format/proleptic-gregorian-calendar.js31
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/format/prop-desc.js37
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/format/related-year-zh.js19
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/format/shell.js50
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/format/taint-Object-prototype.js18
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/format/throws-value-non-finite.js20
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/format/time-clip-near-time-boundaries.js39
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/format/time-clip-to-integer.js39
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/format/timedatestyle-en.js106
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/argument-date-string.js42
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/argument-near-time-boundaries.js50
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/argument-to-integer.js42
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/argument-tonumber-throws.js57
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/browser.js0
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/builtin.js33
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/date-is-infinity-throws.js73
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/date-is-nan-throws.js50
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/date-same-returns-single-date.js64
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/date-undefined-throws.js45
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/date-x-greater-than-y-throws.js40
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/en-US.js39
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/fractionalSecondDigits.js36
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/length.js17
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/name.js17
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/prop-desc.js24
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/shell.js50
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/this-bad-object.js29
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/this-is-not-object-throws.js50
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/argument-date-string.js42
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/argument-near-time-boundaries.js50
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/argument-to-integer.js57
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/argument-tonumber-throws.js57
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/browser.js0
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/builtin.js33
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/date-is-infinity-throws.js72
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/date-is-nan-throws.js50
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/date-same-returns-single-date.js79
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/date-undefined-throws.js44
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/date-x-greater-than-y-throws.js39
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/en-US.js202
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/fractionalSecondDigits.js154
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/length.js17
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/name.js17
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/pattern-on-calendar.js58
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/prop-desc.js24
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/shell.js50
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/this-bad-object.js29
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/this-is-not-object-throws.js50
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/browser.js0
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/date-constructor-not-called.js38
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/date-is-infinity-throws.js35
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/date-is-nan-throws.js35
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/dayPeriod-long-en.js109
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/dayPeriod-narrow-en.js109
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/dayPeriod-short-en.js109
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/formatToParts.js19
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/fractionalSecondDigits.js69
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/length.js15
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/main.js75
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/name.js15
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/pattern-on-calendar.js55
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/related-year-zh.js35
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/related-year.js23
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/return-abrupt-tonumber-date.js44
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/shell.js31
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/this-has-not-internal-throws.js19
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/this-is-not-object-throws.js40
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/time-clip-near-time-boundaries.js39
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/time-clip-to-integer.js43
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/prop-desc.js19
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/basic.js75
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/browser.js0
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/builtin.js30
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/hourCycle-dateStyle.js69
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/hourCycle-default.js58
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/hourCycle-timeStyle.js89
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/hourCycle.js101
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/length.js33
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/name.js28
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/order-dayPeriod.js40
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/order-fractionalSecondDigits.js37
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/order-style.js43
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/order.js51
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/prop-desc.js31
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/resolved-locale-with-hc-unicode.js89
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/shell.js50
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/shell.js0
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/this-value-datetimeformat-prototype.js17
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/this-value-not-datetimeformat.js28
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/toStringTag/browser.js0
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/toStringTag/shell.js0
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/toStringTag/toString-changed-tag.js30
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/toStringTag/toString-removed-tag.js24
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/toStringTag/toString.js26
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/prototype/toStringTag/toStringTag.js25
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/required-date-time-formats.js48
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/shell.js0
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/subclassing.js30
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/basic.js25
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/browser.js0
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/builtin.js30
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/length.js33
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/name.js28
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/prop-desc.js31
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/shell.js19
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/taint-Object-prototype.js16
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/taint-Object-prototype-date-time-components.js18
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/taint-Object-prototype-dayPeriod.js19
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/taint-Object-prototype-fractionalSecondDigits.js18
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/taint-Object-prototype.js18
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/test-option-date-time-components.js17
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/test-option-formatMatcher.js13
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/test-option-hour12.js16
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/test-option-localeMatcher.js13
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/this-value-ignored.js37
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/timezone-canonicalized.js37
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/timezone-invalid.js28
-rw-r--r--js/src/tests/test262/intl402/DateTimeFormat/timezone-utc.js21
173 files changed, 6873 insertions, 0 deletions
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/browser.js b/js/src/tests/test262/intl402/DateTimeFormat/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/browser.js
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/builtin.js b/js/src/tests/test262/intl402/DateTimeFormat/builtin.js
new file mode 100644
index 0000000000..abffae0582
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/builtin.js
@@ -0,0 +1,21 @@
+// Copyright 2012 Mozilla Corporation. All rights reserved.
+// This code is governed by the license found in the LICENSE file.
+
+/*---
+es5id: 12.1_L15
+description: >
+ Tests that Intl.DateTimeFormat meets the requirements for
+ built-in objects defined by the introduction of chapter 17 of the
+ ECMAScript Language Specification.
+author: Norbert Lindenberg
+---*/
+
+assert.sameValue(Object.prototype.toString.call(Intl.DateTimeFormat), "[object Function]",
+ "The [[Class]] internal property of a built-in function must be " +
+ "\"Function\".");
+
+assert(Object.isExtensible(Intl.DateTimeFormat), "Built-in objects must be extensible.");
+
+assert.sameValue(Object.getPrototypeOf(Intl.DateTimeFormat), Function.prototype);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/casing-numbering-system-calendar-options.js b/js/src/tests/test262/intl402/DateTimeFormat/casing-numbering-system-calendar-options.js
new file mode 100644
index 0000000000..0435ec2bae
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/casing-numbering-system-calendar-options.js
@@ -0,0 +1,45 @@
+// Copyright 2020 Google Inc, Igalia S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-initializedatetimeformat
+description: >
+ Tests that the options numberingSystem and calendar are mapped
+ to lower case properly.
+author: Caio Lima
+---*/
+
+let defaultLocale = new Intl.DateTimeFormat().resolvedOptions().locale;
+
+let supportedNumberingSystems = ["latn", "arab"].filter(nu =>
+ new Intl.DateTimeFormat(defaultLocale + "-u-nu-" + nu)
+ .resolvedOptions().numberingSystem === nu
+);
+
+if (supportedNumberingSystems.includes("latn")) {
+ let dateTimeFormat = new Intl.DateTimeFormat(defaultLocale + "-u-nu-lATn");
+ assert.sameValue(dateTimeFormat.resolvedOptions().numberingSystem, "latn", "Numbering system option should be in lower case");
+}
+
+if (supportedNumberingSystems.includes("arab")) {
+ let dateTimeFormat = new Intl.DateTimeFormat(defaultLocale + "-u-nu-Arab");
+ assert.sameValue(dateTimeFormat.resolvedOptions().numberingSystem, "arab", "Numbering system option should be in lower case");
+}
+
+let supportedCalendars = ["gregory", "chinese"].filter(ca =>
+ new Intl.DateTimeFormat(defaultLocale + "-u-ca-" + ca)
+ .resolvedOptions().calendar === ca
+);
+
+if (supportedCalendars.includes("gregory")) {
+ let dateTimeFormat = new Intl.DateTimeFormat(defaultLocale + "-u-ca-Gregory");
+ assert.sameValue(dateTimeFormat.resolvedOptions().calendar, "gregory", "Calendar option should be in lower case");
+}
+
+if (supportedCalendars.includes("chinese")) {
+ let dateTimeFormat = new Intl.DateTimeFormat(defaultLocale + "-u-ca-CHINESE");
+ assert.sameValue(dateTimeFormat.resolvedOptions().calendar, "chinese", "Calendar option should be in lower case");
+}
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/constructor-calendar-numberingSystem-order.js b/js/src/tests/test262/intl402/DateTimeFormat/constructor-calendar-numberingSystem-order.js
new file mode 100644
index 0000000000..d08b114c75
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/constructor-calendar-numberingSystem-order.js
@@ -0,0 +1,51 @@
+// Copyright 2019 Google Inc. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-initializedatetimeformat
+description: >
+ Checks the order of getting "calendar" and "numberingSystem" options in the
+ DateTimeFormat is between "localeMatcher" and "hour12" options.
+info: |
+ 4. Let _matcher_ be ? GetOption(_options_, `"localeMatcher"`, `"string"`, « `"lookup"`, `"best fit"` », `"best fit"`).
+ ...
+ 6. Let _calendar_ be ? GetOption(_options_, `"calendar"`, `"string"`, *undefined*, *undefined*).
+ ...
+ 9. Let _numberingSystem_ be ? GetOption(_options_, `"numberingSystem"`, `"string"`, *undefined*, *undefined*).
+ ...
+ 12. Let _hour12_ be ? GetOption(_options_, `"hour12"`, `"boolean"`, *undefined*, *undefined*).
+includes: [compareArray.js]
+---*/
+
+const actual = [];
+
+const options = {
+ get localeMatcher() {
+ actual.push("localeMatcher");
+ return undefined;
+ },
+ get calendar() {
+ actual.push("calendar");
+ return undefined;
+ },
+ get numberingSystem() {
+ actual.push("numberingSystem");
+ return undefined;
+ },
+ get hour12() {
+ actual.push("hour12");
+ return undefined;
+ },
+};
+
+const expected = [
+ "localeMatcher",
+ "calendar",
+ "numberingSystem",
+ "hour12"
+];
+
+let df = new Intl.DateTimeFormat(undefined, options);
+assert.compareArray(actual, expected);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/constructor-default-value.js b/js/src/tests/test262/intl402/DateTimeFormat/constructor-default-value.js
new file mode 100644
index 0000000000..961bcfec96
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/constructor-default-value.js
@@ -0,0 +1,25 @@
+// Copyright (C) 2018 Ujjwal Sharma. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-initializedatetimeformat
+description: >
+ Tests that the constructor for Intl.DateTimeFormat uses appropriate default
+ values for its arguments (locales and options).
+---*/
+
+const actual = new Intl.DateTimeFormat().resolvedOptions();
+const expected = new Intl.DateTimeFormat(
+ [],
+ Object.create(null)
+).resolvedOptions();
+
+assert.sameValue(actual.locale, expected.locale);
+assert.sameValue(actual.calendar, expected.calendar);
+assert.sameValue(actual.day, expected.day);
+assert.sameValue(actual.month, expected.month);
+assert.sameValue(actual.year, expected.year);
+assert.sameValue(actual.numberingSystem, expected.numberingSystem);
+assert.sameValue(actual.timeZone, expected.timeZone);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-calendar-invalid.js b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-calendar-invalid.js
new file mode 100644
index 0000000000..5ecfd4a6a1
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-calendar-invalid.js
@@ -0,0 +1,42 @@
+// Copyright 2020 André Bargull; Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-initializedatetimeformat
+description: >
+ Checks error cases for the options argument to the DateTimeFormat constructor.
+info: |
+ InitializeDateTimeFormat ( dateTimeFormat, locales, options )
+
+ ...
+ 7. If calendar is not undefined, then
+ a. If calendar does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
+---*/
+
+/*
+ alphanum = (ALPHA / DIGIT) ; letters and numbers
+ numberingSystem = (3*8alphanum) *("-" (3*8alphanum))
+*/
+const invalidCalendarOptions = [
+ "",
+ "a",
+ "ab",
+ "abcdefghi",
+ "abc-abcdefghi",
+ "!invalid!",
+ "-gregory-",
+ "gregory-",
+ "gregory--",
+ "gregory-nu",
+ "gregory-nu-",
+ "gregory-nu-latn",
+ "gregoryé",
+ "gregory역법",
+];
+for (const calendar of invalidCalendarOptions) {
+ assert.throws(RangeError, function() {
+ new Intl.DateTimeFormat('en', {calendar});
+ }, `new Intl.DateTimeFormat("en", {calendar: "${calendar}"}) throws RangeError`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-dateStyle-invalid.js b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-dateStyle-invalid.js
new file mode 100644
index 0000000000..740bcec24f
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-dateStyle-invalid.js
@@ -0,0 +1,31 @@
+// Copyright 2019 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-initializedatetimeformat
+description: >
+ Checks error cases for the options argument to the DateTimeFormat constructor.
+info: |
+ InitializeDateTimeFormat ( dateTimeFormat, locales, options )
+
+ ...
+ 28. Let dateStyle be ? GetOption(options, "dateStyle", "string", « "full", "long", "medium", "short" », undefined).
+features: [Intl.DateTimeFormat-datetimestyle]
+---*/
+
+
+const invalidOptions = [
+ "",
+ "FULL",
+ " long",
+ "short ",
+ "narrow",
+ "numeric",
+];
+for (const dateStyle of invalidOptions) {
+ assert.throws(RangeError, function() {
+ new Intl.DateTimeFormat("en", { dateStyle });
+ }, `new Intl.DateTimeFormat("en", { dateStyle: "${dateStyle}" }) throws RangeError`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-dateStyle-valid.js b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-dateStyle-valid.js
new file mode 100644
index 0000000000..7de1322dcc
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-dateStyle-valid.js
@@ -0,0 +1,39 @@
+// Copyright 2019 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-initializedatetimeformat
+description: >
+ Checks handling of the options argument to the DateTimeFormat constructor.
+info: |
+ InitializeDateTimeFormat ( dateTimeFormat, locales, options )
+
+ ...
+ 28. Let dateStyle be ? GetOption(options, "dateStyle", "string", « "full", "long", "medium", "short" », undefined).
+ 29. If dateStyle is not undefined, set dateTimeFormat.[[DateStyle]] to dateStyle.
+features: [Intl.DateTimeFormat-datetimestyle]
+---*/
+
+
+const validOptions = [
+ [undefined, undefined],
+ ["full", "full"],
+ ["long", "long"],
+ ["medium", "medium"],
+ ["short", "short"],
+ [{ toString() { return "full"; } }, "full"],
+ [{ valueOf() { return "long"; }, toString: undefined }, "long"],
+];
+for (const [dateStyle, expected] of validOptions) {
+ const dtf = new Intl.DateTimeFormat("en", { dateStyle });
+ const options = dtf.resolvedOptions();
+ assert.sameValue(options.dateStyle, expected);
+ const propdesc = Object.getOwnPropertyDescriptor(options, "dateStyle");
+ if (expected === undefined) {
+ assert.sameValue(propdesc, undefined);
+ } else {
+ assert.sameValue(propdesc.value, expected);
+ }
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-dayPeriod-invalid.js b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-dayPeriod-invalid.js
new file mode 100644
index 0000000000..abc9acb7e5
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-dayPeriod-invalid.js
@@ -0,0 +1,31 @@
+// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-dayPeriod is not released yet
+// Copyright 2019 Google Inc. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-initializedatetimeformat
+description: >
+ Checks error cases for the options argument to the DateTimeFormat constructor.
+info: |
+ [[DayPeriod]] `"dayPeriod"` `"narrow"`, `"short"`, `"long"`
+ InitializeDateTimeFormat ( dateTimeFormat, locales, options )
+
+ ...
+features: [Intl.DateTimeFormat-dayPeriod]
+---*/
+
+const invalidOptions = [
+ "",
+ "LONG",
+ " long",
+ "short ",
+ "full",
+ "numeric",
+];
+for (const dayPeriod of invalidOptions) {
+ assert.throws(RangeError, function() {
+ new Intl.DateTimeFormat("en", { dayPeriod });
+ }, `new Intl.DateTimeFormat("en", { dayPeriod: "${dayPeriod}" }) throws RangeError`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-dayPeriod-valid.js b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-dayPeriod-valid.js
new file mode 100644
index 0000000000..07da90bc5c
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-dayPeriod-valid.js
@@ -0,0 +1,37 @@
+// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-dayPeriod is not released yet
+// Copyright 2019 Google Inc. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-initializedatetimeformat
+description: >
+ Checks handling of the options argument to the DateTimeFormat constructor.
+info: |
+ [[DayPeriod]] `"dayPeriod"` `"narrow"`, `"short"`, `"long"`
+ InitializeDateTimeFormat ( dateTimeFormat, locales, options )
+
+ ...
+features: [Intl.DateTimeFormat-dayPeriod]
+---*/
+
+const validOptions = [
+ [undefined, undefined],
+ ["long", "long"],
+ ["short", "short"],
+ ["narrow", "narrow"],
+ [{ toString() { return "narrow"; } }, "narrow"],
+ [{ valueOf() { return "long"; }, toString: undefined }, "long"],
+];
+for (const [dayPeriod, expected] of validOptions) {
+ const dtf = new Intl.DateTimeFormat("en", { dayPeriod });
+ const options = dtf.resolvedOptions();
+ assert.sameValue(options.dayPeriod, expected);
+ const propdesc = Object.getOwnPropertyDescriptor(options, "dayPeriod");
+ if (expected === undefined) {
+ assert.sameValue(propdesc, undefined);
+ } else {
+ assert.sameValue(propdesc.value, expected);
+ }
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-fractionalSecondDigits-invalid.js b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-fractionalSecondDigits-invalid.js
new file mode 100644
index 0000000000..91d017880b
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-fractionalSecondDigits-invalid.js
@@ -0,0 +1,37 @@
+// Copyright 2019 Google Inc. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-initializedatetimeformat
+description: >
+ Checks error cases for the options argument to the DateTimeFormat constructor.
+info: |
+ InitializeDateTimeFormat ( dateTimeFormat, locales, options )
+ 23. Let _opt_.[[FractionalSecondDigits]] be ? GetNumberOption(_options_, `"fractionalSecondDigits"`, 0, 3, 0).
+
+ ...
+features: [Intl.DateTimeFormat-fractionalSecondDigits]
+---*/
+
+
+const invalidOptions = [
+ "LONG",
+ " long",
+ "short ",
+ "full",
+ "numeric",
+ -1,
+ 4,
+ "4",
+ "-1",
+ -0.00001,
+ 3.000001,
+];
+for (const fractionalSecondDigits of invalidOptions) {
+ assert.throws(RangeError, function() {
+ new Intl.DateTimeFormat("en", { fractionalSecondDigits });
+ },
+ `new Intl.DateTimeFormat("en", { fractionalSecondDigits: "${fractionalSecondDigits}" }) throws RangeError`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-fractionalSecondDigits-valid.js b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-fractionalSecondDigits-valid.js
new file mode 100644
index 0000000000..be82eca19b
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-fractionalSecondDigits-valid.js
@@ -0,0 +1,40 @@
+// Copyright 2019 Google Inc. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-initializedatetimeformat
+description: >
+ Checks handling of the options argument to the DateTimeFormat constructor.
+info: |
+ InitializeDateTimeFormat ( dateTimeFormat, locales, options )
+ 23. Let _opt_.[[FractionalSecondDigits]] be ? GetNumberOption(_options_, `"fractionalSecondDigits"`, 0, 3, 0).
+features: [Intl.DateTimeFormat-fractionalSecondDigits]
+---*/
+
+
+const validOptions = [
+ [undefined, undefined],
+ [1, 1],
+ ["1", 1],
+ [2, 2],
+ ["2", 2],
+ [3, 3],
+ ["3", 3],
+ [2.9, 2],
+ ["2.9", 2],
+ [1.00001, 1],
+ [{ toString() { return "3"; } }, 3],
+];
+for (const [fractionalSecondDigits, expected] of validOptions) {
+ const dtf = new Intl.DateTimeFormat("en", { fractionalSecondDigits });
+ const options = dtf.resolvedOptions();
+ assert.sameValue(options.fractionalSecondDigits, expected);
+ const propdesc = Object.getOwnPropertyDescriptor(options, "fractionalSecondDigits");
+ if (expected === undefined) {
+ assert.sameValue(propdesc, undefined);
+ } else {
+ assert.sameValue(propdesc.value, expected);
+ }
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-numberingSystem-invalid.js b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-numberingSystem-invalid.js
new file mode 100644
index 0000000000..c77053a209
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-numberingSystem-invalid.js
@@ -0,0 +1,42 @@
+// Copyright 2020 André Bargull; Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-initializedatetimeformat
+description: >
+ Checks error cases for the options argument to the DateTimeFormat constructor.
+info: |
+ InitializeDateTimeFormat ( dateTimeFormat, locales, options )
+
+ ...
+ 10. If numberingSystem is not undefined, then
+ a. If numberingSystem does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
+---*/
+
+/*
+ alphanum = (ALPHA / DIGIT) ; letters and numbers
+ numberingSystem = (3*8alphanum) *("-" (3*8alphanum))
+*/
+const invalidNumberingSystemOptions = [
+ "",
+ "a",
+ "ab",
+ "abcdefghi",
+ "abc-abcdefghi",
+ "!invalid!",
+ "-latn-",
+ "latn-",
+ "latn--",
+ "latn-ca",
+ "latn-ca-",
+ "latn-ca-gregory",
+ "latné",
+ "latn编号",
+];
+for (const numberingSystem of invalidNumberingSystemOptions) {
+ assert.throws(RangeError, function() {
+ new Intl.DateTimeFormat('en', {numberingSystem});
+ }, `new Intl.DateTimeFormat("en", {numberingSystem: "${numberingSystem}"}) throws RangeError`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-order-dayPeriod.js b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-order-dayPeriod.js
new file mode 100644
index 0000000000..4620f1964a
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-order-dayPeriod.js
@@ -0,0 +1,51 @@
+// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-dayPeriod is not released yet
+// Copyright 2019 Googe Inc. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-initializedatetimeformat
+description: Checks the order of getting options of 'dayPeriod' for the DateTimeFormat constructor.
+info: |
+ ToDateTimeOptions ( options, required, defaults )
+ 4. If required is "date" or "any", then
+ a. For each of the property names "weekday", "year", "month", "day", "dayPeriod" do
+ 5. If required is "time" or "any", then
+ a. For each of the property names "hour", "minute", "second", do
+includes: [compareArray.js]
+features: [Intl.DateTimeFormat-dayPeriod]
+
+---*/
+
+// Just need to ensure dayPeriod are get between day and hour.
+const expected = [
+ // ToDateTimeOptions step 4.
+ "day", "dayPeriod",
+ // ToDateTimeOptions step 5.
+ "hour",
+ // InitializeDateTimeFormat step 22.
+ "day",
+ "dayPeriod",
+ "hour"
+];
+
+const actual = [];
+
+const options = {
+ get day() {
+ actual.push("day");
+ return "numeric";
+ },
+ get dayPeriod() {
+ actual.push("dayPeriod");
+ return "long";
+ },
+ get hour() {
+ actual.push("hour");
+ return "numeric";
+ },
+};
+
+new Intl.DateTimeFormat("en", options);
+assert.compareArray(actual, expected);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-order-fractionalSecondDigits.js b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-order-fractionalSecondDigits.js
new file mode 100644
index 0000000000..1daaba4107
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-order-fractionalSecondDigits.js
@@ -0,0 +1,69 @@
+// Copyright 2019 Googe Inc. All rights reserved.
+// Copyright 2020 Apple Inc. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-initializedatetimeformat
+description: Checks the order of getting options of 'fractionalSecondDigits' for the DateTimeFormat constructor.
+info: |
+ ToDateTimeOptions ( options, required, defaults )
+ 5. If required is "time" or "any", then
+ a. For each of the property names "hour", "minute", "second", "fractionalSecondDigits", do
+
+ InitializeDateTimeFormat ( dateTimeFormat, locales, options )
+ 2. Let options be ? ToDateTimeOptions(options, "any", "date").
+ 4. Let matcher be ? GetOption(options, "localeMatcher", "string", « "lookup", "best fit" », "best fit").
+ 22. For each row of Table 5, except the header row, do
+ a. Let value be ? GetOption(options, prop, "string", « the strings given in the Values column of the row », undefined).
+ 23. Let _opt_.[[FractionalSecondDigits]] be ? GetNumberOption(_options_, `"fractionalSecondDigits"`, 0, 3, 0).
+ 26. Let matcher be ? GetOption(options, "formatMatcher", "string", « "basic", "best fit" », "best fit").
+includes: [compareArray.js]
+features: [Intl.DateTimeFormat-fractionalSecondDigits]
+---*/
+
+// Just need to ensure fractionalSecondDigits are get
+// between second and localeMatcher the first time and
+// between timeZoneName and formatMatcher the second time.
+const expected = [
+ // InitializeDateTimeFormat step 2.
+ // ToDateTimeOptions step 5.
+ "second", "fractionalSecondDigits",
+ // InitializeDateTimeFormat step 4.
+ "localeMatcher",
+ // InitializeDateTimeFormat step 22.
+ "second",
+ "fractionalSecondDigits",
+ "timeZoneName",
+ // InitializeDateTimeFormat step 26.
+ "formatMatcher",
+];
+
+const actual = [];
+
+const options = {
+ get second() {
+ actual.push("second");
+ return "numeric";
+ },
+ get fractionalSecondDigits() {
+ actual.push("fractionalSecondDigits");
+ return undefined;
+ },
+ get localeMatcher() {
+ actual.push("localeMatcher");
+ return undefined;
+ },
+ get timeZoneName() {
+ actual.push("timeZoneName");
+ return undefined;
+ },
+ get formatMatcher() {
+ actual.push("formatMatcher");
+ return undefined;
+ },
+};
+
+new Intl.DateTimeFormat("en", options);
+assert.compareArray(actual, expected);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-order-timedate-style.js b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-order-timedate-style.js
new file mode 100644
index 0000000000..c074860b8f
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-order-timedate-style.js
@@ -0,0 +1,136 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-initializedatetimeformat
+description: Checks the order of getting options for the DateTimeFormat constructor.
+includes: [compareArray.js]
+features: [Intl.DateTimeFormat-datetimestyle]
+---*/
+
+// To be merged into constructor-options-order.js when the feature is removed.
+
+const expected = [
+ // ToDateTimeOptions step 4.
+ "weekday", "year", "month", "day",
+ // ToDateTimeOptions step 5.
+ "hour", "minute", "second",
+ // ToDateTimeOptions step 6.
+ "dateStyle",
+ // ToDateTimeOptions step 7.
+ "timeStyle",
+
+ // InitializeDateTimeFormat step 4.
+ "localeMatcher",
+ // InitializeDateTimeFormat step 6.
+ "hour12",
+ // InitializeDateTimeFormat step 7.
+ "hourCycle",
+ // InitializeDateTimeFormat step 23.
+ "timeZone",
+ // InitializeDateTimeFormat step 28.
+ "weekday",
+ "era",
+ "year",
+ "month",
+ "day",
+ "hour",
+ "minute",
+ "second",
+ "timeZoneName",
+ "formatMatcher",
+ // InitializeDateTimeFormat step 32.
+ "dateStyle",
+ // InitializeDateTimeFormat step 33.
+ "timeStyle",
+];
+
+const actual = [];
+
+const options = {
+ get dateStyle() {
+ actual.push("dateStyle");
+ return undefined;
+ },
+
+ get day() {
+ actual.push("day");
+ return "numeric";
+ },
+
+ get era() {
+ actual.push("era");
+ return "long";
+ },
+
+ get formatMatcher() {
+ actual.push("formatMatcher");
+ return "best fit";
+ },
+
+ get hour() {
+ actual.push("hour");
+ return "numeric";
+ },
+
+ get hour12() {
+ actual.push("hour12");
+ return true;
+ },
+
+ get hourCycle() {
+ actual.push("hourCycle");
+ return "h24";
+ },
+
+ get localeMatcher() {
+ actual.push("localeMatcher");
+ return "best fit";
+ },
+
+ get minute() {
+ actual.push("minute");
+ return "numeric";
+ },
+
+ get month() {
+ actual.push("month");
+ return "numeric";
+ },
+
+ get second() {
+ actual.push("second");
+ return "numeric";
+ },
+
+ get timeStyle() {
+ actual.push("timeStyle");
+ return undefined;
+ },
+
+ get timeZone() {
+ actual.push("timeZone");
+ return "UTC";
+ },
+
+ get timeZoneName() {
+ actual.push("timeZoneName");
+ return "long";
+ },
+
+ get weekday() {
+ actual.push("weekday");
+ return "long";
+ },
+
+ get year() {
+ actual.push("year");
+ return "numeric";
+ },
+};
+
+new Intl.DateTimeFormat("en", options);
+
+assert.compareArray(actual, expected);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-order.js b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-order.js
new file mode 100644
index 0000000000..25dade65e0
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-order.js
@@ -0,0 +1,116 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-initializedatetimeformat
+description: Checks the order of getting options for the DateTimeFormat constructor.
+includes: [compareArray.js]
+---*/
+
+const expected = [
+ // ToDateTimeOptions step 4.
+ "weekday", "year", "month", "day",
+ // ToDateTimeOptions step 5.
+ "hour", "minute", "second",
+
+ // InitializeDateTimeFormat step 4.
+ "localeMatcher",
+ // InitializeDateTimeFormat step 6.
+ "hour12",
+ // InitializeDateTimeFormat step 7.
+ "hourCycle",
+ // InitializeDateTimeFormat step 17.
+ "timeZone",
+ // InitializeDateTimeFormat step 22.
+ "weekday",
+ "era",
+ "year",
+ "month",
+ "day",
+ "hour",
+ "minute",
+ "second",
+ "timeZoneName",
+ // InitializeDateTimeFormat step 25.
+ "formatMatcher",
+];
+
+const actual = [];
+
+const options = {
+ get day() {
+ actual.push("day");
+ return "numeric";
+ },
+
+ get era() {
+ actual.push("era");
+ return "long";
+ },
+
+ get formatMatcher() {
+ actual.push("formatMatcher");
+ return "best fit";
+ },
+
+ get hour() {
+ actual.push("hour");
+ return "numeric";
+ },
+
+ get hour12() {
+ actual.push("hour12");
+ return true;
+ },
+
+ get hourCycle() {
+ actual.push("hourCycle");
+ return "h24";
+ },
+
+ get localeMatcher() {
+ actual.push("localeMatcher");
+ return "best fit";
+ },
+
+ get minute() {
+ actual.push("minute");
+ return "numeric";
+ },
+
+ get month() {
+ actual.push("month");
+ return "numeric";
+ },
+
+ get second() {
+ actual.push("second");
+ return "numeric";
+ },
+
+ get timeZone() {
+ actual.push("timeZone");
+ return "UTC";
+ },
+
+ get timeZoneName() {
+ actual.push("timeZoneName");
+ return "long";
+ },
+
+ get weekday() {
+ actual.push("weekday");
+ return "long";
+ },
+
+ get year() {
+ actual.push("year");
+ return "numeric";
+ },
+};
+
+new Intl.DateTimeFormat("en", options);
+
+assert.compareArray(actual, expected);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-throwing-getters-dayPeriod.js b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-throwing-getters-dayPeriod.js
new file mode 100644
index 0000000000..099438ae65
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-throwing-getters-dayPeriod.js
@@ -0,0 +1,27 @@
+// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-dayPeriod is not released yet
+// Copyright 2019 Google Inc. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-initializedatetimeformat
+description: Checks the propagation of exceptions from the options for the DateTimeFormat constructor.
+features: [Intl.DateTimeFormat-dayPeriod]
+---*/
+
+function CustomError() {}
+
+const options = [
+ "dayPeriod",
+];
+
+for (const option of options) {
+ assert.throws(CustomError, () => {
+ new Intl.DateTimeFormat("en", {
+ get [option]() {
+ throw new CustomError();
+ }
+ });
+ }, `Exception from ${option} getter should be propagated`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-throwing-getters-fractionalSecondDigits.js b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-throwing-getters-fractionalSecondDigits.js
new file mode 100644
index 0000000000..f438e8df97
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-throwing-getters-fractionalSecondDigits.js
@@ -0,0 +1,26 @@
+// Copyright 2019 Google Inc. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-initializedatetimeformat
+description: Checks the propagation of exceptions from the options for the DateTimeFormat constructor.
+features: [Intl.DateTimeFormat-fractionalSecondDigits]
+---*/
+
+function CustomError() {}
+
+const options = [
+ "fractionalSecondDigits",
+];
+
+for (const option of options) {
+ assert.throws(CustomError, () => {
+ new Intl.DateTimeFormat("en", {
+ get [option]() {
+ throw new CustomError();
+ }
+ });
+ }, `Exception from ${option} getter should be propagated`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-throwing-getters-timedate-style.js b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-throwing-getters-timedate-style.js
new file mode 100644
index 0000000000..448acfa175
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-throwing-getters-timedate-style.js
@@ -0,0 +1,31 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-initializedatetimeformat
+description: Checks the propagation of exceptions from the options for the DateTimeFormat constructor.
+features: [Intl.DateTimeFormat-datetimestyle]
+---*/
+
+// To be merged into constructor-options-throwing-getters.js when the feature is removed.
+
+function CustomError() {}
+
+const options = [
+ // InitializeDateTimeFormat step 28
+ "dateStyle",
+ // InitializeDateTimeFormat step 30
+ "timeStyle",
+];
+
+for (const option of options) {
+ assert.throws(CustomError, () => {
+ new Intl.DateTimeFormat("en", {
+ get [option]() {
+ throw new CustomError();
+ }
+ });
+ }, `Exception from ${option} getter should be propagated`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-throwing-getters.js b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-throwing-getters.js
new file mode 100644
index 0000000000..c7faeabb74
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-throwing-getters.js
@@ -0,0 +1,33 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-initializedatetimeformat
+description: Checks the propagation of exceptions from the options for the DateTimeFormat constructor.
+---*/
+
+function CustomError() {}
+
+const options = [
+ "weekday", "year", "month", "day",
+ "hour", "minute", "second",
+ "localeMatcher",
+ "hour12",
+ "hourCycle",
+ "timeZone",
+ "era",
+ "timeZoneName",
+ "formatMatcher",
+];
+
+for (const option of options) {
+ assert.throws(CustomError, () => {
+ new Intl.DateTimeFormat("en", {
+ get [option]() {
+ throw new CustomError();
+ }
+ });
+ }, `Exception from ${option} getter should be propagated`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-timeStyle-invalid.js b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-timeStyle-invalid.js
new file mode 100644
index 0000000000..6979587966
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-timeStyle-invalid.js
@@ -0,0 +1,31 @@
+// Copyright 2019 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-initializedatetimeformat
+description: >
+ Checks error cases for the options argument to the DateTimeFormat constructor.
+info: |
+ InitializeDateTimeFormat ( dateTimeFormat, locales, options )
+
+ ...
+ 30. Let timeStyle be ? GetOption(options, "timeStyle", "string", « "full", "long", "medium", "short" », undefined).
+features: [Intl.DateTimeFormat-datetimestyle]
+---*/
+
+
+const invalidOptions = [
+ "",
+ "FULL",
+ " long",
+ "short ",
+ "narrow",
+ "numeric",
+];
+for (const timeStyle of invalidOptions) {
+ assert.throws(RangeError, function() {
+ new Intl.DateTimeFormat("en", { timeStyle });
+ }, `new Intl.DateTimeFormat("en", { timeStyle: "${timeStyle}" }) throws RangeError`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-timeStyle-valid.js b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-timeStyle-valid.js
new file mode 100644
index 0000000000..cc8665fe44
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-timeStyle-valid.js
@@ -0,0 +1,38 @@
+// Copyright 2019 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-initializedatetimeformat
+description: >
+ Checks handling of the options argument to the DateTimeFormat constructor.
+info: |
+ InitializeDateTimeFormat ( dateTimeFormat, locales, options )
+
+ ...
+ 30. Let timeStyle be ? GetOption(options, "timeStyle", "string", « "full", "long", "medium", "short" », undefined).
+ 31. If timeStyle is not undefined, set dateTimeFormat.[[TimeStyle]] to timeStyle.
+features: [Intl.DateTimeFormat-datetimestyle]
+---*/
+
+const validOptions = [
+ [undefined, undefined],
+ ["full", "full"],
+ ["long", "long"],
+ ["medium", "medium"],
+ ["short", "short"],
+ [{ toString() { return "full"; } }, "full"],
+ [{ valueOf() { return "long"; }, toString: undefined }, "long"],
+];
+for (const [timeStyle, expected] of validOptions) {
+ const dtf = new Intl.DateTimeFormat("en", { timeStyle });
+ const options = dtf.resolvedOptions();
+ assert.sameValue(options.timeStyle, expected);
+ const propdesc = Object.getOwnPropertyDescriptor(options, "timeStyle");
+ if (expected === undefined) {
+ assert.sameValue(propdesc, undefined);
+ } else {
+ assert.sameValue(propdesc.value, expected);
+ }
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-toobject.js b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-toobject.js
new file mode 100644
index 0000000000..bde3e584d2
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-toobject.js
@@ -0,0 +1,44 @@
+// Copyright (C) 2018 Ujjwal Sharma. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-initializedatetimeformat
+description: >
+ Tests that Intl.DateTimeFormat contructor converts the options argument
+ to an object using `ToObject` (7.1.13).
+info: |
+ 12.1.2 ToDateTimeOptions
+
+ 1. If options is undefined, let options be null; otherwise let options be ?
+ ToObject(options).
+---*/
+
+const toObjectResults = [
+ [true, new Boolean(true)],
+ [42, new Number(42)],
+ ['foo', new String('foo')],
+ [{}, {}],
+ [Symbol(), Object(Symbol())]
+];
+
+// Test if ToObject is used to convert primitives to Objects.
+toObjectResults.forEach(pair => {
+ const [value, result] = pair;
+
+ const actual = new Intl.DateTimeFormat(['en-US'], value).resolvedOptions();
+ const expected = new Intl.DateTimeFormat(['en-US'], result).resolvedOptions();
+
+ assert.sameValue(actual.locale, expected.locale);
+ assert.sameValue(actual.calendar, expected.calendar);
+ assert.sameValue(actual.day, expected.day);
+ assert.sameValue(actual.month, expected.month);
+ assert.sameValue(actual.year, expected.year);
+ assert.sameValue(actual.numberingSystem, expected.numberingSystem);
+ assert.sameValue(actual.timeZone, expected.timeZone);
+});
+
+// ToObject throws a TypeError for undefined and null, but it's not called
+// when options is undefined.
+assert.throws(TypeError, () => new Intl.DateTimeFormat(['en-US'], null));
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/date-time-options.js b/js/src/tests/test262/intl402/DateTimeFormat/date-time-options.js
new file mode 100644
index 0000000000..bfe57ade97
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/date-time-options.js
@@ -0,0 +1,106 @@
+// Copyright 2012 Mozilla Corporation. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es5id: 12.1.1_TDTO
+description: >
+ Tests that the set of options for the date and time components is
+ processed correctly.
+author: Norbert Lindenberg
+includes: [testIntl.js]
+---*/
+
+var locales = [[], ["zh-Hans-CN"], ["hi-IN"], ["en-US"], ["id-ID"]];
+var dates = [new Date(), new Date(0), new Date(Date.parse("1989-11-09T17:57:00Z"))];
+
+function testWithDateTimeFormat(options, expected) {
+ locales.forEach(function (locales) {
+ var format = new Intl.DateTimeFormat(locales, options);
+ var resolvedOptions = format.resolvedOptions();
+ getDateTimeComponents().forEach(function (component) {
+ if (resolvedOptions.hasOwnProperty(component)) {
+ assert(expected.hasOwnProperty(component),
+ "Unrequested component " + component +
+ " added to expected subset " + JSON.stringify(expected) +
+ "; locales " + locales + ", options " +
+ (options ? JSON.stringify(options) : options) + ".");
+ } else {
+ assert.sameValue(expected.hasOwnProperty(component), false,
+ "Missing component " + component +
+ " from expected subset " + JSON.stringify(expected) +
+ "; locales " + locales + ", options " +
+ (options ? JSON.stringify(options) : options) + ".");
+ }
+ });
+ });
+}
+
+function testWithToLocale(f, options, expected) {
+ // expected can be either one subset or an array of possible subsets
+ if (expected.length === undefined) {
+ expected = [expected];
+ }
+ locales.forEach(function (locales) {
+ dates.forEach(function (date) {
+ var formatted = Date.prototype[f].call(date, locales, options);
+ var expectedStrings = [];
+ expected.forEach(function (expected) {
+ var referenceFormat = new Intl.DateTimeFormat(locales, expected);
+ expectedStrings.push(referenceFormat.format(date));
+ });
+ assert.notSameValue(expectedStrings.indexOf(formatted), -1,
+ "Function " + f + " did not return expected string for locales " +
+ locales + ", options " + (options? JSON.stringify(options) : options) +
+ "; expected " +
+ (expectedStrings.length === 1 ? expectedStrings[0] : "one of " + expectedStrings) +
+ ", got " + formatted + ".");
+ });
+ });
+}
+
+// any/date: steps 5a, 6a, 7a
+testWithDateTimeFormat(undefined, {year: "numeric", month: "numeric", day: "numeric"});
+
+// any/date: steps 5a, 6a
+testWithDateTimeFormat({year: "numeric", month: "numeric"}, {year: "numeric", month: "numeric"});
+
+// any/date: steps 5a, 6a
+testWithDateTimeFormat({hour: "numeric", minute: "numeric"}, {hour: "numeric", minute: "numeric"});
+
+// any/all: steps 5a, 6a, 7a, 8a
+testWithToLocale("toLocaleString", undefined, [
+ // the first one is not guaranteed to be supported; the second one is
+ {year: "numeric", month: "numeric", day: "numeric", hour: "numeric", minute: "numeric", second: "numeric"},
+ {weekday: "short", year: "numeric", month: "numeric", day: "numeric", hour: "numeric", minute: "numeric", second: "numeric"}
+]);
+
+// any/all: steps 5a, 6a
+testWithToLocale("toLocaleString", {year: "numeric", month: "numeric"}, {year: "numeric", month: "numeric"});
+
+// any/all: steps 5a, 6a
+testWithToLocale("toLocaleString", {hour: "numeric", minute: "numeric"}, {hour: "numeric", minute: "numeric"});
+
+// date/date: steps 5a, 7a
+testWithToLocale("toLocaleDateString", undefined, {year: "numeric", month: "numeric", day: "numeric"});
+
+// date/date: steps 5a
+testWithToLocale("toLocaleDateString", {year: "numeric", month: "numeric"}, {year: "numeric", month: "numeric"});
+
+// date/date: steps 5a, 7a
+testWithToLocale("toLocaleDateString", {hour: "numeric", minute: "numeric", second: "numeric"}, [
+ // the first one is not guaranteed to be supported; the second one is
+ {year: "numeric", month: "numeric", day: "numeric", hour: "numeric", minute: "numeric", second: "numeric"},
+ {weekday: "short", year: "numeric", month: "numeric", day: "numeric", hour: "numeric", minute: "numeric", second: "numeric"}
+]);
+
+// time/time: steps 6a, 8a
+testWithToLocale("toLocaleTimeString", undefined, {hour: "numeric", minute: "numeric", second: "numeric"});
+
+// time/time: steps 6a, 8a
+testWithToLocale("toLocaleTimeString", {weekday: "short", year: "numeric", month: "numeric", day: "numeric"},
+ {weekday: "short", year: "numeric", month: "numeric", day: "numeric", hour: "numeric", minute: "numeric", second: "numeric"});
+
+// time/time: steps 6a
+testWithToLocale("toLocaleTimeString", {hour: "numeric", minute: "numeric"}, {hour: "numeric", minute: "numeric"});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/default-options-object-prototype.js b/js/src/tests/test262/intl402/DateTimeFormat/default-options-object-prototype.js
new file mode 100644
index 0000000000..854e5ff3f1
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/default-options-object-prototype.js
@@ -0,0 +1,22 @@
+// Copyright (C) 2017 Daniel Ehrenberg. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-todatetimeoptions
+description: >
+ Monkey-patching Object.prototype does not change the default
+ options for DateTimeFormat as a null prototype is used.
+info: |
+ ToDateTimeOptions ( options, required, defaults )
+
+ 1. If options is undefined, let options be null; otherwise let options be ? ToObject(options).
+ 1. Let options be ObjectCreate(options).
+---*/
+
+let defaultYear = new Intl.DateTimeFormat("en").resolvedOptions().year;
+
+Object.prototype.year = "2-digit";
+let formatter = new Intl.DateTimeFormat("en");
+assert.sameValue(formatter.resolvedOptions().year, defaultYear);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/ignore-invalid-unicode-ext-values.js b/js/src/tests/test262/intl402/DateTimeFormat/ignore-invalid-unicode-ext-values.js
new file mode 100644
index 0000000000..34c9829741
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/ignore-invalid-unicode-ext-values.js
@@ -0,0 +1,39 @@
+// Copyright 2012 Mozilla Corporation. All rights reserved.
+// This code is governed by the license found in the LICENSE file.
+
+/*---
+es5id: 12.2.3_b
+description: >
+ Tests that Intl.DateTimeFormat does not accept Unicode locale
+ extension keys and values that are not allowed.
+author: Norbert Lindenberg
+---*/
+
+var locales = ["ja-JP", "zh-Hans-CN", "zh-Hant-TW"];
+var input = new Date(Date.parse("1989-11-09T17:57:00Z"));
+
+locales.forEach(function (locale) {
+ var defaultDateTimeFormat = new Intl.DateTimeFormat([locale]);
+ var defaultOptions = defaultDateTimeFormat.resolvedOptions();
+ var defaultOptionsJSON = JSON.stringify(defaultOptions);
+ var defaultLocale = defaultOptions.locale;
+ var defaultFormatted = defaultDateTimeFormat.format(input);
+
+ var keyValues = {
+ "cu": ["USD", "EUR", "JPY", "CNY", "TWD", "invalid"], // DateTimeFormat internally uses NumberFormat
+ "nu": ["native", "traditio", "finance", "invalid"],
+ "tz": ["usnavajo", "utcw01", "aumel", "uslax", "usnyc", "deber", "invalid"]
+ };
+
+ Object.getOwnPropertyNames(keyValues).forEach(function (key) {
+ keyValues[key].forEach(function (value) {
+ var dateTimeFormat = new Intl.DateTimeFormat([locale + "-u-" + key + "-" + value]);
+ var options = dateTimeFormat.resolvedOptions();
+ assert.sameValue(options.locale, defaultLocale, "Locale " + options.locale + " is affected by key " + key + "; value " + value + ".");
+ assert.sameValue(JSON.stringify(options), defaultOptionsJSON, "Resolved options " + JSON.stringify(options) + " are affected by key " + key + "; value " + value + ".");
+ assert.sameValue(dateTimeFormat.format(input), defaultFormatted, "Formatted value " + dateTimeFormat.format(input) + " is affected by key " + key + "; value " + value + ".");
+ });
+ });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/instance-proto-and-extensible.js b/js/src/tests/test262/intl402/DateTimeFormat/instance-proto-and-extensible.js
new file mode 100644
index 0000000000..34e6873529
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/instance-proto-and-extensible.js
@@ -0,0 +1,19 @@
+// Copyright 2012 Mozilla Corporation. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es5id: 12.1.3
+description: >
+ Tests that objects constructed by Intl.DateTimeFormat have the
+ specified internal properties.
+author: Norbert Lindenberg
+---*/
+
+var obj = new Intl.DateTimeFormat();
+
+var actualPrototype = Object.getPrototypeOf(obj);
+assert.sameValue(actualPrototype, Intl.DateTimeFormat.prototype, "Prototype of object constructed by Intl.DateTimeFormat isn't Intl.DateTimeFormat.prototype.");
+
+assert(Object.isExtensible(obj), "Object constructed by Intl.DateTimeFormat must be extensible.");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/intl-legacy-constructed-symbol-on-unwrap.js b/js/src/tests/test262/intl402/DateTimeFormat/intl-legacy-constructed-symbol-on-unwrap.js
new file mode 100644
index 0000000000..61b9452d9a
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/intl-legacy-constructed-symbol-on-unwrap.js
@@ -0,0 +1,34 @@
+// Copyright 2020 Apple Inc. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-unwrapdatetimeformat
+description: >
+ Tests that [[FallbackSymbol]]'s [[Description]] is "IntlLegacyConstructedSymbol" if normative optional is implemented.
+author: Yusuke Suzuki
+features: [intl-normative-optional]
+---*/
+
+let object = new Intl.DateTimeFormat();
+let newObject = Intl.DateTimeFormat.call(object);
+let symbol = null;
+let error = null;
+try {
+ let proxy = new Proxy(newObject, {
+ get(target, property) {
+ symbol = property;
+ return target[property];
+ }
+ });
+ Intl.DateTimeFormat.prototype.resolvedOptions.call(proxy);
+} catch (e) {
+ // If normative optional is not implemented, an error will be thrown.
+ error = e;
+ assert(error instanceof TypeError);
+}
+if (error === null) {
+ assert.sameValue(typeof symbol, "symbol");
+ assert.sameValue(symbol.description, "IntlLegacyConstructedSymbol");
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/intl-legacy-constructed-symbol.js b/js/src/tests/test262/intl402/DateTimeFormat/intl-legacy-constructed-symbol.js
new file mode 100644
index 0000000000..6ca345b44e
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/intl-legacy-constructed-symbol.js
@@ -0,0 +1,20 @@
+// Copyright 2020 Apple Inc. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-intl.datetimeformat
+description: >
+ Tests that [[FallbackSymbol]]'s [[Description]] is "IntlLegacyConstructedSymbol" if normative optional is implemented.
+author: Yusuke Suzuki
+features: [intl-normative-optional]
+---*/
+
+let object = new Intl.DateTimeFormat();
+let newObject = Intl.DateTimeFormat.call(object);
+let symbols = Object.getOwnPropertySymbols(newObject);
+if (symbols.length !== 0) {
+ assert.sameValue(symbols.length, 1);
+ assert.sameValue(symbols[0].description, "IntlLegacyConstructedSymbol");
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/legacy-regexp-statics-not-modified.js b/js/src/tests/test262/intl402/DateTimeFormat/legacy-regexp-statics-not-modified.js
new file mode 100644
index 0000000000..6d44737ef4
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/legacy-regexp-statics-not-modified.js
@@ -0,0 +1,21 @@
+// Copyright 2013 Mozilla Corporation. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es5id: 12.1.1_a
+description: >
+ Tests that constructing a DateTimeFormat doesn't create or modify
+ unwanted properties on the RegExp constructor.
+author: Norbert Lindenberg
+includes: [testIntl.js]
+---*/
+
+testForUnwantedRegExpChanges(function () {
+ new Intl.DateTimeFormat("de-DE-u-ca-gregory");
+});
+
+testForUnwantedRegExpChanges(function () {
+ new Intl.DateTimeFormat("de-DE-u-ca-gregory", {timeZone: "UTC"});
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/length.js b/js/src/tests/test262/intl402/DateTimeFormat/length.js
new file mode 100644
index 0000000000..39331d3787
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/length.js
@@ -0,0 +1,33 @@
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-intl.datetimeformat
+description: >
+ Intl.DateTimeFormat.length is 0.
+info: |
+ Intl.DateTimeFormat ( [ locales [ , options ] ] )
+
+ 17 ECMAScript Standard Built-in Objects:
+
+ Every built-in function object, including constructors, has a length
+ property whose value is an integer. Unless otherwise specified, this
+ value is equal to the largest number of named arguments shown in the
+ subclause headings for the function description. Optional parameters
+ (which are indicated with brackets: [ ]) or rest parameters (which
+ are shown using the form «...name») are not included in the default
+ argument count.
+ Unless otherwise specified, the length property of a built-in function
+ object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+ [[Configurable]]: true }.
+
+includes: [propertyHelper.js]
+---*/
+
+assert.sameValue(Intl.DateTimeFormat.length, 0);
+
+verifyNotEnumerable(Intl.DateTimeFormat, "length");
+verifyNotWritable(Intl.DateTimeFormat, "length");
+verifyConfigurable(Intl.DateTimeFormat, "length");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/name.js b/js/src/tests/test262/intl402/DateTimeFormat/name.js
new file mode 100644
index 0000000000..434fd31ef3
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/name.js
@@ -0,0 +1,28 @@
+// Copyright (C) 2016 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.DateTimeFormat
+description: >
+ Intl.DateTimeFormat.name is "DateTimeFormat".
+info: |
+ 12.2.1 Intl.DateTimeFormat ([ locales [ , options ]])
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, that is not
+ identified as an anonymous function has a name property whose value
+ is a String.
+
+ Unless otherwise specified, the name property of a built-in Function
+ object, if it exists, has the attributes { [[Writable]]: false,
+ [[Enumerable]]: false, [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+assert.sameValue(Intl.DateTimeFormat.name, "DateTimeFormat");
+
+verifyNotEnumerable(Intl.DateTimeFormat, "name");
+verifyNotWritable(Intl.DateTimeFormat, "name");
+verifyConfigurable(Intl.DateTimeFormat, "name");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/numbering-system-calendar-options.js b/js/src/tests/test262/intl402/DateTimeFormat/numbering-system-calendar-options.js
new file mode 100644
index 0000000000..b7cd7a3241
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/numbering-system-calendar-options.js
@@ -0,0 +1,69 @@
+// Copyright 2012 Mozilla Corporation. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-initializedatetimeformat
+description: >
+ Tests that the options numberingSystem and calendar can be set through
+ either the locale or the options.
+author: Norbert Lindenberg, Daniel Ehrenberg
+---*/
+
+let defaultLocale = new Intl.DateTimeFormat().resolvedOptions().locale;
+
+let supportedNumberingSystems = ["latn", "arab"].filter(nu =>
+ new Intl.DateTimeFormat(defaultLocale + "-u-nu-" + nu)
+ .resolvedOptions().numberingSystem === nu
+);
+
+let supportedCalendars = ["gregory", "chinese"].filter(ca =>
+ new Intl.DateTimeFormat(defaultLocale + "-u-ca-" + ca)
+ .resolvedOptions().calendar === ca
+);
+
+let options = [
+ {key: "nu", property: "numberingSystem", type: "string", values: supportedNumberingSystems},
+ {key: "ca", property: "calendar", type: "string", values: supportedCalendars}
+];
+
+options.forEach(function (option) {
+ let dateTimeFormat, opt, result;
+
+ // find out which values are supported for a property in the default locale
+ let supportedValues = [];
+ option.values.forEach(function (value) {
+ opt = {};
+ opt[option.property] = value;
+ dateTimeFormat = new Intl.DateTimeFormat([defaultLocale], opt);
+ result = dateTimeFormat.resolvedOptions()[option.property];
+ if (result !== undefined && supportedValues.indexOf(result) === -1) {
+ supportedValues.push(result);
+ }
+ });
+
+ // verify that the supported values can also be set through the locale
+ supportedValues.forEach(function (value) {
+ dateTimeFormat = new Intl.DateTimeFormat([defaultLocale + "-u-" + option.key + "-" + value]);
+ result = dateTimeFormat.resolvedOptions()[option.property];
+ assert.sameValue(result, value, "Property " + option.property + " couldn't be set through locale extension key " + option.key + ".");
+ });
+
+ // verify that the options setting overrides the locale setting
+ supportedValues.forEach(function (value) {
+ let otherValue;
+ option.values.forEach(function (possibleValue) {
+ if (possibleValue !== value) {
+ otherValue = possibleValue;
+ }
+ });
+ if (otherValue !== undefined) {
+ opt = {};
+ opt[option.property] = value;
+ dateTimeFormat = new Intl.DateTimeFormat([defaultLocale + "-u-" + option.key + "-" + otherValue], opt);
+ result = dateTimeFormat.resolvedOptions()[option.property];
+ assert.sameValue(result, value, "Options value for property " + option.property + " doesn't override locale extension key " + option.key + ".");
+ }
+ });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prop-desc.js b/js/src/tests/test262/intl402/DateTimeFormat/prop-desc.js
new file mode 100644
index 0000000000..7b236b882f
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prop-desc.js
@@ -0,0 +1,31 @@
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-intl.datetimeformat-intro
+description: >
+ "DateTimeFormat" property of Intl.
+info: |
+ Intl.DateTimeFormat (...)
+
+ 7 Requirements for Standard Built-in ECMAScript Objects
+
+ Unless specified otherwise in this document, the objects, functions, and constructors
+ described in this standard are subject to the generic requirements and restrictions
+ specified for standard built-in ECMAScript objects in the ECMAScript 2018 Language
+ Specification, 9th edition, clause 17, or successor.
+
+ 17 ECMAScript Standard Built-in Objects:
+
+ Every other data property described in clauses 18 through 26 and in Annex B.2 has the
+ attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }
+ unless otherwise specified.
+
+includes: [propertyHelper.js]
+---*/
+
+verifyNotEnumerable(Intl, "DateTimeFormat");
+verifyWritable(Intl, "DateTimeFormat");
+verifyConfigurable(Intl, "DateTimeFormat");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/proto-from-ctor-realm.js b/js/src/tests/test262/intl402/DateTimeFormat/proto-from-ctor-realm.js
new file mode 100644
index 0000000000..118fadf545
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/proto-from-ctor-realm.js
@@ -0,0 +1,60 @@
+// Copyright (C) 2019 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-intl.datetimeformat
+description: Default [[Prototype]] value derived from realm of the NewTarget.
+info: |
+ Intl.DateTimeFormat ( [ locales [ , options ] ] )
+
+ 1. If NewTarget is undefined, let newTarget be the active function object, else let newTarget be NewTarget.
+ 2. Let dateTimeFormat be ? OrdinaryCreateFromConstructor(newTarget, "%DateTimeFormatPrototype%", « ... »).
+ ...
+ 6. Return dateTimeFormat.
+
+ OrdinaryCreateFromConstructor ( constructor, intrinsicDefaultProto [ , internalSlotsList ] )
+
+ ...
+ 2. Let proto be ? GetPrototypeFromConstructor(constructor, intrinsicDefaultProto).
+ 3. Return ObjectCreate(proto, internalSlotsList).
+
+ GetPrototypeFromConstructor ( constructor, intrinsicDefaultProto )
+
+ ...
+ 3. Let proto be ? Get(constructor, 'prototype').
+ 4. If Type(proto) is not Object, then
+ a. Let realm be ? GetFunctionRealm(constructor).
+ b. Set proto to realm's intrinsic object named intrinsicDefaultProto.
+ 5. Return proto.
+features: [cross-realm, Reflect, Symbol]
+---*/
+
+var other = $262.createRealm().global;
+var newTarget = new other.Function();
+var dtf;
+
+newTarget.prototype = undefined;
+dtf = Reflect.construct(Intl.DateTimeFormat, [], newTarget);
+assert.sameValue(Object.getPrototypeOf(dtf), other.Intl.DateTimeFormat.prototype, 'newTarget.prototype is undefined');
+
+newTarget.prototype = null;
+dtf = Reflect.construct(Intl.DateTimeFormat, [], newTarget);
+assert.sameValue(Object.getPrototypeOf(dtf), other.Intl.DateTimeFormat.prototype, 'newTarget.prototype is null');
+
+newTarget.prototype = false;
+dtf = Reflect.construct(Intl.DateTimeFormat, [], newTarget);
+assert.sameValue(Object.getPrototypeOf(dtf), other.Intl.DateTimeFormat.prototype, 'newTarget.prototype is a Boolean');
+
+newTarget.prototype = 'str';
+dtf = Reflect.construct(Intl.DateTimeFormat, [], newTarget);
+assert.sameValue(Object.getPrototypeOf(dtf), other.Intl.DateTimeFormat.prototype, 'newTarget.prototype is a String');
+
+newTarget.prototype = Symbol();
+dtf = Reflect.construct(Intl.DateTimeFormat, [], newTarget);
+assert.sameValue(Object.getPrototypeOf(dtf), other.Intl.DateTimeFormat.prototype, 'newTarget.prototype is a Symbol');
+
+newTarget.prototype = 1;
+dtf = Reflect.construct(Intl.DateTimeFormat, [], newTarget);
+assert.sameValue(Object.getPrototypeOf(dtf), other.Intl.DateTimeFormat.prototype, 'newTarget.prototype is a Number');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/browser.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/browser.js
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/builtin.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/builtin.js
new file mode 100644
index 0000000000..dd849faaef
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/builtin.js
@@ -0,0 +1,18 @@
+// Copyright 2012 Mozilla Corporation. All rights reserved.
+// This code is governed by the license found in the LICENSE file.
+
+/*---
+es5id: 12.3_L15
+description: >
+ Tests that Intl.DateTimeFormat.prototype meets the requirements
+ for built-in objects defined by the introduction of chapter 17 of
+ the ECMAScript Language Specification.
+author: Norbert Lindenberg
+---*/
+
+assert(Object.isExtensible(Intl.DateTimeFormat.prototype), "Built-in objects must be extensible.");
+
+assert.sameValue(Object.getPrototypeOf(Intl.DateTimeFormat.prototype), Object.prototype,
+ "Built-in prototype objects must have Object.prototype as their prototype.");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/constructor/browser.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/constructor/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/constructor/browser.js
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/constructor/prop-desc.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/constructor/prop-desc.js
new file mode 100644
index 0000000000..13826e9fa1
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/constructor/prop-desc.js
@@ -0,0 +1,31 @@
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-intl.datetimeformat.prototype.constructor
+description: >
+ "constructor" property of Intl.DateTimeFormat.prototype.
+info: |
+ Intl.DateTimeFormat.prototype.constructor
+
+ 7 Requirements for Standard Built-in ECMAScript Objects
+
+ Unless specified otherwise in this document, the objects, functions, and constructors
+ described in this standard are subject to the generic requirements and restrictions
+ specified for standard built-in ECMAScript objects in the ECMAScript 2018 Language
+ Specification, 9th edition, clause 17, or successor.
+
+ 17 ECMAScript Standard Built-in Objects:
+
+ Every other data property described in clauses 18 through 26 and in Annex B.2 has the
+ attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }
+ unless otherwise specified.
+
+includes: [propertyHelper.js]
+---*/
+
+verifyNotEnumerable(Intl.DateTimeFormat.prototype, "constructor");
+verifyWritable(Intl.DateTimeFormat.prototype, "constructor");
+verifyConfigurable(Intl.DateTimeFormat.prototype, "constructor");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/constructor/shell.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/constructor/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/constructor/shell.js
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/constructor/value.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/constructor/value.js
new file mode 100644
index 0000000000..5092db0768
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/constructor/value.js
@@ -0,0 +1,14 @@
+// Copyright 2012 Google Inc. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es5id: 12.3.1
+description: >
+ Tests that Intl.DateTimeFormat.prototype.constructor is the
+ Intl.DateTimeFormat.
+author: Roozbeh Pournader
+---*/
+
+assert.sameValue(Intl.DateTimeFormat.prototype.constructor, Intl.DateTimeFormat, "Intl.DateTimeFormat.prototype.constructor is not the same as Intl.DateTimeFormat");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/bound-to-datetimeformat-instance.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/bound-to-datetimeformat-instance.js
new file mode 100644
index 0000000000..485a7c0720
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/bound-to-datetimeformat-instance.js
@@ -0,0 +1,30 @@
+// Copyright 2012 Mozilla Corporation. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es5id: 12.3.2_1_c
+description: Tests that format function is bound to its Intl.DateTimeFormat.
+author: Norbert Lindenberg
+---*/
+
+var dates = [new Date(), new Date(0), new Date(Date.parse("1989-11-09T17:57:00Z"))];
+var locales = [undefined, ["de"], ["th-u-ca-gregory-nu-thai"], ["en"], ["ja-u-ca-japanese"], ["ar-u-ca-islamicc-nu-arab"]];
+var options = [
+ undefined,
+ {hour12: false},
+ {month: "long", day: "numeric", hour: "2-digit", minute: "2-digit"}
+];
+
+locales.forEach(function (locales) {
+ options.forEach(function (options) {
+ var formatObj = new Intl.DateTimeFormat(locales, options);
+ var formatFunc = formatObj.format;
+ dates.forEach(function (date) {
+ var referenceFormatted = formatObj.format(date);
+ var formatted = formatFunc(date);
+ assert.sameValue(referenceFormatted, formatted, "format function produces different result than format method for locales " + locales + "; options: " + (options ? JSON.stringify(options) : options) + ".");
+ });
+ });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/browser.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/browser.js
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/builtin.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/builtin.js
new file mode 100644
index 0000000000..c4870b0b57
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/builtin.js
@@ -0,0 +1,33 @@
+// Copyright 2012 Mozilla Corporation. All rights reserved.
+// This code is governed by the license found in the LICENSE file.
+
+/*---
+es5id: 12.3.2_L15
+description: >
+ Tests that the getter for Intl.DateTimeFormat.prototype.format
+ meets the requirements for built-in objects defined by the
+ introduction of chapter 17 of the ECMAScript Language
+ Specification.
+author: Norbert Lindenberg
+includes: [isConstructor.js]
+features: [Reflect.construct]
+---*/
+
+var formatFn = Object.getOwnPropertyDescriptor(Intl.DateTimeFormat.prototype, "format").get;
+
+assert.sameValue(Object.prototype.toString.call(formatFn), "[object Function]",
+ "The [[Class]] internal property of a built-in function must be " +
+ "\"Function\".");
+
+assert(Object.isExtensible(formatFn),
+ "Built-in objects must be extensible.");
+
+assert.sameValue(Object.getPrototypeOf(formatFn), Function.prototype);
+
+assert.sameValue(formatFn.hasOwnProperty("prototype"), false,
+ "Built-in functions that aren't constructors must not have a prototype property.");
+
+assert.sameValue(isConstructor(formatFn), false,
+ "Built-in functions don't implement [[Construct]] unless explicitly specified.");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/date-constructor-not-called.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/date-constructor-not-called.js
new file mode 100644
index 0000000000..f13f9425ce
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/date-constructor-not-called.js
@@ -0,0 +1,38 @@
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-partitiondatetimepattern
+description: |
+ The Date constructor is not called to convert the input value.
+info: >
+ 12.1.5 DateTime Format Functions
+
+ ...
+ 3. If date is not provided or is undefined, then
+ ...
+ 4. Else,
+ a. Let x be ? ToNumber(date).
+ 5. Return FormatDateTime(dtf, x).
+
+ 12.1.6 PartitionDateTimePattern ( dateTimeFormat, x )
+
+ 1. Let x be TimeClip(x).
+ 2. If x is NaN, throw a RangeError exception.
+ 3. ...
+---*/
+
+var dtf = new Intl.DateTimeFormat();
+
+var dateTimeString = "2017-11-10T14:09:00.000Z";
+
+// |dateTimeString| is valid ISO-8601 style date/time string.
+assert.notSameValue(new Date(dateTimeString), NaN);
+
+// Ensure string input values are not converted to time values by calling the
+// Date constructor.
+assert.throws(RangeError, function() {
+ dtf.format(dateTimeString);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/dayPeriod-long-en.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/dayPeriod-long-en.js
new file mode 100644
index 0000000000..3af6285060
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/dayPeriod-long-en.js
@@ -0,0 +1,96 @@
+// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-dayPeriod is not released yet
+// Copyright 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-initializedatetimeformat
+description: Checks basic handling of dayPeriod, long format.
+features: [Intl.DateTimeFormat-dayPeriod]
+locale: [en-US]
+---*/
+
+const d0000 = new Date(2017, 11, 12, 0, 0, 0, 0);
+const d0100 = new Date(2017, 11, 12, 1, 0, 0, 0);
+const d0200 = new Date(2017, 11, 12, 2, 0, 0, 0);
+const d0300 = new Date(2017, 11, 12, 3, 0, 0, 0);
+const d0400 = new Date(2017, 11, 12, 4, 0, 0, 0);
+const d0500 = new Date(2017, 11, 12, 5, 0, 0, 0);
+const d0600 = new Date(2017, 11, 12, 6, 0, 0, 0);
+const d0700 = new Date(2017, 11, 12, 7, 0, 0, 0);
+const d0800 = new Date(2017, 11, 12, 8, 0, 0, 0);
+const d0900 = new Date(2017, 11, 12, 9, 0, 0, 0);
+const d1000 = new Date(2017, 11, 12, 10, 0, 0, 0);
+const d1100 = new Date(2017, 11, 12, 11, 0, 0, 0);
+const d1200 = new Date(2017, 11, 12, 12, 0, 0, 0);
+const d1300 = new Date(2017, 11, 12, 13, 0, 0, 0);
+const d1400 = new Date(2017, 11, 12, 14, 0, 0, 0);
+const d1500 = new Date(2017, 11, 12, 15, 0, 0, 0);
+const d1600 = new Date(2017, 11, 12, 16, 0, 0, 0);
+const d1700 = new Date(2017, 11, 12, 17, 0, 0, 0);
+const d1800 = new Date(2017, 11, 12, 18, 0, 0, 0);
+const d1900 = new Date(2017, 11, 12, 19, 0, 0, 0);
+const d2000 = new Date(2017, 11, 12, 20, 0, 0, 0);
+const d2100 = new Date(2017, 11, 12, 21, 0, 0, 0);
+const d2200 = new Date(2017, 11, 12, 22, 0, 0, 0);
+const d2300 = new Date(2017, 11, 12, 23, 0, 0, 0);
+
+const long = new Intl.DateTimeFormat('en', {
+ dayPeriod: 'long'
+});
+
+assert.sameValue(long.format(d0000), 'at night', '00:00, long format');
+assert.sameValue(long.format(d0100), 'at night', '01:00, long format');
+assert.sameValue(long.format(d0200), 'at night', '02:00, long format');
+assert.sameValue(long.format(d0300), 'at night', '03:00, long format');
+assert.sameValue(long.format(d0400), 'at night', '04:00, long format');
+assert.sameValue(long.format(d0500), 'at night', '05:00, long format');
+assert.sameValue(long.format(d0600), 'in the morning', '06:00, long format');
+assert.sameValue(long.format(d0700), 'in the morning', '07:00, long format');
+assert.sameValue(long.format(d0800), 'in the morning', '08:00, long format');
+assert.sameValue(long.format(d0900), 'in the morning', '09:00, long format');
+assert.sameValue(long.format(d1000), 'in the morning', '10:00, long format');
+assert.sameValue(long.format(d1100), 'in the morning', '11:00, long format');
+assert.sameValue(long.format(d1200), 'noon', '12:00, long format');
+assert.sameValue(long.format(d1300), 'in the afternoon', '13:00, long format');
+assert.sameValue(long.format(d1400), 'in the afternoon', '14:00, long format');
+assert.sameValue(long.format(d1500), 'in the afternoon', '15:00, long format');
+assert.sameValue(long.format(d1600), 'in the afternoon', '16:00, long format');
+assert.sameValue(long.format(d1700), 'in the afternoon', '17:00, long format');
+assert.sameValue(long.format(d1800), 'in the evening', '18:00, long format');
+assert.sameValue(long.format(d1900), 'in the evening', '19:00, long format');
+assert.sameValue(long.format(d2000), 'in the evening', '20:00, long format');
+assert.sameValue(long.format(d2100), 'at night', '21:00, long format');
+assert.sameValue(long.format(d2200), 'at night', '22:00, long format');
+assert.sameValue(long.format(d2300), 'at night', '23:00, long format');
+
+const longNumeric = new Intl.DateTimeFormat('en', {
+ dayPeriod: 'long',
+ hour: 'numeric'
+});
+
+assert.sameValue(longNumeric.format(d0000), '12 at night', '00:00, long-numeric');
+assert.sameValue(longNumeric.format(d0100), '1 at night', '01:00, long-numeric');
+assert.sameValue(longNumeric.format(d0200), '2 at night', '02:00, long-numeric');
+assert.sameValue(longNumeric.format(d0300), '3 at night', '03:00, long-numeric');
+assert.sameValue(longNumeric.format(d0400), '4 at night', '04:00, long-numeric');
+assert.sameValue(longNumeric.format(d0500), '5 at night', '05:00, long-numeric');
+assert.sameValue(longNumeric.format(d0600), '6 in the morning', '06:00, long-numeric');
+assert.sameValue(longNumeric.format(d0700), '7 in the morning', '07:00, long-numeric');
+assert.sameValue(longNumeric.format(d0800), '8 in the morning', '08:00, long-numeric');
+assert.sameValue(longNumeric.format(d0900), '9 in the morning', '09:00, long-numeric');
+assert.sameValue(longNumeric.format(d1000), '10 in the morning', '10:00, long-numeric');
+assert.sameValue(longNumeric.format(d1100), '11 in the morning', '11:00, long-numeric');
+assert.sameValue(longNumeric.format(d1200), '12 noon', '12:00, long-numeric');
+assert.sameValue(longNumeric.format(d1300), '1 in the afternoon', '13:00, long-numeric');
+assert.sameValue(longNumeric.format(d1400), '2 in the afternoon', '14:00, long-numeric');
+assert.sameValue(longNumeric.format(d1500), '3 in the afternoon', '15:00, long-numeric');
+assert.sameValue(longNumeric.format(d1600), '4 in the afternoon', '16:00, long-numeric');
+assert.sameValue(longNumeric.format(d1700), '5 in the afternoon', '17:00, long-numeric');
+assert.sameValue(longNumeric.format(d1800), '6 in the evening', '18:00, long-numeric');
+assert.sameValue(longNumeric.format(d1900), '7 in the evening', '19:00, long-numeric');
+assert.sameValue(longNumeric.format(d2000), '8 in the evening', '20:00, long-numeric');
+assert.sameValue(longNumeric.format(d2100), '9 at night', '21:00, long-numeric');
+assert.sameValue(longNumeric.format(d2200), '10 at night', '22:00, long-numeric');
+assert.sameValue(longNumeric.format(d2300), '11 at night', '23:00, long-numeric');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/dayPeriod-narrow-en.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/dayPeriod-narrow-en.js
new file mode 100644
index 0000000000..9ab465db89
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/dayPeriod-narrow-en.js
@@ -0,0 +1,96 @@
+// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-dayPeriod is not released yet
+// Copyright 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-initializedatetimeformat
+description: Checks basic handling of dayPeriod, narrow format.
+features: [Intl.DateTimeFormat-dayPeriod]
+locale: [en-US]
+---*/
+
+const d0000 = new Date(2017, 11, 12, 0, 0, 0, 0);
+const d0100 = new Date(2017, 11, 12, 1, 0, 0, 0);
+const d0200 = new Date(2017, 11, 12, 2, 0, 0, 0);
+const d0300 = new Date(2017, 11, 12, 3, 0, 0, 0);
+const d0400 = new Date(2017, 11, 12, 4, 0, 0, 0);
+const d0500 = new Date(2017, 11, 12, 5, 0, 0, 0);
+const d0600 = new Date(2017, 11, 12, 6, 0, 0, 0);
+const d0700 = new Date(2017, 11, 12, 7, 0, 0, 0);
+const d0800 = new Date(2017, 11, 12, 8, 0, 0, 0);
+const d0900 = new Date(2017, 11, 12, 9, 0, 0, 0);
+const d1000 = new Date(2017, 11, 12, 10, 0, 0, 0);
+const d1100 = new Date(2017, 11, 12, 11, 0, 0, 0);
+const d1200 = new Date(2017, 11, 12, 12, 0, 0, 0);
+const d1300 = new Date(2017, 11, 12, 13, 0, 0, 0);
+const d1400 = new Date(2017, 11, 12, 14, 0, 0, 0);
+const d1500 = new Date(2017, 11, 12, 15, 0, 0, 0);
+const d1600 = new Date(2017, 11, 12, 16, 0, 0, 0);
+const d1700 = new Date(2017, 11, 12, 17, 0, 0, 0);
+const d1800 = new Date(2017, 11, 12, 18, 0, 0, 0);
+const d1900 = new Date(2017, 11, 12, 19, 0, 0, 0);
+const d2000 = new Date(2017, 11, 12, 20, 0, 0, 0);
+const d2100 = new Date(2017, 11, 12, 21, 0, 0, 0);
+const d2200 = new Date(2017, 11, 12, 22, 0, 0, 0);
+const d2300 = new Date(2017, 11, 12, 23, 0, 0, 0);
+
+const narrow = new Intl.DateTimeFormat('en', {
+ dayPeriod: 'narrow'
+});
+
+assert.sameValue(narrow.format(d0000), 'at night', '00:00, narrow format');
+assert.sameValue(narrow.format(d0100), 'at night', '01:00, narrow format');
+assert.sameValue(narrow.format(d0200), 'at night', '02:00, narrow format');
+assert.sameValue(narrow.format(d0300), 'at night', '03:00, narrow format');
+assert.sameValue(narrow.format(d0400), 'at night', '04:00, narrow format');
+assert.sameValue(narrow.format(d0500), 'at night', '05:00, narrow format');
+assert.sameValue(narrow.format(d0600), 'in the morning', '06:00, narrow format');
+assert.sameValue(narrow.format(d0700), 'in the morning', '07:00, narrow format');
+assert.sameValue(narrow.format(d0800), 'in the morning', '08:00, narrow format');
+assert.sameValue(narrow.format(d0900), 'in the morning', '09:00, narrow format');
+assert.sameValue(narrow.format(d1000), 'in the morning', '10:00, narrow format');
+assert.sameValue(narrow.format(d1100), 'in the morning', '11:00, narrow format');
+assert.sameValue(narrow.format(d1200), 'n', '12:00, narrow format');
+assert.sameValue(narrow.format(d1300), 'in the afternoon', '13:00, narrow format');
+assert.sameValue(narrow.format(d1400), 'in the afternoon', '14:00, narrow format');
+assert.sameValue(narrow.format(d1500), 'in the afternoon', '15:00, narrow format');
+assert.sameValue(narrow.format(d1600), 'in the afternoon', '16:00, narrow format');
+assert.sameValue(narrow.format(d1700), 'in the afternoon', '17:00, narrow format');
+assert.sameValue(narrow.format(d1800), 'in the evening', '18:00, narrow format');
+assert.sameValue(narrow.format(d1900), 'in the evening', '19:00, narrow format');
+assert.sameValue(narrow.format(d2000), 'in the evening', '20:00, narrow format');
+assert.sameValue(narrow.format(d2100), 'at night', '21:00, narrow format');
+assert.sameValue(narrow.format(d2200), 'at night', '22:00, narrow format');
+assert.sameValue(narrow.format(d2300), 'at night', '23:00, narrow format');
+
+const narrowNumeric = new Intl.DateTimeFormat('en', {
+ dayPeriod: 'narrow',
+ hour: 'numeric'
+});
+
+assert.sameValue(narrowNumeric.format(d0000), '12 at night', '00:00, narrow-numeric');
+assert.sameValue(narrowNumeric.format(d0100), '1 at night', '01:00, narrow-numeric');
+assert.sameValue(narrowNumeric.format(d0200), '2 at night', '02:00, narrow-numeric');
+assert.sameValue(narrowNumeric.format(d0300), '3 at night', '03:00, narrow-numeric');
+assert.sameValue(narrowNumeric.format(d0400), '4 at night', '04:00, narrow-numeric');
+assert.sameValue(narrowNumeric.format(d0500), '5 at night', '05:00, narrow-numeric');
+assert.sameValue(narrowNumeric.format(d0600), '6 in the morning', '06:00, narrow-numeric');
+assert.sameValue(narrowNumeric.format(d0700), '7 in the morning', '07:00, narrow-numeric');
+assert.sameValue(narrowNumeric.format(d0800), '8 in the morning', '08:00, narrow-numeric');
+assert.sameValue(narrowNumeric.format(d0900), '9 in the morning', '09:00, narrow-numeric');
+assert.sameValue(narrowNumeric.format(d1000), '10 in the morning', '10:00, narrow-numeric');
+assert.sameValue(narrowNumeric.format(d1100), '11 in the morning', '11:00, narrow-numeric');
+assert.sameValue(narrowNumeric.format(d1200), '12 n', '12:00, narrow-numeric');
+assert.sameValue(narrowNumeric.format(d1300), '1 in the afternoon', '13:00, narrow-numeric');
+assert.sameValue(narrowNumeric.format(d1400), '2 in the afternoon', '14:00, narrow-numeric');
+assert.sameValue(narrowNumeric.format(d1500), '3 in the afternoon', '15:00, narrow-numeric');
+assert.sameValue(narrowNumeric.format(d1600), '4 in the afternoon', '16:00, narrow-numeric');
+assert.sameValue(narrowNumeric.format(d1700), '5 in the afternoon', '17:00, narrow-numeric');
+assert.sameValue(narrowNumeric.format(d1800), '6 in the evening', '18:00, narrow-numeric');
+assert.sameValue(narrowNumeric.format(d1900), '7 in the evening', '19:00, narrow-numeric');
+assert.sameValue(narrowNumeric.format(d2000), '8 in the evening', '20:00, narrow-numeric');
+assert.sameValue(narrowNumeric.format(d2100), '9 at night', '21:00, narrow-numeric');
+assert.sameValue(narrowNumeric.format(d2200), '10 at night', '22:00, narrow-numeric');
+assert.sameValue(narrowNumeric.format(d2300), '11 at night', '23:00, narrow-numeric');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/dayPeriod-short-en.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/dayPeriod-short-en.js
new file mode 100644
index 0000000000..c950aee0ca
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/dayPeriod-short-en.js
@@ -0,0 +1,96 @@
+// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-dayPeriod is not released yet
+// Copyright 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-initializedatetimeformat
+description: Checks basic handling of dayPeriod, short format.
+features: [Intl.DateTimeFormat-dayPeriod]
+locale: [en-US]
+---*/
+
+const d0000 = new Date(2017, 11, 12, 0, 0, 0, 0);
+const d0100 = new Date(2017, 11, 12, 1, 0, 0, 0);
+const d0200 = new Date(2017, 11, 12, 2, 0, 0, 0);
+const d0300 = new Date(2017, 11, 12, 3, 0, 0, 0);
+const d0400 = new Date(2017, 11, 12, 4, 0, 0, 0);
+const d0500 = new Date(2017, 11, 12, 5, 0, 0, 0);
+const d0600 = new Date(2017, 11, 12, 6, 0, 0, 0);
+const d0700 = new Date(2017, 11, 12, 7, 0, 0, 0);
+const d0800 = new Date(2017, 11, 12, 8, 0, 0, 0);
+const d0900 = new Date(2017, 11, 12, 9, 0, 0, 0);
+const d1000 = new Date(2017, 11, 12, 10, 0, 0, 0);
+const d1100 = new Date(2017, 11, 12, 11, 0, 0, 0);
+const d1200 = new Date(2017, 11, 12, 12, 0, 0, 0);
+const d1300 = new Date(2017, 11, 12, 13, 0, 0, 0);
+const d1400 = new Date(2017, 11, 12, 14, 0, 0, 0);
+const d1500 = new Date(2017, 11, 12, 15, 0, 0, 0);
+const d1600 = new Date(2017, 11, 12, 16, 0, 0, 0);
+const d1700 = new Date(2017, 11, 12, 17, 0, 0, 0);
+const d1800 = new Date(2017, 11, 12, 18, 0, 0, 0);
+const d1900 = new Date(2017, 11, 12, 19, 0, 0, 0);
+const d2000 = new Date(2017, 11, 12, 20, 0, 0, 0);
+const d2100 = new Date(2017, 11, 12, 21, 0, 0, 0);
+const d2200 = new Date(2017, 11, 12, 22, 0, 0, 0);
+const d2300 = new Date(2017, 11, 12, 23, 0, 0, 0);
+
+const short = new Intl.DateTimeFormat('en', {
+ dayPeriod: 'short'
+});
+
+assert.sameValue(short.format(d0000), 'at night', '00:00, short format');
+assert.sameValue(short.format(d0100), 'at night', '01:00, short format');
+assert.sameValue(short.format(d0200), 'at night', '02:00, short format');
+assert.sameValue(short.format(d0300), 'at night', '03:00, short format');
+assert.sameValue(short.format(d0400), 'at night', '04:00, short format');
+assert.sameValue(short.format(d0500), 'at night', '05:00, short format');
+assert.sameValue(short.format(d0600), 'in the morning', '06:00, short format');
+assert.sameValue(short.format(d0700), 'in the morning', '07:00, short format');
+assert.sameValue(short.format(d0800), 'in the morning', '08:00, short format');
+assert.sameValue(short.format(d0900), 'in the morning', '09:00, short format');
+assert.sameValue(short.format(d1000), 'in the morning', '10:00, short format');
+assert.sameValue(short.format(d1100), 'in the morning', '11:00, short format');
+assert.sameValue(short.format(d1200), 'noon', '12:00, short format');
+assert.sameValue(short.format(d1300), 'in the afternoon', '13:00, short format');
+assert.sameValue(short.format(d1400), 'in the afternoon', '14:00, short format');
+assert.sameValue(short.format(d1500), 'in the afternoon', '15:00, short format');
+assert.sameValue(short.format(d1600), 'in the afternoon', '16:00, short format');
+assert.sameValue(short.format(d1700), 'in the afternoon', '17:00, short format');
+assert.sameValue(short.format(d1800), 'in the evening', '18:00, short format');
+assert.sameValue(short.format(d1900), 'in the evening', '19:00, short format');
+assert.sameValue(short.format(d2000), 'in the evening', '20:00, short format');
+assert.sameValue(short.format(d2100), 'at night', '21:00, short format');
+assert.sameValue(short.format(d2200), 'at night', '22:00, short format');
+assert.sameValue(short.format(d2300), 'at night', '23:00, short format');
+
+const shortNumeric = new Intl.DateTimeFormat('en', {
+ dayPeriod: 'short',
+ hour: 'numeric'
+});
+
+assert.sameValue(shortNumeric.format(d0000), '12 at night', '00:00, short-numeric');
+assert.sameValue(shortNumeric.format(d0100), '1 at night', '01:00, short-numeric');
+assert.sameValue(shortNumeric.format(d0200), '2 at night', '02:00, short-numeric');
+assert.sameValue(shortNumeric.format(d0300), '3 at night', '03:00, short-numeric');
+assert.sameValue(shortNumeric.format(d0400), '4 at night', '04:00, short-numeric');
+assert.sameValue(shortNumeric.format(d0500), '5 at night', '05:00, short-numeric');
+assert.sameValue(shortNumeric.format(d0600), '6 in the morning', '06:00, short-numeric');
+assert.sameValue(shortNumeric.format(d0700), '7 in the morning', '07:00, short-numeric');
+assert.sameValue(shortNumeric.format(d0800), '8 in the morning', '08:00, short-numeric');
+assert.sameValue(shortNumeric.format(d0900), '9 in the morning', '09:00, short-numeric');
+assert.sameValue(shortNumeric.format(d1000), '10 in the morning', '10:00, short-numeric');
+assert.sameValue(shortNumeric.format(d1100), '11 in the morning', '11:00, short-numeric');
+assert.sameValue(shortNumeric.format(d1200), '12 noon', '12:00, short-numeric');
+assert.sameValue(shortNumeric.format(d1300), '1 in the afternoon', '13:00, short-numeric');
+assert.sameValue(shortNumeric.format(d1400), '2 in the afternoon', '14:00, short-numeric');
+assert.sameValue(shortNumeric.format(d1500), '3 in the afternoon', '15:00, short-numeric');
+assert.sameValue(shortNumeric.format(d1600), '4 in the afternoon', '16:00, short-numeric');
+assert.sameValue(shortNumeric.format(d1700), '5 in the afternoon', '17:00, short-numeric');
+assert.sameValue(shortNumeric.format(d1800), '6 in the evening', '18:00, short-numeric');
+assert.sameValue(shortNumeric.format(d1900), '7 in the evening', '19:00, short-numeric');
+assert.sameValue(shortNumeric.format(d2000), '8 in the evening', '20:00, short-numeric');
+assert.sameValue(shortNumeric.format(d2100), '9 at night', '21:00, short-numeric');
+assert.sameValue(shortNumeric.format(d2200), '10 at night', '22:00, short-numeric');
+assert.sameValue(shortNumeric.format(d2300), '11 at night', '23:00, short-numeric');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/format-function-builtin.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/format-function-builtin.js
new file mode 100644
index 0000000000..d5270e354a
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/format-function-builtin.js
@@ -0,0 +1,33 @@
+// Copyright 2012 Mozilla Corporation. All rights reserved.
+// This code is governed by the license found in the LICENSE file.
+
+/*---
+es5id: 12.3.2_1_a_L15
+description: >
+ Tests that the function returned by
+ Intl.DateTimeFormat.prototype.format meets the requirements for
+ built-in objects defined by the introduction of chapter 17 of the
+ ECMAScript Language Specification.
+author: Norbert Lindenberg
+includes: [isConstructor.js]
+features: [Reflect.construct]
+---*/
+
+var formatFn = new Intl.DateTimeFormat().format;
+
+assert.sameValue(Object.prototype.toString.call(formatFn), "[object Function]",
+ "The [[Class]] internal property of a built-in function must be " +
+ "\"Function\".");
+
+assert(Object.isExtensible(formatFn),
+ "Built-in objects must be extensible.");
+
+assert.sameValue(Object.getPrototypeOf(formatFn), Function.prototype);
+
+assert.sameValue(formatFn.hasOwnProperty("prototype"), false,
+ "Built-in functions that aren't constructors must not have a prototype property.");
+
+assert.sameValue(isConstructor(formatFn), false,
+ "Built-in functions don't implement [[Construct]] unless explicitly specified.");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/format-function-length.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/format-function-length.js
new file mode 100644
index 0000000000..805c197144
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/format-function-length.js
@@ -0,0 +1,30 @@
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-intl.datetimeformat.prototype.format
+description: >
+ The length of the bound DateTime Format function is 1.
+info: |
+ get Intl.DateTimeFormat.prototype.format
+
+ ...
+ 4. If dtf.[[BoundFormat]] is undefined, then
+ a. Let F be a new built-in function object as defined in DateTime Format Functions (12.1.5).
+ b. Let bf be BoundFunctionCreate(F, dft, « »).
+ c. Perform ! DefinePropertyOrThrow(bf, "length", PropertyDescriptor {[[Value]]: 1,
+ [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true}).
+ ...
+
+includes: [propertyHelper.js]
+---*/
+
+var formatFn = new Intl.DateTimeFormat().format;
+
+assert.sameValue(formatFn.length, 1);
+
+verifyNotEnumerable(formatFn, "length");
+verifyNotWritable(formatFn, "length");
+verifyConfigurable(formatFn, "length");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/format-function-name.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/format-function-name.js
new file mode 100644
index 0000000000..73922bca5f
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/format-function-name.js
@@ -0,0 +1,28 @@
+// Copyright (C) 2016 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.DateTimeFormat.prototype.format
+description: >
+ The bound DateTimeFormat format function is an anonymous function.
+info: |
+ 12.4.3 get Intl.DateTimeFormat.prototype.compare
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in function object, including constructors, has a `name`
+ property whose value is a String. Functions that are identified as
+ anonymous functions use the empty string as the value of the `name`
+ property.
+ Unless otherwise specified, the `name` property of a built-in function
+ object has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*,
+ [[Configurable]]: *true* }.
+includes: [propertyHelper.js]
+---*/
+
+var formatFn = new Intl.DateTimeFormat().format;
+
+verifyProperty(formatFn, "name", {
+ value: "", writable: false, enumerable: false, configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/fractionalSecondDigits.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/fractionalSecondDigits.js
new file mode 100644
index 0000000000..4d5b8db882
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/fractionalSecondDigits.js
@@ -0,0 +1,34 @@
+// Copyright 2019 Google Inc. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-initializedatetimeformat
+description: Checks basic handling of fractionalSecondDigits.
+features: [Intl.DateTimeFormat-fractionalSecondDigits]
+locale: [en-US]
+---*/
+
+const d1 = new Date(2019, 7, 10, 1, 2, 3, 234);
+const d2 = new Date(2019, 7, 10, 1, 2, 3, 567);
+
+let dtf = new Intl.DateTimeFormat(
+ 'en', { minute: "numeric", second: "numeric", fractionalSecondDigits: undefined});
+assert.sameValue(dtf.format(d1), "02:03", "no fractionalSecondDigits");
+assert.sameValue(dtf.format(d2), "02:03", "no fractionalSecondDigits");
+
+dtf = new Intl.DateTimeFormat(
+ 'en', { minute: "numeric", second: "numeric", fractionalSecondDigits: 1});
+assert.sameValue(dtf.format(d1), "02:03.2", "1 fractionalSecondDigits round down");
+assert.sameValue(dtf.format(d2), "02:03.5", "1 fractionalSecondDigits round down");
+
+dtf = new Intl.DateTimeFormat(
+ 'en', { minute: "numeric", second: "numeric", fractionalSecondDigits: 2});
+assert.sameValue(dtf.format(d1), "02:03.23", "2 fractionalSecondDigits round down");
+assert.sameValue(dtf.format(d2), "02:03.56", "2 fractionalSecondDigits round down");
+
+dtf = new Intl.DateTimeFormat(
+ 'en', { minute: "numeric", second: "numeric", fractionalSecondDigits: 3});
+assert.sameValue(dtf.format(d1), "02:03.234", "3 fractionalSecondDigits round down");
+assert.sameValue(dtf.format(d2), "02:03.567", "3 fractionalSecondDigits round down");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/length.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/length.js
new file mode 100644
index 0000000000..9b9ff002b1
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/length.js
@@ -0,0 +1,35 @@
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-intl.datetimeformat.prototype.format
+description: >
+ get Intl.DateTimeFormat.prototype.format.length is 0.
+info: |
+ get Intl.DateTimeFormat.prototype.format
+
+ 17 ECMAScript Standard Built-in Objects:
+
+ Every built-in function object, including constructors, has a length
+ property whose value is an integer. Unless otherwise specified, this
+ value is equal to the largest number of named arguments shown in the
+ subclause headings for the function description. Optional parameters
+ (which are indicated with brackets: [ ]) or rest parameters (which
+ are shown using the form «...name») are not included in the default
+ argument count.
+ Unless otherwise specified, the length property of a built-in function
+ object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+ [[Configurable]]: true }.
+
+includes: [propertyHelper.js]
+---*/
+
+var desc = Object.getOwnPropertyDescriptor(Intl.DateTimeFormat.prototype, "format");
+
+assert.sameValue(desc.get.length, 0);
+
+verifyNotEnumerable(desc.get, "length");
+verifyNotWritable(desc.get, "length");
+verifyConfigurable(desc.get, "length");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/name.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/name.js
new file mode 100644
index 0000000000..3729320d39
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/name.js
@@ -0,0 +1,30 @@
+// Copyright (C) 2016 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.DateTimeFormat.prototype.format
+description: >
+ get Intl.DateTimeFormat.prototype.format.name is "get format".
+info: |
+ 12.4.3 get Intl.DateTimeFormat.prototype.format
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, that is not
+ identified as an anonymous function has a name property whose value
+ is a String.
+
+ Unless otherwise specified, the name property of a built-in Function
+ object, if it exists, has the attributes { [[Writable]]: false,
+ [[Enumerable]]: false, [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+var desc = Object.getOwnPropertyDescriptor(Intl.DateTimeFormat.prototype, "format");
+
+assert.sameValue(desc.get.name, "get format");
+
+verifyNotEnumerable(desc.get, "name");
+verifyNotWritable(desc.get, "name");
+verifyConfigurable(desc.get, "name");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/proleptic-gregorian-calendar.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/proleptic-gregorian-calendar.js
new file mode 100644
index 0000000000..0a76e32cab
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/proleptic-gregorian-calendar.js
@@ -0,0 +1,31 @@
+// Copyright 2012 Mozilla Corporation. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es5id: 12.3.2_FDT_7_a_iv
+description: >
+ Tests that format uses a proleptic Gregorian calendar with no year
+ 0.
+author: Norbert Lindenberg
+---*/
+
+var dates = [
+ 0, // January 1, 1970
+ -62151602400000, // in June 1 BC
+ -8640000000000000 // beginning of ECMAScript time
+];
+
+var format = new Intl.DateTimeFormat(["en-US"], {year: "numeric", month: "long", timeZone: "UTC"});
+
+// this test requires a Gregorian calendar, which we usually find in the US
+assert.sameValue(format.resolvedOptions().calendar, "gregory", "Internal error: Didn't find Gregorian calendar");
+
+dates.forEach(function (date) {
+ var year = new Date(date).getUTCFullYear();
+ var expectedYear = year <= 0 ? 1 - year : year;
+ var expectedYearString = expectedYear.toLocaleString(["en-US"], {useGrouping: false});
+ var dateString = format.format(date);
+ assert.notSameValue(dateString.indexOf(expectedYearString), -1, "Formatted year doesn't contain expected year – expected " + expectedYearString + ", got " + dateString + ".");
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/prop-desc.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/prop-desc.js
new file mode 100644
index 0000000000..737d4841a2
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/prop-desc.js
@@ -0,0 +1,37 @@
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-intl.datetimeformat.prototype.format
+description: >
+ "format" property of Intl.DateTimeFormat.prototype.
+info: |
+ get Intl.DateTimeFormat.prototype.format
+
+ 7 Requirements for Standard Built-in ECMAScript Objects
+
+ Unless specified otherwise in this document, the objects, functions, and constructors
+ described in this standard are subject to the generic requirements and restrictions
+ specified for standard built-in ECMAScript objects in the ECMAScript 2018 Language
+ Specification, 9th edition, clause 17, or successor.
+
+ 17 ECMAScript Standard Built-in Objects:
+
+ Every accessor property described in clauses 18 through 26 and in Annex B.2 has the
+ attributes { [[Enumerable]]: false, [[Configurable]]: true } unless otherwise specified.
+ If only a get accessor function is described, the set accessor function is the default
+ value, undefined. If only a set accessor is described the get accessor is the default
+ value, undefined.
+
+includes: [propertyHelper.js]
+---*/
+
+var desc = Object.getOwnPropertyDescriptor(Intl.DateTimeFormat.prototype, "format");
+
+assert.sameValue(desc.set, undefined);
+assert.sameValue(typeof desc.get, "function");
+
+verifyNotEnumerable(Intl.DateTimeFormat.prototype, "format");
+verifyConfigurable(Intl.DateTimeFormat.prototype, "format");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/related-year-zh.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/related-year-zh.js
new file mode 100644
index 0000000000..eba77bf9e9
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/related-year-zh.js
@@ -0,0 +1,19 @@
+// Copyright 2019 Google Inc, Igalia S.L. All rights reserved.
+// Copyright 2020 Apple Inc. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-partitiondatetimepattern
+description: >
+ Checks the output of 'relatedYear' and 'yearName' type, and
+ the choice of pattern based on calendar.
+locale: [zh-u-ca-chinese]
+---*/
+
+const df = new Intl.DateTimeFormat("zh-u-ca-chinese", {year: "numeric"});
+const date = new Date(2019, 5, 1);
+const formatted = df.format(date);
+const expected = ["2019己亥年", "己亥年"];
+assert(expected.includes(formatted));
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/shell.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/shell.js
new file mode 100644
index 0000000000..a96394ce86
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/shell.js
@@ -0,0 +1,50 @@
+// GENERATED, DO NOT EDIT
+// file: dateConstants.js
+// Copyright (C) 2009 the Sputnik authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: |
+ Collection of date-centric values
+defines:
+ - date_1899_end
+ - date_1900_start
+ - date_1969_end
+ - date_1970_start
+ - date_1999_end
+ - date_2000_start
+ - date_2099_end
+ - date_2100_start
+ - start_of_time
+ - end_of_time
+---*/
+
+var date_1899_end = -2208988800001;
+var date_1900_start = -2208988800000;
+var date_1969_end = -1;
+var date_1970_start = 0;
+var date_1999_end = 946684799999;
+var date_2000_start = 946684800000;
+var date_2099_end = 4102444799999;
+var date_2100_start = 4102444800000;
+
+var start_of_time = -8.64e15;
+var end_of_time = 8.64e15;
+
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+---*/
+
+function isConstructor(f) {
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/taint-Object-prototype.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/taint-Object-prototype.js
new file mode 100644
index 0000000000..b4ca8b4b0d
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/taint-Object-prototype.js
@@ -0,0 +1,18 @@
+// Copyright 2012 Mozilla Corporation. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es5id: 12.3.2_TLT_2
+description: >
+ Tests that the behavior of a Record is not affected by
+ adversarial changes to Object.prototype.
+author: Norbert Lindenberg
+includes: [testIntl.js]
+---*/
+
+taintProperties(["weekday", "era", "year", "month", "day", "hour", "minute", "second", "inDST"]);
+
+var format = new Intl.DateTimeFormat();
+var time = format.format();
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/throws-value-non-finite.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/throws-value-non-finite.js
new file mode 100644
index 0000000000..598b9ec88e
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/throws-value-non-finite.js
@@ -0,0 +1,20 @@
+// Copyright 2012 Mozilla Corporation. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es5id: 12.3.2_FDT_1
+description: Tests that format handles non-finite values correctly.
+author: Norbert Lindenberg
+---*/
+
+var invalidValues = [NaN, Infinity, -Infinity];
+
+var format = new Intl.DateTimeFormat();
+
+invalidValues.forEach(function (value) {
+ assert.throws(RangeError, function() {
+ var result = format.format(value);
+ }, "Invalid value " + value + " was not rejected.");
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/time-clip-near-time-boundaries.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/time-clip-near-time-boundaries.js
new file mode 100644
index 0000000000..0c415ec7ea
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/time-clip-near-time-boundaries.js
@@ -0,0 +1,39 @@
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-partitiondatetimepattern
+description: |
+ TimeClip is applied when calling Intl.DateTimeFormat.prototype.format.
+info: >
+ 12.1.6 PartitionDateTimePattern ( dateTimeFormat, x )
+
+ 1. Let x be TimeClip(x).
+ 2. If x is NaN, throw a RangeError exception.
+ 3. ...
+
+ 20.3.1.15 TimeClip ( time )
+ ...
+ 2. If abs(time) > 8.64 × 10^15, return NaN.
+ ...
+
+includes: [dateConstants.js]
+---*/
+
+var dtf = new Intl.DateTimeFormat();
+
+// Test values near the start of the ECMAScript time range.
+assert.throws(RangeError, function() {
+ dtf.format(start_of_time - 1);
+});
+assert.sameValue(typeof dtf.format(start_of_time), "string");
+assert.sameValue(typeof dtf.format(start_of_time + 1), "string");
+
+// Test values near the end of the ECMAScript time range.
+assert.sameValue(typeof dtf.format(end_of_time - 1), "string");
+assert.sameValue(typeof dtf.format(end_of_time), "string");
+assert.throws(RangeError, function() {
+ dtf.format(end_of_time + 1);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/time-clip-to-integer.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/time-clip-to-integer.js
new file mode 100644
index 0000000000..d7fbe4db66
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/time-clip-to-integer.js
@@ -0,0 +1,39 @@
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-partitiondatetimepattern
+description: |
+ TimeClip applies ToInteger on its input value.
+info: >
+ 12.1.6 PartitionDateTimePattern ( dateTimeFormat, x )
+
+ 1. Let x be TimeClip(x).
+ 2. ...
+
+ 20.3.1.15 TimeClip ( time )
+ ...
+ 3. Let clippedTime be ! ToInteger(time).
+ 4. If clippedTime is -0, set clippedTime to +0.
+ 5. Return clippedTime.
+---*/
+
+// Switch to a time format instead of using DateTimeFormat's default date-only format.
+var dtf = new Intl.DateTimeFormat(undefined, {
+ hour: "numeric", minute: "numeric", second: "numeric"
+});
+
+var expected = dtf.format(0);
+
+assert.sameValue(dtf.format(-0.9), expected, "format(-0.9)");
+assert.sameValue(dtf.format(-0.5), expected, "format(-0.5)");
+assert.sameValue(dtf.format(-0.1), expected, "format(-0.1)");
+assert.sameValue(dtf.format(-Number.MIN_VALUE), expected, "format(-Number.MIN_VALUE)");
+assert.sameValue(dtf.format(-0), expected, "format(-0)");
+assert.sameValue(dtf.format(+0), expected, "format(+0)");
+assert.sameValue(dtf.format(Number.MIN_VALUE), expected, "format(Number.MIN_VALUE)");
+assert.sameValue(dtf.format(0.1), expected, "format(0.1)");
+assert.sameValue(dtf.format(0.5), expected, "format(0.5)");
+assert.sameValue(dtf.format(0.9), expected, "format(0.9)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/timedatestyle-en.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/timedatestyle-en.js
new file mode 100644
index 0000000000..b51cb84475
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/timedatestyle-en.js
@@ -0,0 +1,106 @@
+// Copyright 2019 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-date-time-style-pattern
+description: Checks basic handling of timeStyle and dateStyle.
+features: [Intl.DateTimeFormat-datetimestyle]
+locale: [en-US]
+---*/
+
+const date = new Date("1886-05-01T14:12:47Z");
+const dateOptions = [
+ ["full", "Saturday, May 1, 1886"],
+ ["long", "May 1, 1886"],
+ ["medium", "May 1, 1886"],
+ ["short", "5/1/86"],
+];
+
+const timeOptions = [
+ ["full", "2:12:47 PM Coordinated Universal Time", "14:12:47 Coordinated Universal Time"],
+ ["long", "2:12:47 PM UTC", "14:12:47 UTC"],
+ ["medium", "2:12:47 PM", "14:12:47"],
+ ["short", "2:12 PM", "14:12"],
+];
+
+const options12 = [
+ { "hour12": true },
+ { "hourCycle": "h11" },
+ { "hourCycle": "h12" },
+ { "hourCycle": "h23", "hour12": true },
+ { "hourCycle": "h24", "hour12": true },
+];
+
+const options24 = [
+ { "hour12": false },
+ { "hourCycle": "h23" },
+ { "hourCycle": "h24" },
+ { "hourCycle": "h11", "hour12": false },
+ { "hourCycle": "h12", "hour12": false },
+];
+
+for (const [dateStyle, expected] of dateOptions) {
+ const dtf = new Intl.DateTimeFormat("en-US", {
+ dateStyle,
+ timeZone: "UTC",
+ });
+
+ const dateString = dtf.format(date);
+ assert.sameValue(dateString, expected, `Result for ${dateStyle}`);
+}
+
+for (const [timeStyle, expected12, expected24] of timeOptions) {
+ const check = (locale, options, expected) => {
+ const dtf = new Intl.DateTimeFormat(locale, {
+ timeStyle,
+ timeZone: "UTC",
+ ...options
+ });
+
+ const dateString = dtf.format(date);
+ assert.sameValue(dateString, expected, `Result for ${timeStyle} with ${JSON.stringify(options)}`);
+ };
+
+ check("en-US", {}, expected12);
+ check("en-US-u-hc-h11", {}, expected12);
+ check("en-US-u-hc-h12", {}, expected12);
+ check("en-US-u-hc-h23", {}, expected24);
+ check("en-US-u-hc-h24", {}, expected24);
+
+ for (const hourOptions of options12) {
+ check("en-US", hourOptions, expected12);
+ check("en-US-u-hc-h11", hourOptions, expected12);
+ check("en-US-u-hc-h12", hourOptions, expected12);
+ check("en-US-u-hc-h23", hourOptions, expected12);
+ check("en-US-u-hc-h24", hourOptions, expected12);
+ }
+
+ for (const hourOptions of options24) {
+ check("en-US", hourOptions, expected24);
+ check("en-US-u-hc-h11", hourOptions, expected24);
+ check("en-US-u-hc-h12", hourOptions, expected24);
+ check("en-US-u-hc-h23", hourOptions, expected24);
+ check("en-US-u-hc-h24", hourOptions, expected24);
+ }
+}
+
+for (const [dateStyle, expectedDate] of dateOptions) {
+ for (const [timeStyle, expectedTime] of timeOptions) {
+ const dtf = new Intl.DateTimeFormat("en-US", {
+ dateStyle,
+ timeStyle,
+ timeZone: "UTC",
+ });
+ const result1 = [expectedDate, ", ", expectedTime].join("");
+ const result2 = [expectedDate, " at ", expectedTime].join("");
+
+ const dateString = dtf.format(date);
+ assert.sameValue(
+ [result1, result2].includes(dateString),
+ true,
+ `Result for date=${dateStyle} and time=${timeStyle}`
+ );
+ }
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/argument-date-string.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/argument-date-string.js
new file mode 100644
index 0000000000..edbcbee2c6
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/argument-date-string.js
@@ -0,0 +1,42 @@
+// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// Copyright (C) 2019 Igalia S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-partitiondatetimerangepattern
+description: >
+ The Date constructor is not called to convert the input value.
+info: |
+ Intl.DateTimeFormat.prototype.formatRange ( startDate , endDate )
+
+ 5. Let x be ? ToNumber(startDate).
+ 6. Let y be ? ToNumber(endDate).
+ 8. Return ? FormatDateTimeRange(dtf, x, y).
+
+ PartitionDateTimeRangePattern ( dateTimeFormat, x, y )
+
+ 1. Let x be TimeClip(x).
+ 2. If x is NaN, throw a RangeError exception.
+ 3. Let y be TimeClip(y).
+ 4. If y is NaN, throw a RangeError exception.
+features: [Intl.DateTimeFormat-formatRange]
+---*/
+
+const dtf = new Intl.DateTimeFormat();
+const dateTimeString = "2017-11-10T14:09:00.000Z";
+const date = new Date(dateTimeString);
+// |dateTimeString| is valid ISO-8601 style date/time string.
+assert.notSameValue(date, NaN);
+
+// ToNumber() will try to parse the string as an integer and yield NaN, rather
+// than attempting to parse it like the Date constructor would.
+assert.throws(RangeError, function() {
+ dtf.formatRange(dateTimeString, date);
+});
+
+assert.throws(RangeError, function() {
+ dtf.formatRange(date, dateTimeString);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/argument-near-time-boundaries.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/argument-near-time-boundaries.js
new file mode 100644
index 0000000000..3f0141ed42
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/argument-near-time-boundaries.js
@@ -0,0 +1,50 @@
+// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// Copyright (C) 2019 Igalia S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-partitiondatetimerangepattern
+description: >
+ TimeClip is applied when calling Intl.DateTimeFormat.prototype.formatRange.
+info: |
+ PartitionDateTimeRangePattern ( dateTimeFormat, x, y )
+
+ 1. Let x be TimeClip(x).
+ 2. If x is NaN, throw a RangeError exception.
+ 3. Let y be TimeClip(y).
+ 4. If y is NaN, throw a RangeError exception.
+
+ TimeClip ( time )
+ ...
+ 2. If abs(time) > 8.64 × 10^15, return NaN.
+ ...
+
+includes: [dateConstants.js]
+features: [Intl.DateTimeFormat-formatRange]
+---*/
+
+const dtf = new Intl.DateTimeFormat();
+const date = Date.now();
+
+// Test values near the start of the ECMAScript time range.
+assert.throws(RangeError, function() {
+ dtf.formatRange(start_of_time - 1, date);
+});
+assert.throws(RangeError, function() {
+ dtf.formatRange(date, start_of_time - 1);
+});
+assert.sameValue(typeof dtf.formatRange(start_of_time, date), "string");
+assert.sameValue(typeof dtf.formatRange(start_of_time + 1, date), "string");
+
+// Test values near the end of the ECMAScript time range.
+assert.sameValue(typeof dtf.formatRange(date, end_of_time - 1), "string");
+assert.sameValue(typeof dtf.formatRange(date, end_of_time), "string");
+assert.throws(RangeError, function() {
+ dtf.formatRange(end_of_time + 1, date);
+});
+assert.throws(RangeError, function() {
+ dtf.formatRange(date, end_of_time + 1);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/argument-to-integer.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/argument-to-integer.js
new file mode 100644
index 0000000000..adabb74dc7
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/argument-to-integer.js
@@ -0,0 +1,42 @@
+// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// Copyright (C) 2019 Igalia S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-partitiondatetimerangepattern
+description: >
+ TimeClip applies ToInteger on its input value.
+info: |
+ Intl.DateTimeFormat.prototype.formatRange ( startDate , endDate )
+
+ 5. Let x be ? ToNumber(startDate).
+ 6. Let y be ? ToNumber(endDate).
+
+ TimeClip ( time )
+ ...
+ 3. Let clippedTime be ! ToInteger(time).
+ 4. If clippedTime is -0, set clippedTime to +0.
+ 5. Return clippedTime.
+features: [Intl.DateTimeFormat-formatRange]
+---*/
+
+// Switch to a time format instead of using DateTimeFormat's default date-only format.
+const dtf = new Intl.DateTimeFormat(undefined, {
+ hour: "numeric", minute: "numeric", second: "numeric"
+});
+const date = Date.now();
+const expected = dtf.formatRange(0, date);
+
+assert.sameValue(dtf.formatRange(-0.9, date), expected, "formatRange(-0.9)");
+assert.sameValue(dtf.formatRange(-0.5, date), expected, "formatRange(-0.5)");
+assert.sameValue(dtf.formatRange(-0.1, date), expected, "formatRange(-0.1)");
+assert.sameValue(dtf.formatRange(-Number.MIN_VALUE, date), expected, "formatRange(-Number.MIN_VALUE)");
+assert.sameValue(dtf.formatRange(-0, date), expected, "formatRange(-0)");
+assert.sameValue(dtf.formatRange(+0, date), expected, "formatRange(+0)");
+assert.sameValue(dtf.formatRange(Number.MIN_VALUE, date), expected, "formatRange(Number.MIN_VALUE)");
+assert.sameValue(dtf.formatRange(0.1, date), expected, "formatRange(0.1)");
+assert.sameValue(dtf.formatRange(0.5, date), expected, "formatRange(0.5)");
+assert.sameValue(dtf.formatRange(0.9, date), expected, "formatRange(0.9)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/argument-tonumber-throws.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/argument-tonumber-throws.js
new file mode 100644
index 0000000000..a0178e5b92
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/argument-tonumber-throws.js
@@ -0,0 +1,57 @@
+// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet
+// Copyright 2019 Igalia S.L. All rights reserved.
+// This code is governed by the license found in the LICENSE file.
+
+/*---
+description: >
+ Return abrupt completions from ToNumber(date)
+info: |
+ Intl.DateTimeFormat.prototype.formatRange ( startDate , endDate )
+
+ 5. Let x be ? ToNumber(startDate).
+ 6. Let y be ? ToNumber(endDate).
+features: [Symbol,Intl.DateTimeFormat-formatRange]
+---*/
+
+const date = Date.now();
+
+const objectValueOf = {
+ valueOf: function() {
+ throw new Test262Error();
+ }
+};
+
+const objectToString = {
+ toString: function() {
+ throw new Test262Error();
+ }
+};
+
+const dtf = new Intl.DateTimeFormat(["pt-BR"]);
+
+assert.throws(Test262Error, function() {
+ dtf.formatRange(objectValueOf, date);
+}, "valueOf start");
+
+assert.throws(Test262Error, function() {
+ dtf.formatRange(date, objectValueOf);
+}, "valueOf end");
+
+assert.throws(Test262Error, function() {
+ dtf.formatRange(objectToString, date);
+}, "toString start");
+
+assert.throws(Test262Error, function() {
+ dtf.formatRange(date, objectToString);
+}, "toString end");
+
+const s = Symbol('1');
+assert.throws(TypeError, function() {
+ dtf.formatRange(s, date);
+}, "symbol start");
+
+assert.throws(TypeError, function() {
+ dtf.formatRange(date, s);
+}, "symbol end");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/browser.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/browser.js
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/builtin.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/builtin.js
new file mode 100644
index 0000000000..2b42ca92ea
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/builtin.js
@@ -0,0 +1,33 @@
+// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet
+// Copyright 2012 Mozilla Corporation. All rights reserved.
+// Copyright 2019 Igalia S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-ecmascript-standard-built-in-objects
+description: >
+ Tests that the Intl.DateTimeFormat.prototype.formatRange function meets the
+ requirements for built-in objects defined by the ECMAScript Language
+ Specification.
+includes: [isConstructor.js]
+features: [Reflect.construct,Intl.DateTimeFormat-formatRange]
+---*/
+
+const formatRange = Intl.DateTimeFormat.prototype.formatRange;
+
+assert.sameValue(Object.prototype.toString.call(formatRange), "[object Function]",
+ "The [[Class]] internal property of a built-in function must be " +
+ "\"Function\".");
+
+assert(Object.isExtensible(formatRange),
+ "Built-in objects must be extensible.");
+
+assert.sameValue(Object.getPrototypeOf(formatRange), Function.prototype);
+
+assert.sameValue(formatRange.hasOwnProperty("prototype"), false,
+ "Built-in functions that aren't constructors must not have a prototype property.");
+
+assert.sameValue(isConstructor(formatRange), false,
+ "Built-in functions don't implement [[Construct]] unless explicitly specified.");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/date-is-infinity-throws.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/date-is-infinity-throws.js
new file mode 100644
index 0000000000..9ddfd159e8
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/date-is-infinity-throws.js
@@ -0,0 +1,73 @@
+// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet
+// Copyright 2019 Google, Inc. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Throws a RangeError if date arg is cast to an Infinity value
+info: |
+ Intl.DateTimeFormat.prototype.formatRange ( startDate , endDate )
+
+ 1. Let dtf be this value.
+ 2. If Type(dtf) is not Object, throw a TypeError exception.
+ 3. If dtf does not have an [[InitializedDateTimeFormat]] internal slot, throw a TypeError exception.
+ 4. If startDate is undefined or endDate is undefined, throw a RangeError exception.
+ 5. Let x be ? ToNumber(startDate).
+ 6. Let y be ? ToNumber(endDate).
+ 7. If x is greater than y, throw a RangeError exception.
+ 8. Return ? FormatDateTimeRange(dtf, x, y).
+
+ FormatDateTimeRange ( dateTimeFormat, x, y )
+
+ 1. Let parts be ? PartitionDateTimeRangePattern(dateTimeFormat, x, y).
+
+ PartitionDateTimeRangePattern ( dateTimeFormat, x, y )
+
+ 1. Let x be TimeClip(x).
+ 2. If x is NaN, throw a RangeError exception.
+ 3. Let y be TimeClip(y).
+ 4. If y is NaN, throw a RangeError exception.
+
+ TimeClip ( time )
+ 1. If time is not finite, return NaN.
+
+features: [Intl.DateTimeFormat-formatRange]
+---*/
+
+var dtf = new Intl.DateTimeFormat();
+
+var date = new Date();
+
+assert.throws(RangeError, function() {
+ dtf.formatRange(Infinity, date);
+}, "+Infinity/date");
+
+assert.throws(RangeError, function() {
+ dtf.formatRange(-Infinity, date);
+}, "-Infinity/date");
+
+assert.throws(RangeError, function() {
+ dtf.formatRange(date, Infinity);
+}, "date/+Infinity");
+
+assert.throws(RangeError, function() {
+ dtf.formatRange(date, -Infinity);
+}, "date/-Infinity");
+
+assert.throws(RangeError, function() {
+ dtf.formatRange(Infinity, Infinity);
+}, "+Infinity/+Infinity");
+
+assert.throws(RangeError, function() {
+ dtf.formatRange(-Infinity, -Infinity);
+}, "-Infinity/-Infinity");
+
+assert.throws(RangeError, function() {
+ dtf.formatRange(Infinity, -Infinity);
+}, "+Infinity/-Infinity");
+
+assert.throws(RangeError, function() {
+ dtf.formatRange(-Infinity, Infinity);
+}, "-Infinity/+Infinity");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/date-is-nan-throws.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/date-is-nan-throws.js
new file mode 100644
index 0000000000..52621dd1a4
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/date-is-nan-throws.js
@@ -0,0 +1,50 @@
+// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet
+// Copyright 2019 Google, Inc. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Throws a RangeError if date arg is cast to NaN
+info: |
+ Intl.DateTimeFormat.prototype.formatRange ( startDate , endDate )
+
+ 1. Let dtf be this value.
+ 2. If Type(dtf) is not Object, throw a TypeError exception.
+ 3. If dtf does not have an [[InitializedDateTimeFormat]] internal slot, throw a TypeError exception.
+ 4. If startDate is undefined or endDate is undefined, throw a RangeError exception.
+ 5. Let x be ? ToNumber(startDate).
+ 6. Let y be ? ToNumber(endDate).
+ 7. If x is greater than y, throw a RangeError exception.
+ 8. Return ? FormatDateTimeRange(dtf, x, y).
+
+ FormatDateTimeRange ( dateTimeFormat, x, y )
+
+ 1. Let parts be ? PartitionDateTimeRangePattern(dateTimeFormat, x, y).
+
+ PartitionDateTimeRangePattern ( dateTimeFormat, x, y )
+
+ 1. Let x be TimeClip(x).
+ 2. If x is NaN, throw a RangeError exception.
+ 3. Let y be TimeClip(y).
+ 4. If y is NaN, throw a RangeError exception.
+
+features: [Intl.DateTimeFormat-formatRange]
+---*/
+
+var dtf = new Intl.DateTimeFormat();
+
+var date = new Date();
+
+assert.throws(RangeError, function() {
+ dtf.formatRange(NaN, date);
+}, "NaN/date");
+
+assert.throws(RangeError, function() {
+ dtf.formatRange(date, NaN);
+}, "date/NaN");
+
+assert.throws(RangeError, function() {
+ dtf.formatRange(NaN, NaN);
+}, "NaN/NaN");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/date-same-returns-single-date.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/date-same-returns-single-date.js
new file mode 100644
index 0000000000..684130fc7c
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/date-same-returns-single-date.js
@@ -0,0 +1,64 @@
+// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet
+// Copyright 2021 Google Inc. All rights reserved.
+// Copyright 2021 Apple Inc. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-partitiondatetimerangepattern
+description: >
+ When startDate is equal to endDate, the output should be a string equal
+ to the output of Intl.DateTimeFormat.prototype.format.
+info: |
+ Intl.DateTimeFormat.prototype.formatRange ( startDate , endDate )
+
+ 4. Let x be ? ToNumber(startDate).
+ 5. Let y be ? ToNumber(endDate).
+ 6. Return ? FormatDateTimeRange(dtf, x, y).
+
+ PartitionDateTimeRangePattern ( dateTimeFormat, x, y )
+
+ 13. If dateFieldsPracticallyEqual is true, then
+ a. Let pattern be dateTimeFormat.[[Pattern]].
+ b. Let patternParts be PartitionPattern(pattern).
+ c. Let result be ? FormatDateTimePattern(dateTimeFormat, patternParts, tm1).
+ d. For each r in result do
+ i. Set r.[[Source]] to "shared".
+ e. Return result.
+
+features: [Intl.DateTimeFormat-formatRange]
+locale: [en-US]
+---*/
+
+{
+ const date = new Date(2019, 7, 10, 1, 2, 3, 234);
+
+ let dtf = new Intl.DateTimeFormat("en", { year: "numeric", month: "short", day: "numeric" });
+ assert.sameValue(dtf.formatRange(date, date), dtf.format(date), "same output with date options");
+
+ dtf = new Intl.DateTimeFormat("en", { minute: "numeric", second: "numeric" });
+ assert.sameValue(dtf.formatRange(date, date), dtf.format(date), "same output with time options");
+
+ dtf = new Intl.DateTimeFormat("en", { month: "short", day: "numeric", minute: "numeric" });
+ assert.sameValue(dtf.formatRange(date, date), dtf.format(date), "same output with date-time options");
+
+ dtf = new Intl.DateTimeFormat("en", { dateStyle: "long", timeStyle: "short" });
+ assert.sameValue(dtf.formatRange(date, date), dtf.format(date), "same output with dateStyle/timeStyle");
+}
+{
+ const date1 = new Date(2019, 7, 10, 1, 2, 3, 234);
+ const date2 = new Date(2019, 7, 10, 1, 2, 3, 235);
+
+ let dtf = new Intl.DateTimeFormat("en", { year: "numeric", month: "short", day: "numeric" });
+ assert.sameValue(dtf.formatRange(date1, date2), dtf.format(date1), "same output with date options");
+
+ dtf = new Intl.DateTimeFormat("en", { minute: "numeric", second: "numeric" });
+ assert.sameValue(dtf.formatRange(date1, date2), dtf.format(date1), "same output with time options");
+
+ dtf = new Intl.DateTimeFormat("en", { month: "short", day: "numeric", minute: "numeric" });
+ assert.sameValue(dtf.formatRange(date1, date2), dtf.format(date1), "same output with date-time options");
+
+ dtf = new Intl.DateTimeFormat("en", { dateStyle: "long", timeStyle: "short" });
+ assert.sameValue(dtf.formatRange(date1, date2), dtf.format(date1), "same output with dateStyle/timeStyle");
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/date-undefined-throws.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/date-undefined-throws.js
new file mode 100644
index 0000000000..69946151c5
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/date-undefined-throws.js
@@ -0,0 +1,45 @@
+// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet
+// Copyright 2019 Google, Inc. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Throws a TypeError if startDate or endDate is undefined.
+info: |
+ Intl.DateTimeFormat.prototype.formatRange ( startDate , endDate )
+
+ 1. Let dtf be this value.
+ 2. If Type(dtf) is not Object, throw a TypeError exception.
+ 3. If dtf does not have an [[InitializedDateTimeFormat]] internal slot, throw a TypeError exception.
+ 4. If startDate is undefined or endDate is undefined, throw a TypeError exception.
+ 5. Let x be ? ToNumber(startDate).
+ 6. Let y be ? ToNumber(endDate).
+
+features: [Intl.DateTimeFormat-formatRange]
+---*/
+
+var dtf = new Intl.DateTimeFormat();
+
+assert.throws(TypeError, function() {
+ dtf.formatRange(); // Not possible to poison this one
+}, "no args");
+
+var poison = { valueOf() { throw new Test262Error(); } };
+
+assert.throws(TypeError, function() {
+ dtf.formatRange(undefined, poison);
+}, "date/undefined");
+
+assert.throws(TypeError, function() {
+ dtf.formatRange(poison, undefined);
+}, "undefined/date");
+
+assert.throws(TypeError, function() {
+ dtf.formatRange(poison);
+}, "only one arg");
+
+assert.throws(TypeError, function() {
+ dtf.formatRange(undefined, undefined);
+}, "undefined/undefined");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/date-x-greater-than-y-throws.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/date-x-greater-than-y-throws.js
new file mode 100644
index 0000000000..52a44597a9
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/date-x-greater-than-y-throws.js
@@ -0,0 +1,40 @@
+// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet
+// Copyright 2019 Google, Inc. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Throws a RangeError if date x is greater than y.
+info: |
+ Intl.DateTimeFormat.prototype.formatRange ( startDate , endDate )
+
+ 4. Let x be ? ToNumber(startDate).
+ 5. Let y be ? ToNumber(endDate).
+ 6. Return ? FormatDateTimeRange(dtf, x, y).
+
+ PartitionDateTimeRangePattern ( dateTimeFormat, x, y )
+
+ 1. Let x be TimeClip(x).
+ 2. If x is NaN, throw a RangeError exception.
+ 3. Let y be TimeClip(y).
+ 4. If y is NaN, throw a RangeError exception.
+ 5. If x is greater than y, throw a RangeError exception.
+
+features: [Intl.DateTimeFormat-formatRange]
+---*/
+
+var dtf = new Intl.DateTimeFormat();
+
+var x = new Date();
+var y = new Date();
+x.setDate(y.getDate() + 1);
+
+assert.throws(RangeError, function() {
+ dtf.formatRange(x, y);
+}, "x > y");
+
+assert.sameValue("string", typeof dtf.formatRange(x, x));
+assert.sameValue("string", typeof dtf.formatRange(y, y));
+assert.sameValue("string", typeof dtf.formatRange(y, x));
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/en-US.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/en-US.js
new file mode 100644
index 0000000000..7fc01e452a
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/en-US.js
@@ -0,0 +1,39 @@
+// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet
+// Copyright (C) 2019 the V8 project authors, Igalia S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-partitiondatetimerangepattern
+description: Basic tests for the en-US output of formatRange()
+info: |
+ Intl.DateTimeFormat.prototype.formatRange ( startDate , endDate )
+
+ 8. Return ? FormatDateTimeRange(dtf, x, y).
+locale: [en-US]
+features: [Intl.DateTimeFormat-formatRange]
+---*/
+
+const date1 = new Date("2019-01-03T00:00:00");
+const date2 = new Date("2019-01-05T00:00:00");
+const date3 = new Date("2019-03-04T00:00:00");
+const date4 = new Date("2020-03-04T00:00:00");
+
+let dtf = new Intl.DateTimeFormat("en-US");
+assert.sameValue(dtf.formatRange(date1, date1), "1/3/2019");
+assert.sameValue(dtf.formatRange(date1, date2), "1/3/2019 – 1/5/2019");
+assert.sameValue(dtf.formatRange(date1, date3), "1/3/2019 – 3/4/2019");
+assert.sameValue(dtf.formatRange(date1, date4), "1/3/2019 – 3/4/2020");
+assert.sameValue(dtf.formatRange(date2, date3), "1/5/2019 – 3/4/2019");
+assert.sameValue(dtf.formatRange(date2, date4), "1/5/2019 – 3/4/2020");
+assert.sameValue(dtf.formatRange(date3, date4), "3/4/2019 – 3/4/2020");
+
+dtf = new Intl.DateTimeFormat("en-US", {year: "numeric", month: "short", day: "numeric"});
+assert.sameValue(dtf.formatRange(date1, date1), "Jan 3, 2019");
+assert.sameValue(dtf.formatRange(date1, date2), "Jan 3 – 5, 2019");
+assert.sameValue(dtf.formatRange(date1, date3), "Jan 3 – Mar 4, 2019");
+assert.sameValue(dtf.formatRange(date1, date4), "Jan 3, 2019 – Mar 4, 2020");
+assert.sameValue(dtf.formatRange(date2, date3), "Jan 5 – Mar 4, 2019");
+assert.sameValue(dtf.formatRange(date2, date4), "Jan 5, 2019 – Mar 4, 2020");
+assert.sameValue(dtf.formatRange(date3, date4), "Mar 4, 2019 – Mar 4, 2020");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/fractionalSecondDigits.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/fractionalSecondDigits.js
new file mode 100644
index 0000000000..89b83aeacb
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/fractionalSecondDigits.js
@@ -0,0 +1,36 @@
+// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet
+// Copyright 2019 Google Inc. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-initializedatetimeformat
+description: Checks basic handling of fractionalSecondDigits.
+features: [Intl.DateTimeFormat-fractionalSecondDigits, Intl.DateTimeFormat-formatRange]
+locale: [en-US]
+---*/
+
+const d1 = new Date(2019, 7, 10, 1, 2, 3, 234);
+const d2 = new Date(2019, 7, 10, 1, 2, 3, 567);
+const d3 = new Date(2019, 7, 10, 1, 2, 13, 987);
+
+let dtf = new Intl.DateTimeFormat(
+ 'en', { minute: "numeric", second: "numeric", fractionalSecondDigits: undefined});
+assert.sameValue(dtf.formatRange(d1, d2), "02:03", "no fractionalSecondDigits");
+assert.sameValue(dtf.formatRange(d1, d3), "02:03 – 02:13", "no fractionalSecondDigits");
+
+dtf = new Intl.DateTimeFormat(
+ 'en', { minute: "numeric", second: "numeric", fractionalSecondDigits: 1});
+assert.sameValue(dtf.formatRange(d1, d2), "02:03.2 – 02:03.5", "1 fractionalSecondDigits round down");
+assert.sameValue(dtf.formatRange(d1, d3), "02:03.2 – 02:13.9", "1 fractionalSecondDigits round down");
+
+dtf = new Intl.DateTimeFormat(
+ 'en', { minute: "numeric", second: "numeric", fractionalSecondDigits: 2});
+assert.sameValue(dtf.formatRange(d1, d2), "02:03.23 – 02:03.56", "2 fractionalSecondDigits round down");
+assert.sameValue(dtf.formatRange(d1, d3), "02:03.23 – 02:13.98", "2 fractionalSecondDigits round down");
+
+dtf = new Intl.DateTimeFormat(
+ 'en', { minute: "numeric", second: "numeric", fractionalSecondDigits: 3});
+assert.sameValue(dtf.formatRange(d1, d2), "02:03.234 – 02:03.567", "3 fractionalSecondDigits round down");
+assert.sameValue(dtf.formatRange(d1, d3), "02:03.234 – 02:13.987", "3 fractionalSecondDigits round down");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/length.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/length.js
new file mode 100644
index 0000000000..f2f1997596
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/length.js
@@ -0,0 +1,17 @@
+// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet
+// Copyright 2019 Google, Inc. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Intl.DateTimeFormat.prototype.formatRange.length.
+includes: [propertyHelper.js]
+features: [Intl.DateTimeFormat-formatRange]
+---*/
+verifyProperty(Intl.DateTimeFormat.prototype.formatRange, 'length', {
+ value: 2,
+ enumerable: false,
+ writable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/name.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/name.js
new file mode 100644
index 0000000000..1ef3d5199a
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/name.js
@@ -0,0 +1,17 @@
+// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet
+// Copyright 2019 Google, Inc. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Intl.DateTimeFormat.prototype.formatRange.name value and descriptor.
+includes: [propertyHelper.js]
+features: [Intl.DateTimeFormat-formatRange]
+---*/
+verifyProperty(Intl.DateTimeFormat.prototype.formatRange, 'name', {
+ value: 'formatRange',
+ enumerable: false,
+ writable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/prop-desc.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/prop-desc.js
new file mode 100644
index 0000000000..c628b1866b
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/prop-desc.js
@@ -0,0 +1,24 @@
+// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet
+// Copyright 2016 Mozilla Corporation. All rights reserved.
+// Copyright 2019 Igalia S.L. All rights reserved.
+// This code is governed by the license found in the LICENSE file.
+
+/*---
+description: Property type and descriptor.
+includes: [propertyHelper.js]
+features: [Intl.DateTimeFormat-formatRange]
+---*/
+
+assert.sameValue(
+ typeof Intl.DateTimeFormat.prototype.formatRange,
+ 'function',
+ '`typeof Intl.DateTimeFormat.prototype.formatRange` is `function`'
+);
+
+verifyProperty(Intl.DateTimeFormat.prototype, 'formatRange', {
+ enumerable: false,
+ writable: true,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/shell.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/shell.js
new file mode 100644
index 0000000000..a96394ce86
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/shell.js
@@ -0,0 +1,50 @@
+// GENERATED, DO NOT EDIT
+// file: dateConstants.js
+// Copyright (C) 2009 the Sputnik authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: |
+ Collection of date-centric values
+defines:
+ - date_1899_end
+ - date_1900_start
+ - date_1969_end
+ - date_1970_start
+ - date_1999_end
+ - date_2000_start
+ - date_2099_end
+ - date_2100_start
+ - start_of_time
+ - end_of_time
+---*/
+
+var date_1899_end = -2208988800001;
+var date_1900_start = -2208988800000;
+var date_1969_end = -1;
+var date_1970_start = 0;
+var date_1999_end = 946684799999;
+var date_2000_start = 946684800000;
+var date_2099_end = 4102444799999;
+var date_2100_start = 4102444800000;
+
+var start_of_time = -8.64e15;
+var end_of_time = 8.64e15;
+
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+---*/
+
+function isConstructor(f) {
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/this-bad-object.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/this-bad-object.js
new file mode 100644
index 0000000000..f3bf16339f
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/this-bad-object.js
@@ -0,0 +1,29 @@
+// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet
+// Copyright 2019 Igalia, S.L. All rights reserved.
+// This code is governed by the license found in the LICENSE file.
+
+/*---
+description: >
+ Throws a TypeError if this is not a DateTimeFormat object
+features: [Intl.DateTimeFormat-formatRange]
+---*/
+
+const formatRange = Intl.DateTimeFormat.prototype.formatRange;
+
+assert.throws(TypeError, function() {
+ formatRange.call({});
+}, "{}");
+
+assert.throws(TypeError, function() {
+ formatRange.call(new Date());
+}, "new Date()");
+
+assert.throws(TypeError, function() {
+ formatRange.call(Intl.DateTimeFormat);
+}, "Intl.DateTimeFormat");
+
+assert.throws(TypeError, function() {
+ formatRange.call(Intl.DateTimeFormat.prototype);
+}, "Intl.DateTimeFormat.prototype");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/this-is-not-object-throws.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/this-is-not-object-throws.js
new file mode 100644
index 0000000000..8bd0016e2f
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/this-is-not-object-throws.js
@@ -0,0 +1,50 @@
+// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet
+// Copyright 2019 Google, Inc. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Throws a TypeError if this is not Object.
+info: |
+ Intl.DateTimeFormat.prototype.formatRange ( startDate , endDate )
+
+ 1. Let dtf be this value.
+ 2. If Type(dtf) is not Object, throw a TypeError exception.
+
+features: [Intl.DateTimeFormat-formatRange, Symbol]
+---*/
+
+let formatRange = Intl.DateTimeFormat.prototype.formatRange;
+let d1 = new Date("1997-08-22T00:00");
+let d2 = new Date("1999-06-26T00:00");
+
+assert.throws(TypeError, function() {
+ formatRange.call(undefined, d1, d2);
+}, "undefined");
+
+assert.throws(TypeError, function() {
+ formatRange.call(null, d1, d2);
+}, "null");
+
+assert.throws(TypeError, function() {
+ formatRange.call(42, d1, d2);
+}, "number");
+
+assert.throws(TypeError, function() {
+ formatRange.call("foo", d1, d2);
+}, "string");
+
+assert.throws(TypeError, function() {
+ formatRange.call(false, d1, d2);
+}, "false");
+
+assert.throws(TypeError, function() {
+ formatRange.call(true, d1, d2);
+}, "true");
+
+var s = Symbol('3');
+assert.throws(TypeError, function() {
+ formatRange.call(s, d1, d2);
+}, "symbol");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/argument-date-string.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/argument-date-string.js
new file mode 100644
index 0000000000..b61c8219c6
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/argument-date-string.js
@@ -0,0 +1,42 @@
+// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// Copyright (C) 2019 Igalia S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-partitiondatetimerangepattern
+description: >
+ The Date constructor is not called to convert the input value.
+info: |
+ Intl.DateTimeFormat.prototype.formatRangeToParts ( startDate , endDate )
+
+ 5. Let x be ? ToNumber(startDate).
+ 6. Let y be ? ToNumber(endDate).
+ 8. Return ? FormatDateTimeRange(dtf, x, y).
+
+ PartitionDateTimeRangePattern ( dateTimeFormat, x, y )
+
+ 1. Let x be TimeClip(x).
+ 2. If x is NaN, throw a RangeError exception.
+ 3. Let y be TimeClip(y).
+ 4. If y is NaN, throw a RangeError exception.
+features: [Intl.DateTimeFormat-formatRange]
+---*/
+
+const dtf = new Intl.DateTimeFormat();
+const dateTimeString = "2017-11-10T14:09:00.000Z";
+const date = new Date(dateTimeString);
+// |dateTimeString| is valid ISO-8601 style date/time string.
+assert.notSameValue(date, NaN);
+
+// ToNumber() will try to parse the string as an integer and yield NaN, rather
+// than attempting to parse it like the Date constructor would.
+assert.throws(RangeError, function() {
+ dtf.formatRangeToParts(dateTimeString, date);
+});
+
+assert.throws(RangeError, function() {
+ dtf.formatRangeToParts(date, dateTimeString);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/argument-near-time-boundaries.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/argument-near-time-boundaries.js
new file mode 100644
index 0000000000..1ce7ce1e7c
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/argument-near-time-boundaries.js
@@ -0,0 +1,50 @@
+// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// Copyright (C) 2019 Igalia S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-partitiondatetimerangepattern
+description: >
+ TimeClip is applied when calling Intl.DateTimeFormat.prototype.formatRangeToParts.
+info: |
+ PartitionDateTimeRangePattern ( dateTimeFormat, x, y )
+
+ 1. Let x be TimeClip(x).
+ 2. If x is NaN, throw a RangeError exception.
+ 3. Let y be TimeClip(y).
+ 4. If y is NaN, throw a RangeError exception.
+
+ TimeClip ( time )
+ ...
+ 2. If abs(time) > 8.64 × 10^15, return NaN.
+ ...
+
+includes: [dateConstants.js]
+features: [Intl.DateTimeFormat-formatRange]
+---*/
+
+const dtf = new Intl.DateTimeFormat();
+const date = Date.now();
+
+// Test values near the start of the ECMAScript time range.
+assert.throws(RangeError, function() {
+ dtf.formatRangeToParts(start_of_time - 1, date);
+});
+assert.throws(RangeError, function() {
+ dtf.formatRangeToParts(date, start_of_time - 1);
+});
+assert.sameValue(typeof dtf.formatRangeToParts(start_of_time, date), "object");
+assert.sameValue(typeof dtf.formatRangeToParts(start_of_time + 1, date), "object");
+
+// Test values near the end of the ECMAScript time range.
+assert.sameValue(typeof dtf.formatRangeToParts(date, end_of_time - 1), "object");
+assert.sameValue(typeof dtf.formatRangeToParts(date, end_of_time), "object");
+assert.throws(RangeError, function() {
+ dtf.formatRangeToParts(end_of_time + 1, date);
+});
+assert.throws(RangeError, function() {
+ dtf.formatRangeToParts(date, end_of_time + 1);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/argument-to-integer.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/argument-to-integer.js
new file mode 100644
index 0000000000..eb36b29eac
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/argument-to-integer.js
@@ -0,0 +1,57 @@
+// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// Copyright (C) 2019 Igalia S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-partitiondatetimerangepattern
+description: >
+ TimeClip applies ToInteger on its input value.
+info: |
+ Intl.DateTimeFormat.prototype.formatRangeToParts ( startDate , endDate )
+
+ 5. Let x be ? ToNumber(startDate).
+ 6. Let y be ? ToNumber(endDate).
+
+ TimeClip ( time )
+ ...
+ 3. Let clippedTime be ! ToInteger(time).
+ 4. If clippedTime is -0, set clippedTime to +0.
+ 5. Return clippedTime.
+features: [Intl.DateTimeFormat-formatRange]
+---*/
+
+function* zip(a, b) {
+ assert.sameValue(a.length, b.length);
+ for (let i = 0; i < a.length; ++i) {
+ yield [i, a[i], b[i]];
+ }
+}
+
+function compare(actual, expected, message) {
+ for (const [i, actualEntry, expectedEntry] of zip(actual, expected)) {
+ assert.sameValue(actualEntry.type, expectedEntry.type, `${message}: type for entry ${i}`);
+ assert.sameValue(actualEntry.value, expectedEntry.value, `${message}: value for entry ${i}`);
+ assert.sameValue(actualEntry.source, expectedEntry.source, `${message}: source for entry ${i}`);
+ }
+}
+
+// Switch to a time format instead of using DateTimeFormat's default date-only format.
+const dtf = new Intl.DateTimeFormat(undefined, {
+ hour: "numeric", minute: "numeric", second: "numeric"
+});
+const date = Date.now();
+const expected = dtf.formatRangeToParts(0, date);
+
+compare(dtf.formatRangeToParts(-0.9, date), expected, "formatRangeToParts(-0.9)");
+compare(dtf.formatRangeToParts(-0.5, date), expected, "formatRangeToParts(-0.5)");
+compare(dtf.formatRangeToParts(-0.1, date), expected, "formatRangeToParts(-0.1)");
+compare(dtf.formatRangeToParts(-Number.MIN_VALUE, date), expected, "formatRangeToParts(-Number.MIN_VALUE)");
+compare(dtf.formatRangeToParts(-0, date), expected, "formatRangeToParts(-0)");
+compare(dtf.formatRangeToParts(+0, date), expected, "formatRangeToParts(+0)");
+compare(dtf.formatRangeToParts(Number.MIN_VALUE, date), expected, "formatRangeToParts(Number.MIN_VALUE)");
+compare(dtf.formatRangeToParts(0.1, date), expected, "formatRangeToParts(0.1)");
+compare(dtf.formatRangeToParts(0.5, date), expected, "formatRangeToParts(0.5)");
+compare(dtf.formatRangeToParts(0.9, date), expected, "formatRangeToParts(0.9)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/argument-tonumber-throws.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/argument-tonumber-throws.js
new file mode 100644
index 0000000000..287c853cc1
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/argument-tonumber-throws.js
@@ -0,0 +1,57 @@
+// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet
+// Copyright 2019 Igalia S.L. All rights reserved.
+// This code is governed by the license found in the LICENSE file.
+
+/*---
+description: >
+ Return abrupt completions from ToNumber(date)
+info: |
+ Intl.DateTimeFormat.prototype.formatRangeToParts ( startDate , endDate )
+
+ 5. Let x be ? ToNumber(startDate).
+ 6. Let y be ? ToNumber(endDate).
+features: [Symbol,Intl.DateTimeFormat-formatRange]
+---*/
+
+const date = Date.now();
+
+const objectValueOf = {
+ valueOf: function() {
+ throw new Test262Error();
+ }
+};
+
+const objectToString = {
+ toString: function() {
+ throw new Test262Error();
+ }
+};
+
+const dtf = new Intl.DateTimeFormat(["pt-BR"]);
+
+assert.throws(Test262Error, function() {
+ dtf.formatRangeToParts(objectValueOf, date);
+}, "valueOf start");
+
+assert.throws(Test262Error, function() {
+ dtf.formatRangeToParts(date, objectValueOf);
+}, "valueOf end");
+
+assert.throws(Test262Error, function() {
+ dtf.formatRangeToParts(objectToString, date);
+}, "toString start");
+
+assert.throws(Test262Error, function() {
+ dtf.formatRangeToParts(date, objectToString);
+}, "toString end");
+
+const s = Symbol('1');
+assert.throws(TypeError, function() {
+ dtf.formatRangeToParts(s, date);
+}, "symbol start");
+
+assert.throws(TypeError, function() {
+ dtf.formatRangeToParts(date, s);
+}, "symbol end");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/browser.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/browser.js
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/builtin.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/builtin.js
new file mode 100644
index 0000000000..6807ddf6b0
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/builtin.js
@@ -0,0 +1,33 @@
+// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet
+// Copyright 2012 Mozilla Corporation. All rights reserved.
+// Copyright 2019 Igalia S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-ecmascript-standard-built-in-objects
+description: >
+ Tests that the Intl.DateTimeFormat.prototype.formatRangeToParts function meets the
+ requirements for built-in objects defined by the ECMAScript Language
+ Specification.
+includes: [isConstructor.js]
+features: [Reflect.construct,Intl.DateTimeFormat-formatRange]
+---*/
+
+const formatRangeToParts = Intl.DateTimeFormat.prototype.formatRangeToParts;
+
+assert.sameValue(Object.prototype.toString.call(formatRangeToParts), "[object Function]",
+ "The [[Class]] internal property of a built-in function must be " +
+ "\"Function\".");
+
+assert(Object.isExtensible(formatRangeToParts),
+ "Built-in objects must be extensible.");
+
+assert.sameValue(Object.getPrototypeOf(formatRangeToParts), Function.prototype);
+
+assert.sameValue(formatRangeToParts.hasOwnProperty("prototype"), false,
+ "Built-in functions that aren't constructors must not have a prototype property.");
+
+assert.sameValue(isConstructor(formatRangeToParts), false,
+ "Built-in functions don't implement [[Construct]] unless explicitly specified.");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/date-is-infinity-throws.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/date-is-infinity-throws.js
new file mode 100644
index 0000000000..d9d9b27c9d
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/date-is-infinity-throws.js
@@ -0,0 +1,72 @@
+// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet
+// Copyright 2019 Google, Inc. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Throws a RangeError if date arg is cast to an Infinity value
+info: |
+ Intl.DateTimeFormat.prototype.formatRangeToParts ( startDate , endDate )
+
+ 1. Let dtf be this value.
+ 2. If Type(dtf) is not Object, throw a TypeError exception.
+ 3. If dtf does not have an [[InitializedDateTimeFormat]] internal slot, throw a TypeError exception.
+ 4. If startDate is undefined or endDate is undefined, throw a RangeError exception.
+ 5. Let x be ? ToNumber(startDate).
+ 6. Let y be ? ToNumber(endDate).
+ 7. If x is greater than y, throw a RangeError exception.
+ 8. Return ? FormatDateTimeRangeToParts(dtf, x, y).
+
+ FormatDateTimeRangeToParts ( dateTimeFormat, x, y )
+
+ 1. Let parts be ? PartitionDateTimeRangePattern(dateTimeFormat, x, y).
+
+ PartitionDateTimeRangePattern ( dateTimeFormat, x, y )
+ 1. Let x be TimeClip(x).
+ 2. If x is NaN, throw a RangeError exception.
+ 3. Let y be TimeClip(y).
+ 4. If y is NaN, throw a RangeError exception.
+
+ TimeClip ( time )
+ 1. If time is not finite, return NaN.
+
+features: [Intl.DateTimeFormat-formatRange]
+---*/
+
+var dtf = new Intl.DateTimeFormat();
+
+var date = new Date();
+
+assert.throws(RangeError, function() {
+ dtf.formatRangeToParts(Infinity, date);
+}, "+Infinity/date");
+
+assert.throws(RangeError, function() {
+ dtf.formatRangeToParts(-Infinity, date);
+}, "-Infinity/date");
+
+assert.throws(RangeError, function() {
+ dtf.formatRangeToParts(date, Infinity);
+}, "date/+Infinity");
+
+assert.throws(RangeError, function() {
+ dtf.formatRangeToParts(date, -Infinity);
+}, "date/-Infinity");
+
+assert.throws(RangeError, function() {
+ dtf.formatRangeToParts(Infinity, Infinity);
+}, "+Infinity/+Infinity");
+
+assert.throws(RangeError, function() {
+ dtf.formatRangeToParts(-Infinity, -Infinity);
+}, "-Infinity/-Infinity");
+
+assert.throws(RangeError, function() {
+ dtf.formatRangeToParts(Infinity, -Infinity);
+}, "+Infinity/-Infinity");
+
+assert.throws(RangeError, function() {
+ dtf.formatRangeToParts(-Infinity, Infinity);
+}, "-Infinity/+Infinity");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/date-is-nan-throws.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/date-is-nan-throws.js
new file mode 100644
index 0000000000..22d3f5af15
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/date-is-nan-throws.js
@@ -0,0 +1,50 @@
+// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet
+// Copyright 2019 Google, Inc. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Throws a RangeError if date arg is cast to Nan
+info: |
+ Intl.DateTimeFormat.prototype.formatRangeToParts ( startDate , endDate )
+
+ 1. Let dtf be this value.
+ 2. If Type(dtf) is not Object, throw a TypeError exception.
+ 3. If dtf does not have an [[InitializedDateTimeFormat]] internal slot, throw a TypeError exception.
+ 4. If startDate is undefined or endDate is undefined, throw a RangeError exception.
+ 5. Let x be ? ToNumber(startDate).
+ 6. Let y be ? ToNumber(endDate).
+ 7. If x is greater than y, throw a RangeError exception.
+ 8. Return ? FormatDateTimeRangeToParts(dtf, x, y).
+
+ FormatDateTimeRangeToParts ( dateTimeFormat, x, y )
+
+ 1. Let parts be ? PartitionDateTimeRangePattern(dateTimeFormat, x, y).
+
+ PartitionDateTimeRangePattern ( dateTimeFormat, x, y )
+
+ 1. Let x be TimeClip(x).
+ 2. If x is NaN, throw a RangeError exception.
+ 3. Let y be TimeClip(y).
+ 4. If y is NaN, throw a RangeError exception.
+
+features: [Intl.DateTimeFormat-formatRange]
+---*/
+
+var dtf = new Intl.DateTimeFormat();
+
+var date = new Date();
+
+assert.throws(RangeError, function() {
+ dtf.formatRangeToParts(NaN, date);
+}, "NaN/date");
+
+assert.throws(RangeError, function() {
+ dtf.formatRangeToParts(date, NaN);
+}, "date/NaN");
+
+assert.throws(RangeError, function() {
+ dtf.formatRangeToParts(NaN, NaN);
+}, "NaN/NaN");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/date-same-returns-single-date.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/date-same-returns-single-date.js
new file mode 100644
index 0000000000..d12c7bb9a8
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/date-same-returns-single-date.js
@@ -0,0 +1,79 @@
+// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet
+// Copyright 2021 Google Inc. All rights reserved.
+// Copyright 2021 Apple Inc. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-partitiondatetimerangepattern
+description: >
+ When startDate is equal to endDate, the output should be an Array of objects with the
+ same value for the `type` and `value` fields as in the Array returned by
+ Intl.DateTimeFormat.prototype.formatToParts.
+info: |
+ Intl.DateTimeFormat.prototype.formatRangeToParts ( startDate , endDate )
+
+ 4. Let x be ? ToNumber(startDate).
+ 5. Let y be ? ToNumber(endDate).
+ 6. Return ? FormatDateTimeRange(dtf, x, y).
+
+ PartitionDateTimeRangePattern ( dateTimeFormat, x, y )
+
+ 13. If dateFieldsPracticallyEqual is true, then
+ a. Let pattern be dateTimeFormat.[[Pattern]].
+ b. Let patternParts be PartitionPattern(pattern).
+ c. Let result be ? FormatDateTimePattern(dateTimeFormat, patternParts, tm1).
+ d. For each r in result do
+ i. Set r.[[Source]] to "shared".
+ e. Return result.
+
+features: [Intl.DateTimeFormat-formatRange]
+locale: [en-US]
+---*/
+
+function* zip(a, b) {
+ assert.sameValue(a.length, b.length);
+ for (let i = 0; i < a.length; ++i) {
+ yield [i, a[i], b[i]];
+ }
+}
+
+function compare(actual, expected) {
+ for (const [i, actualEntry, expectedEntry] of zip(actual, expected)) {
+ assert.sameValue(actualEntry.type, expectedEntry.type, `type for entry ${i}`);
+ assert.sameValue(actualEntry.value, expectedEntry.value, `value for entry ${i}`);
+ }
+}
+
+{
+ const date = new Date(2019, 7, 10, 1, 2, 3, 234);
+
+ let dtf = new Intl.DateTimeFormat("en", { year: "numeric", month: "short", day: "numeric" });
+ compare(dtf.formatRangeToParts(date, date), dtf.formatToParts(date), "same output with date options");
+
+ dtf = new Intl.DateTimeFormat("en", { minute: "numeric", second: "numeric" });
+ compare(dtf.formatRangeToParts(date, date), dtf.formatToParts(date), "same output with time options");
+
+ dtf = new Intl.DateTimeFormat("en", { month: "short", day: "numeric", minute: "numeric" });
+ compare(dtf.formatRangeToParts(date, date), dtf.formatToParts(date), "same output with date-time options");
+
+ dtf = new Intl.DateTimeFormat("en", { dateStyle: "long", timeStyle: "short" });
+ compare(dtf.formatRangeToParts(date, date), dtf.formatToParts(date), "same output with dateStyle/timeStyle");
+}
+{
+ const date1 = new Date(2019, 7, 10, 1, 2, 3, 234);
+ const date2 = new Date(2019, 7, 10, 1, 2, 3, 235);
+
+ let dtf = new Intl.DateTimeFormat("en", { year: "numeric", month: "short", day: "numeric" });
+ compare(dtf.formatRangeToParts(date1, date2), dtf.formatToParts(date1), "same output with date options");
+
+ dtf = new Intl.DateTimeFormat("en", { minute: "numeric", second: "numeric" });
+ compare(dtf.formatRangeToParts(date1, date2), dtf.formatToParts(date1), "same output with time options");
+
+ dtf = new Intl.DateTimeFormat("en", { month: "short", day: "numeric", minute: "numeric" });
+ compare(dtf.formatRangeToParts(date1, date2), dtf.formatToParts(date1), "same output with date-time options");
+
+ dtf = new Intl.DateTimeFormat("en", { dateStyle: "long", timeStyle: "short" });
+ compare(dtf.formatRangeToParts(date1, date2), dtf.formatToParts(date1), "same output with dateStyle/timeStyle");
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/date-undefined-throws.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/date-undefined-throws.js
new file mode 100644
index 0000000000..7ac2c44bd1
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/date-undefined-throws.js
@@ -0,0 +1,44 @@
+// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet
+// Copyright 2019 Google, Inc. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Throws a TypeError if startDate or endDate are undefined.
+info: |
+ Intl.DateTimeFormat.prototype.formatRangeToParts ( startDate , endDate )
+
+ 1. Let dtf be this value.
+ 2. If Type(dtf) is not Object, throw a TypeError exception.
+ 3. If dtf does not have an [[InitializedDateTimeFormat]] internal slot, throw a TypeError exception.
+ 4. If startDate is undefined or endDate is undefined, throw a TypeError exception.
+ 5. Let x be ? ToNumber(startDate).
+ 6. Let y be ? ToNumber(endDate).
+
+features: [Intl.DateTimeFormat-formatRange]
+---*/
+var dtf = new Intl.DateTimeFormat();
+
+assert.throws(TypeError, function() {
+ dtf.formatRangeToParts(); // Not possible to poison this one
+}, "no args");
+
+var poison = { valueOf() { throw new Test262Error(); } };
+
+assert.throws(TypeError, function() {
+ dtf.formatRangeToParts(undefined, poison);
+}, "date/undefined");
+
+assert.throws(TypeError, function() {
+ dtf.formatRangeToParts(poison, undefined);
+}, "undefined/date");
+
+assert.throws(TypeError, function() {
+ dtf.formatRangeToParts(poison);
+}, "only one arg");
+
+assert.throws(TypeError, function() {
+ dtf.formatRangeToParts(undefined, undefined);
+}, "undefined/undefined");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/date-x-greater-than-y-throws.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/date-x-greater-than-y-throws.js
new file mode 100644
index 0000000000..ab7032065f
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/date-x-greater-than-y-throws.js
@@ -0,0 +1,39 @@
+// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet
+// Copyright 2019 Google, Inc. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Throws a RangeError if date x is greater than y.
+info: |
+ Intl.DateTimeFormat.prototype.formatRangeToParts ( startDate , endDate )
+
+ 4. Let x be ? ToNumber(startDate).
+ 5. Let y be ? ToNumber(endDate).
+ 6. Return ? FormatDateTimeRangeToParts(dtf, x, y).
+
+ PartitionDateTimeRangePattern ( dateTimeFormat, x, y )
+
+ 1. Let x be TimeClip(x).
+ 2. If x is NaN, throw a RangeError exception.
+ 3. Let y be TimeClip(y).
+ 4. If y is NaN, throw a RangeError exception.
+ 5. If x is greater than y, throw a RangeError exception.
+
+features: [Intl.DateTimeFormat-formatRange]
+---*/
+
+var dtf = new Intl.DateTimeFormat();
+
+var x = new Date();
+var y = new Date();
+x.setDate(y.getDate() + 1);
+
+assert.throws(RangeError, function() {
+ dtf.formatRangeToParts(x, y);
+}, "x > y");
+assert.sameValue("object", typeof dtf.formatRangeToParts(x, x));
+assert.sameValue("object", typeof dtf.formatRangeToParts(y, y));
+assert.sameValue("object", typeof dtf.formatRangeToParts(y, x));
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/en-US.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/en-US.js
new file mode 100644
index 0000000000..563acdd47c
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/en-US.js
@@ -0,0 +1,202 @@
+// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet
+// Copyright (C) 2019 the V8 project authors, Igalia S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-partitiondatetimerangepattern
+description: Basic tests for the en-US output of formatRangeToParts()
+info: |
+ Intl.DateTimeFormat.prototype.formatRangeToParts ( startDate , endDate )
+
+ 8. Return ? FormatDateTimeRange(dtf, x, y).
+locale: [en-US]
+features: [Intl.DateTimeFormat-formatRange]
+---*/
+
+function* zip(a, b) {
+ assert.sameValue(a.length, b.length);
+ for (let i = 0; i < a.length; ++i) {
+ yield [i, a[i], b[i]];
+ }
+}
+
+function compare(actual, expected) {
+ for (const [i, actualEntry, expectedEntry] of zip(actual, expected)) {
+ assert.sameValue(actualEntry.type, expectedEntry.type, `type for entry ${i}`);
+ assert.sameValue(actualEntry.value, expectedEntry.value, `value for entry ${i}`);
+ assert.sameValue(actualEntry.source, expectedEntry.source, `source for entry ${i}`);
+ }
+}
+
+const date1 = new Date("2019-01-03T00:00:00");
+const date2 = new Date("2019-01-05T00:00:00");
+const date3 = new Date("2019-03-04T00:00:00");
+const date4 = new Date("2020-03-04T00:00:00");
+
+let dtf = new Intl.DateTimeFormat("en-US");
+compare(dtf.formatRangeToParts(date1, date1), [
+ { type: "month", value: "1", source: "shared" },
+ { type: "literal", value: "/", source: "shared" },
+ { type: "day", value: "3", source: "shared" },
+ { type: "literal", value: "/", source: "shared" },
+ { type: "year", value: "2019", source: "shared" },
+]);
+compare(dtf.formatRangeToParts(date1, date2), [
+ { type: "month", value: "1", source: "startRange" },
+ { type: "literal", value: "/", source: "startRange" },
+ { type: "day", value: "3", source: "startRange" },
+ { type: "literal", value: "/", source: "startRange" },
+ { type: "year", value: "2019", source: "startRange" },
+ { type: "literal", value: " \u2013 ", source: "shared" },
+ { type: "month", value: "1", source: "endRange" },
+ { type: "literal", value: "/", source: "endRange" },
+ { type: "day", value: "5", source: "endRange" },
+ { type: "literal", value: "/", source: "endRange" },
+ { type: "year", value: "2019", source: "endRange" },
+]);
+compare(dtf.formatRangeToParts(date1, date3), [
+ { type: "month", value: "1", source: "startRange" },
+ { type: "literal", value: "/", source: "startRange" },
+ { type: "day", value: "3", source: "startRange" },
+ { type: "literal", value: "/", source: "startRange" },
+ { type: "year", value: "2019", source: "startRange" },
+ { type: "literal", value: " \u2013 ", source: "shared" },
+ { type: "month", value: "3", source: "endRange" },
+ { type: "literal", value: "/", source: "endRange" },
+ { type: "day", value: "4", source: "endRange" },
+ { type: "literal", value: "/", source: "endRange" },
+ { type: "year", value: "2019", source: "endRange" },
+]);
+compare(dtf.formatRangeToParts(date1, date4), [
+ { type: "month", value: "1", source: "startRange" },
+ { type: "literal", value: "/", source: "startRange" },
+ { type: "day", value: "3", source: "startRange" },
+ { type: "literal", value: "/", source: "startRange" },
+ { type: "year", value: "2019", source: "startRange" },
+ { type: "literal", value: " \u2013 ", source: "shared" },
+ { type: "month", value: "3", source: "endRange" },
+ { type: "literal", value: "/", source: "endRange" },
+ { type: "day", value: "4", source: "endRange" },
+ { type: "literal", value: "/", source: "endRange" },
+ { type: "year", value: "2020", source: "endRange" },
+]);
+compare(dtf.formatRangeToParts(date2, date3), [
+ { type: "month", value: "1", source: "startRange" },
+ { type: "literal", value: "/", source: "startRange" },
+ { type: "day", value: "5", source: "startRange" },
+ { type: "literal", value: "/", source: "startRange" },
+ { type: "year", value: "2019", source: "startRange" },
+ { type: "literal", value: " \u2013 ", source: "shared" },
+ { type: "month", value: "3", source: "endRange" },
+ { type: "literal", value: "/", source: "endRange" },
+ { type: "day", value: "4", source: "endRange" },
+ { type: "literal", value: "/", source: "endRange" },
+ { type: "year", value: "2019", source: "endRange" },
+]);
+compare(dtf.formatRangeToParts(date2, date4), [
+ { type: "month", value: "1", source: "startRange" },
+ { type: "literal", value: "/", source: "startRange" },
+ { type: "day", value: "5", source: "startRange" },
+ { type: "literal", value: "/", source: "startRange" },
+ { type: "year", value: "2019", source: "startRange" },
+ { type: "literal", value: " \u2013 ", source: "shared" },
+ { type: "month", value: "3", source: "endRange" },
+ { type: "literal", value: "/", source: "endRange" },
+ { type: "day", value: "4", source: "endRange" },
+ { type: "literal", value: "/", source: "endRange" },
+ { type: "year", value: "2020", source: "endRange" },
+]);
+compare(dtf.formatRangeToParts(date3, date4), [
+ { type: "month", value: "3", source: "startRange" },
+ { type: "literal", value: "/", source: "startRange" },
+ { type: "day", value: "4", source: "startRange" },
+ { type: "literal", value: "/", source: "startRange" },
+ { type: "year", value: "2019", source: "startRange" },
+ { type: "literal", value: " \u2013 ", source: "shared" },
+ { type: "month", value: "3", source: "endRange" },
+ { type: "literal", value: "/", source: "endRange" },
+ { type: "day", value: "4", source: "endRange" },
+ { type: "literal", value: "/", source: "endRange" },
+ { type: "year", value: "2020", source: "endRange" },
+]);
+
+dtf = new Intl.DateTimeFormat("en-US", {year: "numeric", month: "short", day: "numeric"});
+compare(dtf.formatRangeToParts(date1, date1), [
+ { type: "month", value: "Jan", source: "shared" },
+ { type: "literal", value: " ", source: "shared" },
+ { type: "day", value: "3", source: "shared" },
+ { type: "literal", value: ", ", source: "shared" },
+ { type: "year", value: "2019", source: "shared" },
+]);
+compare(dtf.formatRangeToParts(date1, date2), [
+ { type: "month", value: "Jan", source: "shared" },
+ { type: "literal", value: " ", source: "shared" },
+ { type: "day", value: "3", source: "startRange" },
+ { type: "literal", value: " \u2013 ", source: "shared" },
+ { type: "day", value: "5", source: "endRange" },
+ { type: "literal", value: ", ", source: "shared" },
+ { type: "year", value: "2019", source: "shared" },
+]);
+compare(dtf.formatRangeToParts(date1, date3), [
+ { type: "month", value: "Jan", source: "startRange" },
+ { type: "literal", value: " ", source: "startRange" },
+ { type: "day", value: "3", source: "startRange" },
+ { type: "literal", value: " \u2013 ", source: "shared" },
+ { type: "month", value: "Mar", source: "endRange" },
+ { type: "literal", value: " ", source: "endRange" },
+ { type: "day", value: "4", source: "endRange" },
+ { type: "literal", value: ", ", source: "shared" },
+ { type: "year", value: "2019", source: "shared" },
+]);
+compare(dtf.formatRangeToParts(date1, date4), [
+ { type: "month", value: "Jan", source: "startRange" },
+ { type: "literal", value: " ", source: "startRange" },
+ { type: "day", value: "3", source: "startRange" },
+ { type: "literal", value: ", ", source: "startRange" },
+ { type: "year", value: "2019", source: "startRange" },
+ { type: "literal", value: " \u2013 ", source: "shared" },
+ { type: "month", value: "Mar", source: "endRange" },
+ { type: "literal", value: " ", source: "endRange" },
+ { type: "day", value: "4", source: "endRange" },
+ { type: "literal", value: ", ", source: "endRange" },
+ { type: "year", value: "2020", source: "endRange" },
+]);
+compare(dtf.formatRangeToParts(date2, date3), [
+ { type: "month", value: "Jan", source: "startRange" },
+ { type: "literal", value: " ", source: "startRange" },
+ { type: "day", value: "5", source: "startRange" },
+ { type: "literal", value: " \u2013 ", source: "shared" },
+ { type: "month", value: "Mar", source: "endRange" },
+ { type: "literal", value: " ", source: "endRange" },
+ { type: "day", value: "4", source: "endRange" },
+ { type: "literal", value: ", ", source: "shared" },
+ { type: "year", value: "2019", source: "shared" },
+]);
+compare(dtf.formatRangeToParts(date2, date4), [
+ { type: "month", value: "Jan", source: "startRange" },
+ { type: "literal", value: " ", source: "startRange" },
+ { type: "day", value: "5", source: "startRange" },
+ { type: "literal", value: ", ", source: "startRange" },
+ { type: "year", value: "2019", source: "startRange" },
+ { type: "literal", value: " \u2013 ", source: "shared" },
+ { type: "month", value: "Mar", source: "endRange" },
+ { type: "literal", value: " ", source: "endRange" },
+ { type: "day", value: "4", source: "endRange" },
+ { type: "literal", value: ", ", source: "endRange" },
+ { type: "year", value: "2020", source: "endRange" },
+]);
+compare(dtf.formatRangeToParts(date3, date4), [
+ { type: "month", value: "Mar", source: "startRange" },
+ { type: "literal", value: " ", source: "startRange" },
+ { type: "day", value: "4", source: "startRange" },
+ { type: "literal", value: ", ", source: "startRange" },
+ { type: "year", value: "2019", source: "startRange" },
+ { type: "literal", value: " \u2013 ", source: "shared" },
+ { type: "month", value: "Mar", source: "endRange" },
+ { type: "literal", value: " ", source: "endRange" },
+ { type: "day", value: "4", source: "endRange" },
+ { type: "literal", value: ", ", source: "endRange" },
+ { type: "year", value: "2020", source: "endRange" },
+]);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/fractionalSecondDigits.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/fractionalSecondDigits.js
new file mode 100644
index 0000000000..d6af440b80
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/fractionalSecondDigits.js
@@ -0,0 +1,154 @@
+// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet
+// Copyright 2020 Google Inc, Igalia S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-initializedatetimeformat
+description: Checks basic handling of fractionalSecondDigits.
+features: [Intl.DateTimeFormat-fractionalSecondDigits, Intl.DateTimeFormat-formatRange]
+locale: [en-US]
+---*/
+
+function* zip(a, b) {
+ assert.sameValue(a.length, b.length);
+ for (let i = 0; i < a.length; ++i) {
+ yield [i, a[i], b[i]];
+ }
+}
+
+function compare(actual, expected) {
+ for (const [i, actualEntry, expectedEntry] of zip(actual, expected)) {
+ assert.sameValue(actualEntry.type, expectedEntry.type, `type for entry ${i}`);
+ assert.sameValue(actualEntry.value, expectedEntry.value, `value for entry ${i}`);
+ assert.sameValue(actualEntry.source, expectedEntry.source, `source for entry ${i}`);
+ }
+}
+
+const d1 = new Date(2019, 7, 10, 1, 2, 3, 234);
+const d2 = new Date(2019, 7, 10, 1, 2, 3, 567);
+const d3 = new Date(2019, 7, 10, 1, 2, 13, 987);
+
+assert.throws(RangeError, () => {
+ new Intl.DateTimeFormat(
+ 'en', { minute: "numeric", second: "numeric", fractionalSecondDigits: 0});
+ }, "fractionalSecondDigits 0 should throw RangeError for out of range");
+
+assert.throws(RangeError, () => {
+ new Intl.DateTimeFormat(
+ 'en', { minute: "numeric", second: "numeric", fractionalSecondDigits: 4});
+ }, "fractionalSecondDigits 4 should throw RangeError for out of range");
+
+let dtf = new Intl.DateTimeFormat(
+ 'en', { minute: "numeric", second: "numeric", fractionalSecondDigits: undefined});
+
+compare(dtf.formatRangeToParts(d1, d2), [
+ { type: "minute", value: "02", source: "shared" },
+ { type: "literal", value: ":", source: "shared" },
+ { type: "second", value: "03", source: "shared" }
+]);
+
+compare(dtf.formatRangeToParts(d1, d3), [
+ { type: "minute", value: "02", source: "startRange" },
+ { type: "literal", value: ":", source: "startRange" },
+ { type: "second", value: "03", source: "startRange" },
+ { type: "literal", value: " \u2013 ", source: "shared" },
+ { type: "minute", value: "02", source: "endRange" },
+ { type: "literal", value: ":", source: "endRange" },
+ { type: "second", value: "13", source: "endRange" }
+]);
+
+dtf = new Intl.DateTimeFormat(
+ 'en', { minute: "numeric", second: "numeric", fractionalSecondDigits: 1});
+
+compare(dtf.formatRangeToParts(d1, d2), [
+ { type: "minute", value: "02", source: "startRange" },
+ { type: "literal", value: ":", source: "startRange" },
+ { type: "second", value: "03", source: "startRange" },
+ { type: "literal", value: ".", source: "startRange" },
+ { type: "fractionalSecond", value: "2", source: "startRange" },
+ { type: "literal", value: " \u2013 ", source: "shared" },
+ { type: "minute", value: "02", source: "endRange" },
+ { type: "literal", value: ":", source: "endRange" },
+ { type: "second", value: "03", source: "endRange" },
+ { type: "literal", value: ".", source: "endRange" },
+ { type: "fractionalSecond", value: "5", source: "endRange" }
+]);
+
+compare(dtf.formatRangeToParts(d1, d3), [
+ { type: "minute", value: "02", source: "startRange" },
+ { type: "literal", value: ":", source: "startRange" },
+ { type: "second", value: "03", source: "startRange" },
+ { type: "literal", value: ".", source: "startRange" },
+ { type: "fractionalSecond", value: "2", source: "startRange" },
+ { type: "literal", value: " \u2013 ", source: "shared" },
+ { type: "minute", value: "02", source: "endRange" },
+ { type: "literal", value: ":", source: "endRange" },
+ { type: "second", value: "13", source: "endRange" },
+ { type: "literal", value: ".", source: "endRange" },
+ { type: "fractionalSecond", value: "9", source: "endRange" }
+]);
+
+dtf = new Intl.DateTimeFormat(
+ 'en', { minute: "numeric", second: "numeric", fractionalSecondDigits: 2});
+
+compare(dtf.formatRangeToParts(d1, d2), [
+ { type: "minute", value: "02", source: "startRange" },
+ { type: "literal", value: ":", source: "startRange" },
+ { type: "second", value: "03", source: "startRange" },
+ { type: "literal", value: ".", source: "startRange" },
+ { type: "fractionalSecond", value: "23", source: "startRange" },
+ { type: "literal", value: " \u2013 ", source: "shared" },
+ { type: "minute", value: "02", source: "endRange" },
+ { type: "literal", value: ":", source: "endRange" },
+ { type: "second", value: "03", source: "endRange" },
+ { type: "literal", value: ".", source: "endRange" },
+ { type: "fractionalSecond", value: "56", source: "endRange" }
+]);
+
+compare(dtf.formatRangeToParts(d1, d3), [
+ { type: "minute", value: "02", source: "startRange" },
+ { type: "literal", value: ":", source: "startRange" },
+ { type: "second", value: "03", source: "startRange" },
+ { type: "literal", value: ".", source: "startRange" },
+ { type: "fractionalSecond", value: "23", source: "startRange" },
+ { type: "literal", value: " \u2013 ", source: "shared" },
+ { type: "minute", value: "02", source: "endRange" },
+ { type: "literal", value: ":", source: "endRange" },
+ { type: "second", value: "13", source: "endRange" },
+ { type: "literal", value: ".", source: "endRange" },
+ { type: "fractionalSecond", value: "98", source: "endRange" }
+]);
+
+dtf = new Intl.DateTimeFormat(
+ 'en', { minute: "numeric", second: "numeric", fractionalSecondDigits: 3});
+
+compare(dtf.formatRangeToParts(d1, d2), [
+ { type: "minute", value: "02", source: "startRange" },
+ { type: "literal", value: ":", source: "startRange" },
+ { type: "second", value: "03", source: "startRange" },
+ { type: "literal", value: ".", source: "startRange" },
+ { type: "fractionalSecond", value: "234", source: "startRange" },
+ { type: "literal", value: " \u2013 ", source: "shared" },
+ { type: "minute", value: "02", source: "endRange" },
+ { type: "literal", value: ":", source: "endRange" },
+ { type: "second", value: "03", source: "endRange" },
+ { type: "literal", value: ".", source: "endRange" },
+ { type: "fractionalSecond", value: "567", source: "endRange" }
+]);
+
+compare(dtf.formatRangeToParts(d1, d3), [
+ { type: "minute", value: "02", source: "startRange" },
+ { type: "literal", value: ":", source: "startRange" },
+ { type: "second", value: "03", source: "startRange" },
+ { type: "literal", value: ".", source: "startRange" },
+ { type: "fractionalSecond", value: "234", source: "startRange" },
+ { type: "literal", value: " \u2013 ", source: "shared" },
+ { type: "minute", value: "02", source: "endRange" },
+ { type: "literal", value: ":", source: "endRange" },
+ { type: "second", value: "13", source: "endRange" },
+ { type: "literal", value: ".", source: "endRange" },
+ { type: "fractionalSecond", value: "987", source: "endRange" }
+]);
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/length.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/length.js
new file mode 100644
index 0000000000..d737e906ea
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/length.js
@@ -0,0 +1,17 @@
+// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet
+// Copyright 2019 Google, Inc. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Intl.DateTimeFormat.prototype.formatRangeToParts.length.
+includes: [propertyHelper.js]
+features: [Intl.DateTimeFormat-formatRange]
+---*/
+verifyProperty(Intl.DateTimeFormat.prototype.formatRangeToParts, 'length', {
+ value: 2,
+ enumerable: false,
+ writable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/name.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/name.js
new file mode 100644
index 0000000000..a125c4bdda
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/name.js
@@ -0,0 +1,17 @@
+// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet
+// Copyright 2019 Google, Inc. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Intl.DateTimeFormat.prototype.formatRangeToParts.name value and descriptor.
+includes: [propertyHelper.js]
+features: [Intl.DateTimeFormat-formatRange]
+---*/
+verifyProperty(Intl.DateTimeFormat.prototype.formatRangeToParts, 'name', {
+ value: 'formatRangeToParts',
+ enumerable: false,
+ writable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/pattern-on-calendar.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/pattern-on-calendar.js
new file mode 100644
index 0000000000..7161f44804
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/pattern-on-calendar.js
@@ -0,0 +1,58 @@
+// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet
+// Copyright 2019 Google Inc. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-initializedatetimeformat
+description: >
+ Checks the DateTimeFormat choose different patterns based
+ on calendar.
+features: [Intl.DateTimeFormat-formatRange]
+locale: [en]
+---*/
+
+let calendars = [
+ "buddhist",
+ "chinese",
+ "coptic",
+ "dangi",
+ "ethiopic",
+ "ethioaa",
+ "gregory",
+ "hebrew",
+ "indian",
+ "islamic",
+ "islamic-civil",
+ "islamic-rgsa",
+ "islamic-tbla",
+ "islamic-umalqura",
+ "japanese",
+ "persian",
+ "roc"
+];
+let date1 = new Date(2017, 3, 12);
+let date2 = new Date();
+
+// serialize parts to a string by considering only the type and literal.
+function serializeTypesAndLiteral(parts) {
+ let types = parts.map(part => {
+ if (part.type == "literal") {
+ return `${part.type}(${part.value})`;
+ }
+ return part.type;
+ });
+ return types.join(":");
+}
+
+let df = new Intl.DateTimeFormat("en");
+let base = serializeTypesAndLiteral(df.formatRangeToParts(date1, date2));
+
+const foundDifferentPattern = calendars.some(function(calendar) {
+ let cdf = new Intl.DateTimeFormat("en-u-ca-" + calendar);
+ return base != serializeTypesAndLiteral(cdf.formatRangeToParts(date1, date2));
+});
+
+// Expect at least some calendar use different pattern.
+assert.sameValue(foundDifferentPattern, true);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/prop-desc.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/prop-desc.js
new file mode 100644
index 0000000000..c183abdc6c
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/prop-desc.js
@@ -0,0 +1,24 @@
+// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet
+// Copyright 2016 Mozilla Corporation. All rights reserved.
+// Copyright 2019 Igalia S.L. All rights reserved.
+// This code is governed by the license found in the LICENSE file.
+
+/*---
+description: Property type and descriptor.
+includes: [propertyHelper.js]
+features: [Intl.DateTimeFormat-formatRange]
+---*/
+
+assert.sameValue(
+ typeof Intl.DateTimeFormat.prototype.formatRangeToParts,
+ 'function',
+ '`typeof Intl.DateTimeFormat.prototype.formatRangeToParts` is `function`'
+);
+
+verifyProperty(Intl.DateTimeFormat.prototype, 'formatRangeToParts', {
+ enumerable: false,
+ writable: true,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/shell.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/shell.js
new file mode 100644
index 0000000000..a96394ce86
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/shell.js
@@ -0,0 +1,50 @@
+// GENERATED, DO NOT EDIT
+// file: dateConstants.js
+// Copyright (C) 2009 the Sputnik authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: |
+ Collection of date-centric values
+defines:
+ - date_1899_end
+ - date_1900_start
+ - date_1969_end
+ - date_1970_start
+ - date_1999_end
+ - date_2000_start
+ - date_2099_end
+ - date_2100_start
+ - start_of_time
+ - end_of_time
+---*/
+
+var date_1899_end = -2208988800001;
+var date_1900_start = -2208988800000;
+var date_1969_end = -1;
+var date_1970_start = 0;
+var date_1999_end = 946684799999;
+var date_2000_start = 946684800000;
+var date_2099_end = 4102444799999;
+var date_2100_start = 4102444800000;
+
+var start_of_time = -8.64e15;
+var end_of_time = 8.64e15;
+
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+---*/
+
+function isConstructor(f) {
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/this-bad-object.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/this-bad-object.js
new file mode 100644
index 0000000000..3cf6cbfb69
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/this-bad-object.js
@@ -0,0 +1,29 @@
+// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet
+// Copyright 2019 Igalia, S.L. All rights reserved.
+// This code is governed by the license found in the LICENSE file.
+
+/*---
+description: >
+ Throws a TypeError if this is not a DateTimeFormat object
+features: [Intl.DateTimeFormat-formatRange]
+---*/
+
+const formatRangeToParts = Intl.DateTimeFormat.prototype.formatRangeToParts;
+
+assert.throws(TypeError, function() {
+ formatRangeToParts.call({});
+}, "{}");
+
+assert.throws(TypeError, function() {
+ formatRangeToParts.call(new Date());
+}, "new Date()");
+
+assert.throws(TypeError, function() {
+ formatRangeToParts.call(Intl.DateTimeFormat);
+}, "Intl.DateTimeFormat");
+
+assert.throws(TypeError, function() {
+ formatRangeToParts.call(Intl.DateTimeFormat.prototype);
+}, "Intl.DateTimeFormat.prototype");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/this-is-not-object-throws.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/this-is-not-object-throws.js
new file mode 100644
index 0000000000..cf04cdc0af
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/this-is-not-object-throws.js
@@ -0,0 +1,50 @@
+// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet
+// Copyright 2019 Google, Inc. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Throws a TypeError if this is not Object.
+info: |
+ Intl.DateTimeFormat.prototype.formatRangeToParts ( startDate , endDate )
+
+ 1. Let dtf be this value.
+ 2. If Type(dtf) is not Object, throw a TypeError exception.
+
+features: [Intl.DateTimeFormat-formatRange, Symbol]
+---*/
+
+let formatRangeToParts = Intl.DateTimeFormat.prototype.formatRangeToParts;
+let d1 = new Date("1997-08-22T00:00");
+let d2 = new Date("1999-06-26T00:00");
+
+assert.throws(TypeError, function() {
+ formatRangeToParts.call(undefined, d1, d2);
+}, "undefined");
+
+assert.throws(TypeError, function() {
+ formatRangeToParts.call(null, d1, d2);
+}, "null");
+
+assert.throws(TypeError, function() {
+ formatRangeToParts.call(42, d1, d2);
+}, "number");
+
+assert.throws(TypeError, function() {
+ formatRangeToParts.call("foo", d1, d2);
+}, "string");
+
+assert.throws(TypeError, function() {
+ formatRangeToParts.call(false, d1, d2);
+}, "false");
+
+assert.throws(TypeError, function() {
+ formatRangeToParts.call(true, d1, d2);
+}, "true");
+
+var s = Symbol('3');
+assert.throws(TypeError, function() {
+ formatRangeToParts.call(s, d1, d2);
+}, "symbol");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/browser.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/browser.js
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/date-constructor-not-called.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/date-constructor-not-called.js
new file mode 100644
index 0000000000..9c63ee3e52
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/date-constructor-not-called.js
@@ -0,0 +1,38 @@
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-partitiondatetimepattern
+description: |
+ The Date constructor is not called to convert the input value.
+info: >
+ 12.4.4 Intl.DateTimeFormat.prototype.formatToParts ( date )
+
+ ...
+ 4. If date is undefined, then
+ ...
+ 5. Else,
+ a. Let x be ? ToNumber(date).
+ 5. Return ? FormatDateTimeToParts(dtf, x).
+
+ 12.1.6 PartitionDateTimePattern ( dateTimeFormat, x )
+
+ 1. Let x be TimeClip(x).
+ 2. If x is NaN, throw a RangeError exception.
+ 3. ...
+---*/
+
+var dtf = new Intl.DateTimeFormat();
+
+var dateTimeString = "2017-11-10T14:09:00.000Z";
+
+// |dateTimeString| is valid ISO-8601 style date/time string.
+assert.notSameValue(new Date(dateTimeString), NaN);
+
+// Ensure string input values are not converted to time values by calling the
+// Date constructor.
+assert.throws(RangeError, function() {
+ dtf.formatToParts(dateTimeString);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/date-is-infinity-throws.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/date-is-infinity-throws.js
new file mode 100644
index 0000000000..071c07ed45
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/date-is-infinity-throws.js
@@ -0,0 +1,35 @@
+// Copyright 2016 Leonardo Balter. All rights reserved.
+// This code is governed by the license found in the LICENSE file.
+
+/*---
+description: >
+ Throws a RangeError if date arg is cast to an Infinity value
+info: |
+ Intl.DateTimeFormat.prototype.formatToParts ([ date ])
+
+ 4. If _date_ is not provided or is *undefined*, then
+ a. Let _x_ be *%Date_now%*().
+ 5. Else,
+ a. Let _x_ be ? ToNumber(_date_).
+ 6. Return ? FormatDateTimeToParts(_dtf_, _x_).
+
+ FormatDateTimeToParts(dateTimeFormat, x)
+
+ 1. Let _parts_ be ? PartitionDateTimePattern(_dateTimeFormat_, _x_).
+
+ PartitionDateTimePattern (dateTimeFormat, x)
+
+ 1. If _x_ is not a finite Number, throw a *RangeError* exception.
+---*/
+
+var dtf = new Intl.DateTimeFormat(["pt-BR"]);
+
+assert.throws(RangeError, function() {
+ dtf.formatToParts(Infinity);
+}, "+Infinity");
+
+assert.throws(RangeError, function() {
+ dtf.formatToParts(-Infinity);
+}, "-Infinity");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/date-is-nan-throws.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/date-is-nan-throws.js
new file mode 100644
index 0000000000..ab062734e0
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/date-is-nan-throws.js
@@ -0,0 +1,35 @@
+// Copyright 2016 Leonardo Balter. All rights reserved.
+// This code is governed by the license found in the LICENSE file.
+
+/*---
+description: >
+ Throws a RangeError if date arg is cast to NaN
+info: |
+ Intl.DateTimeFormat.prototype.formatToParts ([ date ])
+
+ 4. If _date_ is not provided or is *undefined*, then
+ a. Let _x_ be *%Date_now%*().
+ 5. Else,
+ a. Let _x_ be ? ToNumber(_date_).
+ 6. Return ? FormatDateTimeToParts(_dtf_, _x_).
+
+ FormatDateTimeToParts(dateTimeFormat, x)
+
+ 1. Let _parts_ be ? PartitionDateTimePattern(_dateTimeFormat_, _x_).
+
+ PartitionDateTimePattern (dateTimeFormat, x)
+
+ 1. If _x_ is not a finite Number, throw a *RangeError* exception.
+---*/
+
+var dtf = new Intl.DateTimeFormat(["pt-BR"]);
+
+assert.throws(RangeError, function() {
+ dtf.formatToParts(NaN);
+});
+
+assert.throws(RangeError, function() {
+ dtf.formatToParts("lol");
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/dayPeriod-long-en.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/dayPeriod-long-en.js
new file mode 100644
index 0000000000..c3595070d0
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/dayPeriod-long-en.js
@@ -0,0 +1,109 @@
+// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-dayPeriod is not released yet
+// Copyright 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-initializedatetimeformat
+description: Checks basic handling of dayPeriod, long format.
+features: [Intl.DateTimeFormat-dayPeriod]
+---*/
+
+const d0000 = new Date(2017, 11, 12, 0, 0, 0, 0);
+const d0100 = new Date(2017, 11, 12, 1, 0, 0, 0);
+const d0200 = new Date(2017, 11, 12, 2, 0, 0, 0);
+const d0300 = new Date(2017, 11, 12, 3, 0, 0, 0);
+const d0400 = new Date(2017, 11, 12, 4, 0, 0, 0);
+const d0500 = new Date(2017, 11, 12, 5, 0, 0, 0);
+const d0600 = new Date(2017, 11, 12, 6, 0, 0, 0);
+const d0700 = new Date(2017, 11, 12, 7, 0, 0, 0);
+const d0800 = new Date(2017, 11, 12, 8, 0, 0, 0);
+const d0900 = new Date(2017, 11, 12, 9, 0, 0, 0);
+const d1000 = new Date(2017, 11, 12, 10, 0, 0, 0);
+const d1100 = new Date(2017, 11, 12, 11, 0, 0, 0);
+const d1200 = new Date(2017, 11, 12, 12, 0, 0, 0);
+const d1300 = new Date(2017, 11, 12, 13, 0, 0, 0);
+const d1400 = new Date(2017, 11, 12, 14, 0, 0, 0);
+const d1500 = new Date(2017, 11, 12, 15, 0, 0, 0);
+const d1600 = new Date(2017, 11, 12, 16, 0, 0, 0);
+const d1700 = new Date(2017, 11, 12, 17, 0, 0, 0);
+const d1800 = new Date(2017, 11, 12, 18, 0, 0, 0);
+const d1900 = new Date(2017, 11, 12, 19, 0, 0, 0);
+const d2000 = new Date(2017, 11, 12, 20, 0, 0, 0);
+const d2100 = new Date(2017, 11, 12, 21, 0, 0, 0);
+const d2200 = new Date(2017, 11, 12, 22, 0, 0, 0);
+const d2300 = new Date(2017, 11, 12, 23, 0, 0, 0);
+
+const long = new Intl.DateTimeFormat('en', { dayPeriod: 'long' });
+
+function assertParts(parts, expected, message) {
+ assert.sameValue(parts.length, 1, `length should be 1, ${message}`);
+ assert.sameValue(parts[0].value, expected, `expected part value. ${message}`);
+ assert.sameValue(parts[0].type, 'dayPeriod', `part type is dayPeriod. ${message}`);
+}
+
+assertParts(long.formatToParts(d0000), 'at night', '00:00, long format');
+assertParts(long.formatToParts(d0100), 'at night', '01:00, long format');
+assertParts(long.formatToParts(d0200), 'at night', '02:00, long format');
+assertParts(long.formatToParts(d0300), 'at night', '03:00, long format');
+assertParts(long.formatToParts(d0400), 'at night', '04:00, long format');
+assertParts(long.formatToParts(d0500), 'at night', '05:00, long format');
+assertParts(long.formatToParts(d0600), 'in the morning', '06:00, long format');
+assertParts(long.formatToParts(d0700), 'in the morning', '07:00, long format');
+assertParts(long.formatToParts(d0800), 'in the morning', '08:00, long format');
+assertParts(long.formatToParts(d0900), 'in the morning', '09:00, long format');
+assertParts(long.formatToParts(d1000), 'in the morning', '10:00, long format');
+assertParts(long.formatToParts(d1100), 'in the morning', '11:00, long format');
+assertParts(long.formatToParts(d1200), 'noon', '12:00, long format');
+assertParts(long.formatToParts(d1300), 'in the afternoon', '13:00, long format');
+assertParts(long.formatToParts(d1400), 'in the afternoon', '14:00, long format');
+assertParts(long.formatToParts(d1500), 'in the afternoon', '15:00, long format');
+assertParts(long.formatToParts(d1600), 'in the afternoon', '16:00, long format');
+assertParts(long.formatToParts(d1700), 'in the afternoon', '17:00, long format');
+assertParts(long.formatToParts(d1800), 'in the evening', '18:00, long format');
+assertParts(long.formatToParts(d1900), 'in the evening', '19:00, long format');
+assertParts(long.formatToParts(d2000), 'in the evening', '20:00, long format');
+assertParts(long.formatToParts(d2100), 'at night', '21:00, long format');
+assertParts(long.formatToParts(d2200), 'at night', '22:00, long format');
+assertParts(long.formatToParts(d2300), 'at night', '23:00, long format');
+
+const longNumeric = new Intl.DateTimeFormat('en', {
+ dayPeriod: 'long',
+ hour: 'numeric'
+});
+
+function assertPartsNumeric(parts, hour, expected, message) {
+ assert.sameValue(parts.length, 3, `length should be 3, ${message}`);
+ assert.sameValue(parts[0].value, hour, `hour part value. ${message}`);
+ assert.sameValue(parts[0].type, 'hour', `hour part type. ${message}`);
+ assert.sameValue(parts[1].value, ' ', `literal part value. ${message}`);
+ assert.sameValue(parts[1].type, 'literal', `literal part type. ${message}`);
+ assert.sameValue(parts[2].value, expected, `expected part value. ${message}`);
+ assert.sameValue(parts[2].type, 'dayPeriod', `expected part type. ${message}`);
+}
+
+assertPartsNumeric(longNumeric.formatToParts(d0000), '12', 'at night', '00:00, long-numeric');
+assertPartsNumeric(longNumeric.formatToParts(d0100), '1', 'at night', '01:00, long-numeric');
+assertPartsNumeric(longNumeric.formatToParts(d0200), '2', 'at night', '02:00, long-numeric');
+assertPartsNumeric(longNumeric.formatToParts(d0300), '3', 'at night', '03:00, long-numeric');
+assertPartsNumeric(longNumeric.formatToParts(d0400), '4', 'at night', '04:00, long-numeric');
+assertPartsNumeric(longNumeric.formatToParts(d0500), '5', 'at night', '05:00, long-numeric');
+assertPartsNumeric(longNumeric.formatToParts(d0600), '6', 'in the morning', '06:00, long-numeric');
+assertPartsNumeric(longNumeric.formatToParts(d0700), '7', 'in the morning', '07:00, long-numeric');
+assertPartsNumeric(longNumeric.formatToParts(d0800), '8', 'in the morning', '08:00, long-numeric');
+assertPartsNumeric(longNumeric.formatToParts(d0900), '9', 'in the morning', '09:00, long-numeric');
+assertPartsNumeric(longNumeric.formatToParts(d1000), '10', 'in the morning', '10:00, long-numeric');
+assertPartsNumeric(longNumeric.formatToParts(d1100), '11', 'in the morning', '11:00, long-numeric');
+assertPartsNumeric(longNumeric.formatToParts(d1200), '12', 'noon', '12:00, long-numeric');
+assertPartsNumeric(longNumeric.formatToParts(d1300), '1', 'in the afternoon', '13:00, long-numeric');
+assertPartsNumeric(longNumeric.formatToParts(d1400), '2', 'in the afternoon', '14:00, long-numeric');
+assertPartsNumeric(longNumeric.formatToParts(d1500), '3', 'in the afternoon', '15:00, long-numeric');
+assertPartsNumeric(longNumeric.formatToParts(d1600), '4', 'in the afternoon', '16:00, long-numeric');
+assertPartsNumeric(longNumeric.formatToParts(d1700), '5', 'in the afternoon', '17:00, long-numeric');
+assertPartsNumeric(longNumeric.formatToParts(d1800), '6', 'in the evening', '18:00, long-numeric');
+assertPartsNumeric(longNumeric.formatToParts(d1900), '7', 'in the evening', '19:00, long-numeric');
+assertPartsNumeric(longNumeric.formatToParts(d2000), '8', 'in the evening', '20:00, long-numeric');
+assertPartsNumeric(longNumeric.formatToParts(d2100), '9', 'at night', '21:00, long-numeric');
+assertPartsNumeric(longNumeric.formatToParts(d2200), '10', 'at night', '22:00, long-numeric');
+assertPartsNumeric(longNumeric.formatToParts(d2300), '11', 'at night', '23:00, long-numeric');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/dayPeriod-narrow-en.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/dayPeriod-narrow-en.js
new file mode 100644
index 0000000000..72a24eacbc
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/dayPeriod-narrow-en.js
@@ -0,0 +1,109 @@
+// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-dayPeriod is not released yet
+// Copyright 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-initializedatetimeformat
+description: Checks basic handling of dayPeriod, narrow format.
+features: [Intl.DateTimeFormat-dayPeriod]
+---*/
+
+const d0000 = new Date(2017, 11, 12, 0, 0, 0, 0);
+const d0100 = new Date(2017, 11, 12, 1, 0, 0, 0);
+const d0200 = new Date(2017, 11, 12, 2, 0, 0, 0);
+const d0300 = new Date(2017, 11, 12, 3, 0, 0, 0);
+const d0400 = new Date(2017, 11, 12, 4, 0, 0, 0);
+const d0500 = new Date(2017, 11, 12, 5, 0, 0, 0);
+const d0600 = new Date(2017, 11, 12, 6, 0, 0, 0);
+const d0700 = new Date(2017, 11, 12, 7, 0, 0, 0);
+const d0800 = new Date(2017, 11, 12, 8, 0, 0, 0);
+const d0900 = new Date(2017, 11, 12, 9, 0, 0, 0);
+const d1000 = new Date(2017, 11, 12, 10, 0, 0, 0);
+const d1100 = new Date(2017, 11, 12, 11, 0, 0, 0);
+const d1200 = new Date(2017, 11, 12, 12, 0, 0, 0);
+const d1300 = new Date(2017, 11, 12, 13, 0, 0, 0);
+const d1400 = new Date(2017, 11, 12, 14, 0, 0, 0);
+const d1500 = new Date(2017, 11, 12, 15, 0, 0, 0);
+const d1600 = new Date(2017, 11, 12, 16, 0, 0, 0);
+const d1700 = new Date(2017, 11, 12, 17, 0, 0, 0);
+const d1800 = new Date(2017, 11, 12, 18, 0, 0, 0);
+const d1900 = new Date(2017, 11, 12, 19, 0, 0, 0);
+const d2000 = new Date(2017, 11, 12, 20, 0, 0, 0);
+const d2100 = new Date(2017, 11, 12, 21, 0, 0, 0);
+const d2200 = new Date(2017, 11, 12, 22, 0, 0, 0);
+const d2300 = new Date(2017, 11, 12, 23, 0, 0, 0);
+
+const narrow = new Intl.DateTimeFormat('en', { dayPeriod: 'narrow' });
+
+function assertParts(parts, expected, message) {
+ assert.sameValue(parts.length, 1, `length should be 1, ${message}`);
+ assert.sameValue(parts[0].value, expected, `expected part value. ${message}`);
+ assert.sameValue(parts[0].type, 'dayPeriod', `part type is dayPeriod. ${message}`);
+}
+
+assertParts(narrow.formatToParts(d0000), 'at night', '00:00, narrow format');
+assertParts(narrow.formatToParts(d0100), 'at night', '01:00, narrow format');
+assertParts(narrow.formatToParts(d0200), 'at night', '02:00, narrow format');
+assertParts(narrow.formatToParts(d0300), 'at night', '03:00, narrow format');
+assertParts(narrow.formatToParts(d0400), 'at night', '04:00, narrow format');
+assertParts(narrow.formatToParts(d0500), 'at night', '05:00, narrow format');
+assertParts(narrow.formatToParts(d0600), 'in the morning', '06:00, narrow format');
+assertParts(narrow.formatToParts(d0700), 'in the morning', '07:00, narrow format');
+assertParts(narrow.formatToParts(d0800), 'in the morning', '08:00, narrow format');
+assertParts(narrow.formatToParts(d0900), 'in the morning', '09:00, narrow format');
+assertParts(narrow.formatToParts(d1000), 'in the morning', '10:00, narrow format');
+assertParts(narrow.formatToParts(d1100), 'in the morning', '11:00, narrow format');
+assertParts(narrow.formatToParts(d1200), 'n', '12:00, narrow format');
+assertParts(narrow.formatToParts(d1300), 'in the afternoon', '13:00, narrow format');
+assertParts(narrow.formatToParts(d1400), 'in the afternoon', '14:00, narrow format');
+assertParts(narrow.formatToParts(d1500), 'in the afternoon', '15:00, narrow format');
+assertParts(narrow.formatToParts(d1600), 'in the afternoon', '16:00, narrow format');
+assertParts(narrow.formatToParts(d1700), 'in the afternoon', '17:00, narrow format');
+assertParts(narrow.formatToParts(d1800), 'in the evening', '18:00, narrow format');
+assertParts(narrow.formatToParts(d1900), 'in the evening', '19:00, narrow format');
+assertParts(narrow.formatToParts(d2000), 'in the evening', '20:00, narrow format');
+assertParts(narrow.formatToParts(d2100), 'at night', '21:00, narrow format');
+assertParts(narrow.formatToParts(d2200), 'at night', '22:00, narrow format');
+assertParts(narrow.formatToParts(d2300), 'at night', '23:00, narrow format');
+
+const narrowNumeric = new Intl.DateTimeFormat('en', {
+ dayPeriod: 'narrow',
+ hour: 'numeric'
+});
+
+function assertPartsNumeric(parts, hour, expected, message) {
+ assert.sameValue(parts.length, 3, `length should be 3, ${message}`);
+ assert.sameValue(parts[0].value, hour, `hour part value. ${message}`);
+ assert.sameValue(parts[0].type, 'hour', `hour part type. ${message}`);
+ assert.sameValue(parts[1].value, ' ', `literal part value. ${message}`);
+ assert.sameValue(parts[1].type, 'literal', `literal part type. ${message}`);
+ assert.sameValue(parts[2].value, expected, `expected part value. ${message}`);
+ assert.sameValue(parts[2].type, 'dayPeriod', `expected part type. ${message}`);
+}
+
+assertPartsNumeric(narrowNumeric.formatToParts(d0000), '12', 'at night', '00:00, narrow-numeric');
+assertPartsNumeric(narrowNumeric.formatToParts(d0100), '1', 'at night', '01:00, narrow-numeric');
+assertPartsNumeric(narrowNumeric.formatToParts(d0200), '2', 'at night', '02:00, narrow-numeric');
+assertPartsNumeric(narrowNumeric.formatToParts(d0300), '3', 'at night', '03:00, narrow-numeric');
+assertPartsNumeric(narrowNumeric.formatToParts(d0400), '4', 'at night', '04:00, narrow-numeric');
+assertPartsNumeric(narrowNumeric.formatToParts(d0500), '5', 'at night', '05:00, narrow-numeric');
+assertPartsNumeric(narrowNumeric.formatToParts(d0600), '6', 'in the morning', '06:00, narrow-numeric');
+assertPartsNumeric(narrowNumeric.formatToParts(d0700), '7', 'in the morning', '07:00, narrow-numeric');
+assertPartsNumeric(narrowNumeric.formatToParts(d0800), '8', 'in the morning', '08:00, narrow-numeric');
+assertPartsNumeric(narrowNumeric.formatToParts(d0900), '9', 'in the morning', '09:00, narrow-numeric');
+assertPartsNumeric(narrowNumeric.formatToParts(d1000), '10', 'in the morning', '10:00, narrow-numeric');
+assertPartsNumeric(narrowNumeric.formatToParts(d1100), '11', 'in the morning', '11:00, narrow-numeric');
+assertPartsNumeric(narrowNumeric.formatToParts(d1200), '12', 'n', '12:00, narrow-numeric');
+assertPartsNumeric(narrowNumeric.formatToParts(d1300), '1', 'in the afternoon', '13:00, narrow-numeric');
+assertPartsNumeric(narrowNumeric.formatToParts(d1400), '2', 'in the afternoon', '14:00, narrow-numeric');
+assertPartsNumeric(narrowNumeric.formatToParts(d1500), '3', 'in the afternoon', '15:00, narrow-numeric');
+assertPartsNumeric(narrowNumeric.formatToParts(d1600), '4', 'in the afternoon', '16:00, narrow-numeric');
+assertPartsNumeric(narrowNumeric.formatToParts(d1700), '5', 'in the afternoon', '17:00, narrow-numeric');
+assertPartsNumeric(narrowNumeric.formatToParts(d1800), '6', 'in the evening', '18:00, narrow-numeric');
+assertPartsNumeric(narrowNumeric.formatToParts(d1900), '7', 'in the evening', '19:00, narrow-numeric');
+assertPartsNumeric(narrowNumeric.formatToParts(d2000), '8', 'in the evening', '20:00, narrow-numeric');
+assertPartsNumeric(narrowNumeric.formatToParts(d2100), '9', 'at night', '21:00, narrow-numeric');
+assertPartsNumeric(narrowNumeric.formatToParts(d2200), '10', 'at night', '22:00, narrow-numeric');
+assertPartsNumeric(narrowNumeric.formatToParts(d2300), '11', 'at night', '23:00, narrow-numeric');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/dayPeriod-short-en.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/dayPeriod-short-en.js
new file mode 100644
index 0000000000..8301bfca84
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/dayPeriod-short-en.js
@@ -0,0 +1,109 @@
+// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-dayPeriod is not released yet
+// Copyright 2019 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-initializedatetimeformat
+description: Checks basic handling of dayPeriod, short format.
+features: [Intl.DateTimeFormat-dayPeriod]
+---*/
+
+const d0000 = new Date(2017, 11, 12, 0, 0, 0, 0);
+const d0100 = new Date(2017, 11, 12, 1, 0, 0, 0);
+const d0200 = new Date(2017, 11, 12, 2, 0, 0, 0);
+const d0300 = new Date(2017, 11, 12, 3, 0, 0, 0);
+const d0400 = new Date(2017, 11, 12, 4, 0, 0, 0);
+const d0500 = new Date(2017, 11, 12, 5, 0, 0, 0);
+const d0600 = new Date(2017, 11, 12, 6, 0, 0, 0);
+const d0700 = new Date(2017, 11, 12, 7, 0, 0, 0);
+const d0800 = new Date(2017, 11, 12, 8, 0, 0, 0);
+const d0900 = new Date(2017, 11, 12, 9, 0, 0, 0);
+const d1000 = new Date(2017, 11, 12, 10, 0, 0, 0);
+const d1100 = new Date(2017, 11, 12, 11, 0, 0, 0);
+const d1200 = new Date(2017, 11, 12, 12, 0, 0, 0);
+const d1300 = new Date(2017, 11, 12, 13, 0, 0, 0);
+const d1400 = new Date(2017, 11, 12, 14, 0, 0, 0);
+const d1500 = new Date(2017, 11, 12, 15, 0, 0, 0);
+const d1600 = new Date(2017, 11, 12, 16, 0, 0, 0);
+const d1700 = new Date(2017, 11, 12, 17, 0, 0, 0);
+const d1800 = new Date(2017, 11, 12, 18, 0, 0, 0);
+const d1900 = new Date(2017, 11, 12, 19, 0, 0, 0);
+const d2000 = new Date(2017, 11, 12, 20, 0, 0, 0);
+const d2100 = new Date(2017, 11, 12, 21, 0, 0, 0);
+const d2200 = new Date(2017, 11, 12, 22, 0, 0, 0);
+const d2300 = new Date(2017, 11, 12, 23, 0, 0, 0);
+
+const short = new Intl.DateTimeFormat('en', { dayPeriod: 'short' });
+
+function assertParts(parts, expected, message) {
+ assert.sameValue(parts.length, 1, `length should be 1, ${message}`);
+ assert.sameValue(parts[0].value, expected, `expected part value. ${message}`);
+ assert.sameValue(parts[0].type, 'dayPeriod', `part type is dayPeriod. ${message}`);
+}
+
+assertParts(short.formatToParts(d0000), 'at night', '00:00, short format');
+assertParts(short.formatToParts(d0100), 'at night', '01:00, short format');
+assertParts(short.formatToParts(d0200), 'at night', '02:00, short format');
+assertParts(short.formatToParts(d0300), 'at night', '03:00, short format');
+assertParts(short.formatToParts(d0400), 'at night', '04:00, short format');
+assertParts(short.formatToParts(d0500), 'at night', '05:00, short format');
+assertParts(short.formatToParts(d0600), 'in the morning', '06:00, short format');
+assertParts(short.formatToParts(d0700), 'in the morning', '07:00, short format');
+assertParts(short.formatToParts(d0800), 'in the morning', '08:00, short format');
+assertParts(short.formatToParts(d0900), 'in the morning', '09:00, short format');
+assertParts(short.formatToParts(d1000), 'in the morning', '10:00, short format');
+assertParts(short.formatToParts(d1100), 'in the morning', '11:00, short format');
+assertParts(short.formatToParts(d1200), 'noon', '12:00, short format');
+assertParts(short.formatToParts(d1300), 'in the afternoon', '13:00, short format');
+assertParts(short.formatToParts(d1400), 'in the afternoon', '14:00, short format');
+assertParts(short.formatToParts(d1500), 'in the afternoon', '15:00, short format');
+assertParts(short.formatToParts(d1600), 'in the afternoon', '16:00, short format');
+assertParts(short.formatToParts(d1700), 'in the afternoon', '17:00, short format');
+assertParts(short.formatToParts(d1800), 'in the evening', '18:00, short format');
+assertParts(short.formatToParts(d1900), 'in the evening', '19:00, short format');
+assertParts(short.formatToParts(d2000), 'in the evening', '20:00, short format');
+assertParts(short.formatToParts(d2100), 'at night', '21:00, short format');
+assertParts(short.formatToParts(d2200), 'at night', '22:00, short format');
+assertParts(short.formatToParts(d2300), 'at night', '23:00, short format');
+
+const shortNumeric = new Intl.DateTimeFormat('en', {
+ dayPeriod: 'short',
+ hour: 'numeric'
+});
+
+function assertPartsNumeric(parts, hour, expected, message) {
+ assert.sameValue(parts.length, 3, `length should be 3, ${message}`);
+ assert.sameValue(parts[0].value, hour, `hour part value. ${message}`);
+ assert.sameValue(parts[0].type, 'hour', `hour part type. ${message}`);
+ assert.sameValue(parts[1].value, ' ', `literal part value. ${message}`);
+ assert.sameValue(parts[1].type, 'literal', `literal part type. ${message}`);
+ assert.sameValue(parts[2].value, expected, `expected part value. ${message}`);
+ assert.sameValue(parts[2].type, 'dayPeriod', `expected part type. ${message}`);
+}
+
+assertPartsNumeric(shortNumeric.formatToParts(d0000), '12', 'at night', '00:00, short-numeric');
+assertPartsNumeric(shortNumeric.formatToParts(d0100), '1', 'at night', '01:00, short-numeric');
+assertPartsNumeric(shortNumeric.formatToParts(d0200), '2', 'at night', '02:00, short-numeric');
+assertPartsNumeric(shortNumeric.formatToParts(d0300), '3', 'at night', '03:00, short-numeric');
+assertPartsNumeric(shortNumeric.formatToParts(d0400), '4', 'at night', '04:00, short-numeric');
+assertPartsNumeric(shortNumeric.formatToParts(d0500), '5', 'at night', '05:00, short-numeric');
+assertPartsNumeric(shortNumeric.formatToParts(d0600), '6', 'in the morning', '06:00, short-numeric');
+assertPartsNumeric(shortNumeric.formatToParts(d0700), '7', 'in the morning', '07:00, short-numeric');
+assertPartsNumeric(shortNumeric.formatToParts(d0800), '8', 'in the morning', '08:00, short-numeric');
+assertPartsNumeric(shortNumeric.formatToParts(d0900), '9', 'in the morning', '09:00, short-numeric');
+assertPartsNumeric(shortNumeric.formatToParts(d1000), '10', 'in the morning', '10:00, short-numeric');
+assertPartsNumeric(shortNumeric.formatToParts(d1100), '11', 'in the morning', '11:00, short-numeric');
+assertPartsNumeric(shortNumeric.formatToParts(d1200), '12', 'noon', '12:00, short-numeric');
+assertPartsNumeric(shortNumeric.formatToParts(d1300), '1', 'in the afternoon', '13:00, short-numeric');
+assertPartsNumeric(shortNumeric.formatToParts(d1400), '2', 'in the afternoon', '14:00, short-numeric');
+assertPartsNumeric(shortNumeric.formatToParts(d1500), '3', 'in the afternoon', '15:00, short-numeric');
+assertPartsNumeric(shortNumeric.formatToParts(d1600), '4', 'in the afternoon', '16:00, short-numeric');
+assertPartsNumeric(shortNumeric.formatToParts(d1700), '5', 'in the afternoon', '17:00, short-numeric');
+assertPartsNumeric(shortNumeric.formatToParts(d1800), '6', 'in the evening', '18:00, short-numeric');
+assertPartsNumeric(shortNumeric.formatToParts(d1900), '7', 'in the evening', '19:00, short-numeric');
+assertPartsNumeric(shortNumeric.formatToParts(d2000), '8', 'in the evening', '20:00, short-numeric');
+assertPartsNumeric(shortNumeric.formatToParts(d2100), '9', 'at night', '21:00, short-numeric');
+assertPartsNumeric(shortNumeric.formatToParts(d2200), '10', 'at night', '22:00, short-numeric');
+assertPartsNumeric(shortNumeric.formatToParts(d2300), '11', 'at night', '23:00, short-numeric');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/formatToParts.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/formatToParts.js
new file mode 100644
index 0000000000..d1898c5c1d
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/formatToParts.js
@@ -0,0 +1,19 @@
+// Copyright 2016 Mozilla Corporation. All rights reserved.
+// This code is governed by the license found in the LICENSE file.
+
+/*---
+description: Property type and descriptor.
+includes: [propertyHelper.js]
+---*/
+
+assert.sameValue(
+ typeof Intl.DateTimeFormat.prototype.formatToParts,
+ 'function',
+ '`typeof Intl.DateTimeFormat.prototype.formatToParts` is `function`'
+);
+
+verifyNotEnumerable(Intl.DateTimeFormat.prototype, 'formatToParts');
+verifyWritable(Intl.DateTimeFormat.prototype, 'formatToParts');
+verifyConfigurable(Intl.DateTimeFormat.prototype, 'formatToParts');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/fractionalSecondDigits.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/fractionalSecondDigits.js
new file mode 100644
index 0000000000..30d96b4d31
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/fractionalSecondDigits.js
@@ -0,0 +1,69 @@
+// Copyright 2019 Google Inc. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-initializedatetimeformat
+description: Checks basic handling of fractionalSecondDigits.
+features: [Intl.DateTimeFormat-fractionalSecondDigits]
+locale: [en-US]
+---*/
+
+const d1 = new Date(2019, 7, 10, 1, 2, 3, 234);
+const d2 = new Date(2019, 7, 10, 1, 2, 3, 567);
+
+function assertParts(parts, minute, second, fractionalSecond, message) {
+ if (fractionalSecond === null) {
+ assert.sameValue(parts.length, 3, `length should be 3, ${message}`);
+ } else {
+ assert.sameValue(parts.length, 5, `length should be 5, ${message}`);
+ }
+ assert.sameValue(parts[0].value, minute, `minute part value. ${message}`);
+ assert.sameValue(parts[0].type, 'minute', `minute part type. ${message}`);
+ assert.sameValue(parts[1].value, ':', `literal part value. ${message}`);
+ assert.sameValue(parts[1].type, 'literal', `literal part type. ${message}`);
+ assert.sameValue(parts[2].value, second, `second part value. ${message}`);
+ assert.sameValue(parts[2].type, 'second', `second part type. ${message}`);
+ if (fractionalSecond !== null) {
+ assert.sameValue(parts[3].value, '.', `literal part value. ${message}`);
+ assert.sameValue(parts[3].type, 'literal', `literal part type. ${message}`);
+ assert.sameValue(parts[4].value, fractionalSecond, `fractionalSecond part value. ${message}`);
+ assert.sameValue(parts[4].type, 'fractionalSecond', `fractionalSecond part type. ${message}`);
+ }
+}
+
+assert.throws(RangeError, () => {
+ new Intl.DateTimeFormat(
+ 'en', { minute: "numeric", second: "numeric", fractionalSecondDigits: 0});
+}, "fractionalSecondDigits 0 should throw RangeError for out of range");
+
+assert.throws(RangeError, () => {
+ new Intl.DateTimeFormat(
+ 'en', { minute: "numeric", second: "numeric", fractionalSecondDigits: 4});
+}, "fractionalSecondDigits 4 should throw RangeError for out of range");
+
+let dtf = new Intl.DateTimeFormat(
+ 'en', { minute: "numeric", second: "numeric"});
+assertParts(dtf.formatToParts(d1), "02", "03", null, "no fractionalSecondDigits round down");
+assertParts(dtf.formatToParts(d2), "02", "03", null, "no fractionalSecondDigits round down");
+
+dtf = new Intl.DateTimeFormat(
+ 'en', { minute: "numeric", second: "numeric", fractionalSecondDigits: undefined});
+assertParts(dtf.formatToParts(d1), "02", "03", null, "no fractionalSecondDigits round down");
+assertParts(dtf.formatToParts(d2), "02", "03", null, "no fractionalSecondDigits round down");
+
+dtf = new Intl.DateTimeFormat(
+ 'en', { minute: "numeric", second: "numeric", fractionalSecondDigits: 1});
+assertParts(dtf.formatToParts(d1), "02", "03", "2", "1 fractionalSecondDigits round down");
+assertParts(dtf.formatToParts(d2), "02", "03", "5", "1 fractionalSecondDigits round down");
+
+dtf = new Intl.DateTimeFormat(
+ 'en', { minute: "numeric", second: "numeric", fractionalSecondDigits: 2});
+assertParts(dtf.formatToParts(d1), "02", "03", "23", "2 fractionalSecondDigits round down");
+assertParts(dtf.formatToParts(d2), "02", "03", "56", "2 fractionalSecondDigits round down");
+
+dtf = new Intl.DateTimeFormat(
+ 'en', { minute: "numeric", second: "numeric", fractionalSecondDigits: 3});
+assertParts(dtf.formatToParts(d1), "02", "03", "234", "3 fractionalSecondDigits round down");
+assertParts(dtf.formatToParts(d2), "02", "03", "567", "3 fractionalSecondDigits round down");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/length.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/length.js
new file mode 100644
index 0000000000..cc596ada97
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/length.js
@@ -0,0 +1,15 @@
+// Copyright 2016 Mozilla Corporation. All rights reserved.
+// This code is governed by the license found in the LICENSE file.
+
+/*---
+description: Intl.DateTimeFormat.prototype.formatToParts.length.
+includes: [propertyHelper.js]
+---*/
+verifyProperty(Intl.DateTimeFormat.prototype.formatToParts, 'length', {
+ value: 1,
+ enumerable: false,
+ writable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/main.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/main.js
new file mode 100644
index 0000000000..79ad4f324e
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/main.js
@@ -0,0 +1,75 @@
+// Copyright 2016 Mozilla Corporation. All rights reserved.
+// This code is governed by the license found in the LICENSE file.
+
+/*---
+description: Tests for existance and behavior of Intl.DateTimeFormat.prototype.formatToParts
+---*/
+
+function reduce(parts) {
+ return parts.map(part => part.value).join('');
+}
+
+function compareFTPtoFormat(locales, options, value) {
+ const dtf = new Intl.DateTimeFormat(locales, options);
+ assert.sameValue(
+ dtf.format(value),
+ reduce(dtf.formatToParts(value)),
+ `Expected the same value for value ${value},
+ locales: ${locales} and options: ${options}`
+ );
+}
+
+compareFTPtoFormat();
+compareFTPtoFormat('pl');
+compareFTPtoFormat(['pl']);
+compareFTPtoFormat([]);
+compareFTPtoFormat(['de'], undefined, 0);
+compareFTPtoFormat(['de'], undefined, -10);
+compareFTPtoFormat(['de'], undefined, 25324234235);
+compareFTPtoFormat(['de'], {
+ day: '2-digit'
+}, Date.now());
+compareFTPtoFormat(['de'], {
+ day: 'numeric',
+ year: '2-digit'
+}, Date.now());
+compareFTPtoFormat(['ar'], {
+ month: 'numeric',
+ day: 'numeric',
+ year: '2-digit'
+}, Date.now());
+
+const actualPartTypes = new Intl.DateTimeFormat('en-us', {
+ weekday: 'long',
+ era: 'long',
+ year: 'numeric',
+ month: 'numeric',
+ day: 'numeric',
+ hour: 'numeric',
+ minute: 'numeric',
+ second: 'numeric',
+ hour12: true,
+ timeZone: 'UTC',
+ timeZoneName: 'long'
+}).formatToParts(Date.UTC(2012, 11, 17, 3, 0, 42))
+ .map(part => part.type);
+
+const legalPartTypes = [
+ 'weekday',
+ 'era',
+ 'year',
+ 'month',
+ 'day',
+ 'hour',
+ 'minute',
+ 'second',
+ 'literal',
+ 'dayPeriod',
+ 'timeZoneName',
+];
+
+actualPartTypes.forEach(function(type) {
+ assert(legalPartTypes.includes(type), `${type} is not a legal type`);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/name.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/name.js
new file mode 100644
index 0000000000..92b4805ee9
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/name.js
@@ -0,0 +1,15 @@
+// Copyright 2016 Mozilla Corporation. All rights reserved.
+// This code is governed by the license found in the LICENSE file.
+
+/*---
+description: Intl.DateTimeFormat.prototype.formatToParts.name value and descriptor.
+includes: [propertyHelper.js]
+---*/
+verifyProperty(Intl.DateTimeFormat.prototype.formatToParts, 'name', {
+ value: 'formatToParts',
+ enumerable: false,
+ writable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/pattern-on-calendar.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/pattern-on-calendar.js
new file mode 100644
index 0000000000..9a87da8dbc
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/pattern-on-calendar.js
@@ -0,0 +1,55 @@
+// Copyright 2019 Google Inc. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-initializedatetimeformat
+description: >
+ Checks the DateTimeFormat choose different patterns based
+ on calendar.
+locale: [en]
+---*/
+
+let calendars = [
+ "buddhist",
+ "chinese",
+ "coptic",
+ "dangi",
+ "ethiopic",
+ "ethioaa",
+ "gregory",
+ "hebrew",
+ "indian",
+ "islamic",
+ "islamic-civil",
+ "islamic-rgsa",
+ "islamic-tbla",
+ "islamic-umalqura",
+ "japanese",
+ "persian",
+ "roc"
+];
+let date = new Date();
+
+// serialize parts to a string by considering only the type and literal.
+function serializeTypesAndLiteral(parts) {
+ let types = parts.map(part => {
+ if (part.type == "literal") {
+ return `${part.type}(${part.value})`;
+ }
+ return part.type;
+ });
+ return types.join(":");
+}
+
+let df = new Intl.DateTimeFormat("en");
+let base = serializeTypesAndLiteral(df.formatToParts(date));
+
+const foundDifferentPattern = calendars.some(function(calendar) {
+ let cdf = new Intl.DateTimeFormat("en-u-ca-" + calendar);
+ return base != serializeTypesAndLiteral(cdf.formatToParts(date));
+});
+
+// Expect at least some calendar use different pattern.
+assert.sameValue(foundDifferentPattern, true);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/related-year-zh.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/related-year-zh.js
new file mode 100644
index 0000000000..1033404e00
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/related-year-zh.js
@@ -0,0 +1,35 @@
+// Copyright 2019 Google Inc, Igalia S.L. All rights reserved.
+// Copyright 2020 Apple Inc. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-partitiondatetimepattern
+description: >
+ Checks the output of 'relatedYear' and 'yearName' type, and
+ the choice of pattern based on calendar.
+locale: [zh-u-ca-chinese]
+---*/
+
+const df = new Intl.DateTimeFormat("zh-u-ca-chinese", {year: "numeric"});
+const date = new Date(2019, 5, 1);
+const actual = df.formatToParts(date);
+
+const expected = [
+ {type: "relatedYear", value: "2019"},
+ {type: "yearName", value: "己亥"},
+ {type: "literal", value: "年"},
+];
+
+assert.sameValue(Array.isArray(actual), true, 'actual is Array');
+
+if (actual.length <= 2) {
+ expected.shift(); // removes the relatedYear
+}
+
+actual.forEach(({ type, value }, i) => {
+ const { type: eType, value: eValue } = expected[i];
+ assert.sameValue(type, eType, `actual[${i}].type should be ${eType}`);
+ assert.sameValue(value, eValue, `actual[${i}].value should be ${eValue}`);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/related-year.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/related-year.js
new file mode 100644
index 0000000000..92aae9e730
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/related-year.js
@@ -0,0 +1,23 @@
+// Copyright 2019 Google Inc. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-partitiondatetimepattern
+description: >
+ Checks the output of 'relatedYear' and 'yearName' type, and
+ the choose of pattern base on calendar.
+locale: [en-u-ca-chinese]
+---*/
+
+let df = new Intl.DateTimeFormat("en-u-ca-chinese", {year: "numeric"});
+let parts = df.formatToParts(new Date());
+var relatedYearCount = 0;
+var yearNameCount = 0;
+parts.forEach(function(part) {
+ relatedYearCount += (part.type == "relatedYear") ? 1 : 0;
+ yearNameCount += (part.type == "yearName") ? 1 : 0;
+});
+assert.sameValue(relatedYearCount > 0, true);
+assert.sameValue(yearNameCount > 0, true);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/return-abrupt-tonumber-date.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/return-abrupt-tonumber-date.js
new file mode 100644
index 0000000000..b8141a3776
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/return-abrupt-tonumber-date.js
@@ -0,0 +1,44 @@
+// Copyright 2016 Leonardo Balter. All rights reserved.
+// This code is governed by the license found in the LICENSE file.
+
+/*---
+description: >
+ Return abrupt completions from ToNumber(date)
+info: |
+ Intl.DateTimeFormat.prototype.formatToParts ([ date ])
+
+ 4. If _date_ is not provided or is *undefined*, then
+ a. Let _x_ be *%Date_now%*().
+ 5. Else,
+ a. Let _x_ be ? ToNumber(_date_).
+features: [Symbol]
+---*/
+
+var obj1 = {
+ valueOf: function() {
+ throw new Test262Error();
+ }
+};
+
+var obj2 = {
+ toString: function() {
+ throw new Test262Error();
+ }
+};
+
+var dtf = new Intl.DateTimeFormat(["pt-BR"]);
+
+assert.throws(Test262Error, function() {
+ dtf.formatToParts(obj1);
+}, "valueOf");
+
+assert.throws(Test262Error, function() {
+ dtf.formatToParts(obj2);
+}, "toString");
+
+var s = Symbol('1');
+assert.throws(TypeError, function() {
+ dtf.formatToParts(s);
+}, "symbol");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/shell.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/shell.js
new file mode 100644
index 0000000000..62c6315a70
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/shell.js
@@ -0,0 +1,31 @@
+// GENERATED, DO NOT EDIT
+// file: dateConstants.js
+// Copyright (C) 2009 the Sputnik authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: |
+ Collection of date-centric values
+defines:
+ - date_1899_end
+ - date_1900_start
+ - date_1969_end
+ - date_1970_start
+ - date_1999_end
+ - date_2000_start
+ - date_2099_end
+ - date_2100_start
+ - start_of_time
+ - end_of_time
+---*/
+
+var date_1899_end = -2208988800001;
+var date_1900_start = -2208988800000;
+var date_1969_end = -1;
+var date_1970_start = 0;
+var date_1999_end = 946684799999;
+var date_2000_start = 946684800000;
+var date_2099_end = 4102444799999;
+var date_2100_start = 4102444800000;
+
+var start_of_time = -8.64e15;
+var end_of_time = 8.64e15;
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/this-has-not-internal-throws.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/this-has-not-internal-throws.js
new file mode 100644
index 0000000000..18dae83a16
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/this-has-not-internal-throws.js
@@ -0,0 +1,19 @@
+// Copyright 2016 Leonardo Balter. All rights reserved.
+// This code is governed by the license found in the LICENSE file.
+
+/*---
+description: >
+ Throws a TypeError if this is not a DateTimeFormat object
+---*/
+
+var formatToParts = Intl.DateTimeFormat.prototype.formatToParts;
+
+assert.throws(TypeError, function() {
+ formatToParts.call({});
+}, "{}");
+
+assert.throws(TypeError, function() {
+ formatToParts.call(new Date());
+}, "new Date()");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/this-is-not-object-throws.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/this-is-not-object-throws.js
new file mode 100644
index 0000000000..0837bfb1ca
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/this-is-not-object-throws.js
@@ -0,0 +1,40 @@
+// Copyright 2016 Leonardo Balter. All rights reserved.
+// This code is governed by the license found in the LICENSE file.
+
+/*---
+description: Throws a TypeError if this is not Object
+features: [Symbol]
+---*/
+
+var formatToParts = Intl.DateTimeFormat.prototype.formatToParts;
+
+assert.throws(TypeError, function() {
+ formatToParts.call(undefined);
+}, "undefined");
+
+assert.throws(TypeError, function() {
+ formatToParts.call(null);
+}, "null");
+
+assert.throws(TypeError, function() {
+ formatToParts.call(42);
+}, "number");
+
+assert.throws(TypeError, function() {
+ formatToParts.call("foo");
+}, "string");
+
+assert.throws(TypeError, function() {
+ formatToParts.call(false);
+}, "false");
+
+assert.throws(TypeError, function() {
+ formatToParts.call(true);
+}, "true");
+
+var s = Symbol('1');
+assert.throws(TypeError, function() {
+ formatToParts.call(s);
+}, "symbol");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/time-clip-near-time-boundaries.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/time-clip-near-time-boundaries.js
new file mode 100644
index 0000000000..61599ebbc1
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/time-clip-near-time-boundaries.js
@@ -0,0 +1,39 @@
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-partitiondatetimepattern
+description: |
+ TimeClip is applied when calling Intl.DateTimeFormat.prototype.formatToParts.
+info: >
+ 12.1.6 PartitionDateTimePattern ( dateTimeFormat, x )
+
+ 1. Let x be TimeClip(x).
+ 2. If x is NaN, throw a RangeError exception.
+ 3. ...
+
+ 20.3.1.15 TimeClip ( time )
+ ...
+ 2. If abs(time) > 8.64 × 10^15, return NaN.
+ ...
+
+includes: [dateConstants.js]
+---*/
+
+var dtf = new Intl.DateTimeFormat();
+
+// Test values near the start of the ECMAScript time range.
+assert.throws(RangeError, function() {
+ dtf.formatToParts(start_of_time - 1);
+});
+assert.sameValue(typeof dtf.formatToParts(start_of_time), "object");
+assert.sameValue(typeof dtf.formatToParts(start_of_time + 1), "object");
+
+// Test values near the end of the ECMAScript time range.
+assert.sameValue(typeof dtf.formatToParts(end_of_time - 1), "object");
+assert.sameValue(typeof dtf.formatToParts(end_of_time), "object");
+assert.throws(RangeError, function() {
+ dtf.formatToParts(end_of_time + 1);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/time-clip-to-integer.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/time-clip-to-integer.js
new file mode 100644
index 0000000000..576b08ca92
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/time-clip-to-integer.js
@@ -0,0 +1,43 @@
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-partitiondatetimepattern
+description: |
+ TimeClip applies ToInteger on its input value.
+info: >
+ 12.1.6 PartitionDateTimePattern ( dateTimeFormat, x )
+
+ 1. Let x be TimeClip(x).
+ 2. ...
+
+ 20.3.1.15 TimeClip ( time )
+ ...
+ 3. Let clippedTime be ! ToInteger(time).
+ 4. If clippedTime is -0, set clippedTime to +0.
+ 5. Return clippedTime.
+---*/
+
+// Switch to a time format instead of using DateTimeFormat's default date-only format.
+var dtf = new Intl.DateTimeFormat(undefined, {
+ hour: "numeric", minute: "numeric", second: "numeric"
+});
+
+function formatAsString(dtf, time) {
+ return dtf.formatToParts(time).map(part => part.value).join("");
+}
+
+var expected = formatAsString(dtf, 0);
+
+assert.sameValue(formatAsString(dtf, -0.9), expected, "formatToParts(-0.9)");
+assert.sameValue(formatAsString(dtf, -0.5), expected, "formatToParts(-0.5)");
+assert.sameValue(formatAsString(dtf, -0.1), expected, "formatToParts(-0.1)");
+assert.sameValue(formatAsString(dtf, -Number.MIN_VALUE), expected, "formatToParts(-Number.MIN_VALUE)");
+assert.sameValue(formatAsString(dtf, -0), expected, "formatToParts(-0)");
+assert.sameValue(formatAsString(dtf, +0), expected, "formatToParts(+0)");
+assert.sameValue(formatAsString(dtf, Number.MIN_VALUE), expected, "formatToParts(Number.MIN_VALUE)");
+assert.sameValue(formatAsString(dtf, 0.1), expected, "formatToParts(0.1)");
+assert.sameValue(formatAsString(dtf, 0.5), expected, "formatToParts(0.5)");
+assert.sameValue(formatAsString(dtf, 0.9), expected, "formatToParts(0.9)");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/prop-desc.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/prop-desc.js
new file mode 100644
index 0000000000..711e47059a
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/prop-desc.js
@@ -0,0 +1,19 @@
+// Copyright 2012 Mozilla Corporation. All rights reserved.
+// This code is governed by the license found in the LICENSE file.
+
+/*---
+es5id: 12.2.1
+description: >
+ Tests that Intl.DateTimeFormat.prototype has the required
+ attributes.
+author: Norbert Lindenberg
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(Intl.DateTimeFormat, "prototype", {
+ writable: false,
+ enumerable: false,
+ configurable: false,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/basic.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/basic.js
new file mode 100644
index 0000000000..294b8f4d80
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/basic.js
@@ -0,0 +1,75 @@
+// Copyright 2012 Mozilla Corporation. All rights reserved.
+// This code is governed by the license found in the LICENSE file.
+
+/*---
+es5id: 12.3.3
+description: >
+ Tests that the object returned by
+ Intl.DateTimeFormat.prototype.resolvedOptions has the right
+ properties.
+author: Norbert Lindenberg
+includes: [testIntl.js, propertyHelper.js]
+---*/
+
+var actual = new Intl.DateTimeFormat().resolvedOptions();
+
+var actual2 = new Intl.DateTimeFormat().resolvedOptions();
+assert.notSameValue(actual2, actual, "resolvedOptions returned the same object twice.");
+
+// source: CLDR file common/bcp47/calendar.xml; version CLDR 32.
+var calendars = [
+ "buddhist",
+ "chinese",
+ "coptic",
+ "dangi",
+ "ethioaa",
+ "ethiopic-amete-alem",
+ "ethiopic",
+ "gregory",
+ "hebrew",
+ "indian",
+ "islamic",
+ "islamic-umalqura",
+ "islamic-tbla",
+ "islamic-civil",
+ "islamic-rgsa",
+ "iso8601",
+ "japanese",
+ "persian",
+ "roc",
+ "islamicc",
+];
+
+// this assumes the default values where the specification provides them
+assert(isCanonicalizedStructurallyValidLanguageTag(actual.locale),
+ "Invalid locale: " + actual.locale);
+assert.notSameValue(calendars.indexOf(actual.calendar), -1,
+ "Invalid calendar: " + actual.calendar);
+assert(isValidNumberingSystem(actual.numberingSystem),
+ "Invalid numbering system: " + actual.numberingSystem);
+assert(isCanonicalizedStructurallyValidTimeZoneName(actual.timeZone),
+ "Invalid time zone: " + actual.timeZone);
+assert.notSameValue(["2-digit", "numeric"].indexOf(actual.year), -1,
+ "Invalid year: " + actual.year);
+assert.notSameValue(["2-digit", "numeric", "narrow", "short", "long"].indexOf(actual.month), -1,
+ "Invalid month: " + actual.month);
+assert.notSameValue(["2-digit", "numeric"].indexOf(actual.day), -1,
+ "Invalid day: " + actual.day);
+
+var dataPropertyDesc = { writable: true, enumerable: true, configurable: true };
+verifyProperty(actual, "locale", dataPropertyDesc);
+verifyProperty(actual, "calendar", dataPropertyDesc);
+verifyProperty(actual, "numberingSystem", dataPropertyDesc);
+verifyProperty(actual, "timeZone", dataPropertyDesc);
+verifyProperty(actual, "weekday", undefined);
+verifyProperty(actual, "era", undefined);
+verifyProperty(actual, "year", dataPropertyDesc);
+verifyProperty(actual, "month", dataPropertyDesc);
+verifyProperty(actual, "day", dataPropertyDesc);
+verifyProperty(actual, "hour", undefined);
+verifyProperty(actual, "minute", undefined);
+verifyProperty(actual, "second", undefined);
+verifyProperty(actual, "timeZoneName", undefined);
+verifyProperty(actual, "hour12", undefined);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/browser.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/browser.js
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/builtin.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/builtin.js
new file mode 100644
index 0000000000..643376e7e2
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/builtin.js
@@ -0,0 +1,30 @@
+// Copyright 2012 Mozilla Corporation. All rights reserved.
+// This code is governed by the license found in the LICENSE file.
+
+/*---
+es5id: 12.3.3_L15
+description: >
+ Tests that Intl.DateTimeFormat.prototype.resolvedOptions meets
+ the requirements for built-in objects defined by the introduction
+ of chapter 17 of the ECMAScript Language Specification.
+author: Norbert Lindenberg
+includes: [isConstructor.js]
+features: [Reflect.construct]
+---*/
+
+assert.sameValue(Object.prototype.toString.call(Intl.DateTimeFormat.prototype.resolvedOptions), "[object Function]",
+ "The [[Class]] internal property of a built-in function must be " +
+ "\"Function\".");
+
+assert(Object.isExtensible(Intl.DateTimeFormat.prototype.resolvedOptions),
+ "Built-in objects must be extensible.");
+
+assert.sameValue(Object.getPrototypeOf(Intl.DateTimeFormat.prototype.resolvedOptions), Function.prototype);
+
+assert.sameValue(Intl.DateTimeFormat.prototype.resolvedOptions.hasOwnProperty("prototype"), false,
+ "Built-in functions that aren't constructors must not have a prototype property.");
+
+assert.sameValue(isConstructor(Intl.DateTimeFormat.prototype.resolvedOptions), false,
+ "Built-in functions don't implement [[Construct]] unless explicitly specified.");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/hourCycle-dateStyle.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/hourCycle-dateStyle.js
new file mode 100644
index 0000000000..e6e06a1ad0
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/hourCycle-dateStyle.js
@@ -0,0 +1,69 @@
+// Copyright 2019 Mozilla Corporation, Igalia S.L. All rights reserved.
+// This code is governed by the license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.DateTimeFormat.prototype.resolvedOptions
+description: >
+ Intl.DateTimeFormat.prototype.resolvedOptions properly
+ reflect hourCycle settings when using dateStyle.
+features: [Intl.DateTimeFormat-datetimestyle]
+---*/
+
+const hcValues = ["h11", "h12", "h23", "h24"];
+const hour12Values = ["h11", "h12"];
+
+for (const dateStyle of ["full", "long", "medium", "short"]) {
+ assert.sameValue(new Intl.DateTimeFormat([], { dateStyle }).resolvedOptions().dateStyle,
+ dateStyle,
+ `Should support dateStyle=${dateStyle}`);
+
+ /* Values passed via unicode extension key work */
+
+ for (const hcValue of hcValues) {
+ const resolvedOptions = new Intl.DateTimeFormat(`de-u-hc-${hcValue}`, {
+ dateStyle,
+ }).resolvedOptions();
+
+ assert.sameValue(resolvedOptions.hourCycle, undefined);
+ assert.sameValue(resolvedOptions.hour12, undefined);
+ }
+
+ /* Values passed via options work */
+
+ for (const hcValue of hcValues) {
+ const resolvedOptions = new Intl.DateTimeFormat("en-US", {
+ dateStyle,
+ hourCycle: hcValue
+ }).resolvedOptions();
+
+ assert.sameValue(resolvedOptions.hourCycle, undefined);
+ assert.sameValue(resolvedOptions.hour12, undefined);
+ }
+
+ let resolvedOptions = new Intl.DateTimeFormat("en-US-u-hc-h12", {
+ dateStyle,
+ hourCycle: "h23"
+ }).resolvedOptions();
+
+ assert.sameValue(resolvedOptions.hourCycle, undefined);
+ assert.sameValue(resolvedOptions.hour12, undefined);
+
+ resolvedOptions = new Intl.DateTimeFormat("fr", {
+ dateStyle,
+ hour12: true,
+ hourCycle: "h23"
+ }).resolvedOptions();
+
+ assert.sameValue(resolvedOptions.hourCycle, undefined);
+ assert.sameValue(resolvedOptions.hour12, undefined);
+
+ resolvedOptions = new Intl.DateTimeFormat("fr-u-hc-h24", {
+ dateStyle,
+ hour12: true,
+ }).resolvedOptions();
+
+ assert.sameValue(resolvedOptions.hourCycle, undefined);
+ assert.sameValue(resolvedOptions.hour12, undefined);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/hourCycle-default.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/hourCycle-default.js
new file mode 100644
index 0000000000..906518c44b
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/hourCycle-default.js
@@ -0,0 +1,58 @@
+// Copyright 2019 Google Inc. All rights reserved.
+// This code is governed by the license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.DateTimeFormat.prototype.resolvedOptions
+description: >
+ Intl.DateTimeFormat.prototype.resolvedOptions properly
+ reflect hourCycle settings.
+info: |
+ 12.4.5 Intl.DateTimeFormat.prototype.resolvedOptions()
+
+ 12.1.1 InitializeDateTimeFormat ( dateTimeFormat, locales, options )
+ 29. If dateTimeFormat.[[Hour]] is not undefined, then
+ a. Let hcDefault be dataLocaleData.[[hourCycle]].
+ b. Let hc be dateTimeFormat.[[HourCycle]].
+ c. If hc is null, then
+ i. Set hc to hcDefault.
+ d. If hour12 is not undefined, then
+ i. If hour12 is true, then
+ 1. If hcDefault is "h11" or "h23", then
+ a. Set hc to "h11".
+ 2. Else,
+ a. Set hc to "h12".
+ ii. Else,
+ 1. Assert: hour12 is false.
+ 2. If hcDefault is "h11" or "h23", then
+ a. Set hc to "h23".
+ 3. Else,
+ a. Set hc to "h24".
+ e. Set dateTimeFormat.[[HourCycle]] to hc.
+
+locale: [en, fr, it, ja, zh, ko, ar, hi]
+---*/
+
+let locales = ["en", "fr", "it", "ja", "zh", "ko", "ar", "hi"];
+
+locales.forEach(function(locale) {
+ let hcDefault = (new Intl.DateTimeFormat(locale, {hour: "numeric"}))
+ .resolvedOptions().hourCycle;
+ if (hcDefault == "h11" || hcDefault == "h23") {
+ assert.sameValue("h11",
+ (new Intl.DateTimeFormat(locale, {hour: "numeric", hour12: true}))
+ .resolvedOptions().hourCycle);
+ assert.sameValue("h23",
+ (new Intl.DateTimeFormat(locale, {hour: "numeric", hour12: false}))
+ .resolvedOptions().hourCycle);
+ } else {
+ assert.sameValue(true, hcDefault == "h12" || hcDefault == "h24")
+ assert.sameValue("h12",
+ (new Intl.DateTimeFormat(locale, {hour: "numeric", hour12: true}))
+ .resolvedOptions().hourCycle);
+ assert.sameValue("h24",
+ (new Intl.DateTimeFormat(locale, {hour: "numeric", hour12: false}))
+ .resolvedOptions().hourCycle);
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/hourCycle-timeStyle.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/hourCycle-timeStyle.js
new file mode 100644
index 0000000000..7fc96e2adb
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/hourCycle-timeStyle.js
@@ -0,0 +1,89 @@
+// Copyright 2019 Mozilla Corporation, Igalia S.L. All rights reserved.
+// This code is governed by the license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.DateTimeFormat.prototype.resolvedOptions
+description: >
+ Intl.DateTimeFormat.prototype.resolvedOptions properly
+ reflect hourCycle settings when using timeStyle.
+includes: [propertyHelper.js]
+features: [Intl.DateTimeFormat-datetimestyle]
+---*/
+
+const hcValues = ["h11", "h12", "h23", "h24"];
+const hour12Values = ["h11", "h12"];
+const dataPropertyDesc = { writable: true, enumerable: true, configurable: true };
+
+for (const timeStyle of ["full", "long", "medium", "short"]) {
+ assert.sameValue(new Intl.DateTimeFormat([], { timeStyle }).resolvedOptions().timeStyle,
+ timeStyle,
+ `Should support timeStyle=${timeStyle}`);
+
+ /* Values passed via unicode extension key work */
+
+ for (const hcValue of hcValues) {
+ const resolvedOptions = new Intl.DateTimeFormat(`de-u-hc-${hcValue}`, {
+ timeStyle,
+ }).resolvedOptions();
+
+ assert.sameValue(resolvedOptions.hourCycle, hcValue);
+ assert.sameValue(resolvedOptions.hour12, hour12Values.includes(hcValue));
+ }
+
+ /* Values passed via options work */
+
+ for (const hcValue of hcValues) {
+ const resolvedOptions = new Intl.DateTimeFormat("en-US", {
+ timeStyle,
+ hourCycle: hcValue
+ }).resolvedOptions();
+
+ assert.sameValue(resolvedOptions.hourCycle, hcValue);
+ assert.sameValue(resolvedOptions.hour12, hour12Values.includes(hcValue));
+
+ verifyProperty(resolvedOptions, "hourCycle", dataPropertyDesc);
+ verifyProperty(resolvedOptions, "hour12", dataPropertyDesc);
+ }
+
+ /* When both extension key and option is passed, option takes precedence */
+
+ let resolvedOptions = new Intl.DateTimeFormat("en-US-u-hc-h12", {
+ timeStyle,
+ hourCycle: "h23"
+ }).resolvedOptions();
+
+ assert.sameValue(resolvedOptions.hourCycle, "h23");
+ assert.sameValue(resolvedOptions.hour12, false);
+
+ verifyProperty(resolvedOptions, "hourCycle", dataPropertyDesc);
+ verifyProperty(resolvedOptions, "hour12", dataPropertyDesc);
+
+ /* When hour12 and hourCycle are set, hour12 takes precedence */
+
+ resolvedOptions = new Intl.DateTimeFormat("fr", {
+ timeStyle,
+ hour12: true,
+ hourCycle: "h23"
+ }).resolvedOptions();
+
+ assert(hour12Values.includes(resolvedOptions.hourCycle));
+ assert.sameValue(resolvedOptions.hour12, true);
+
+ verifyProperty(resolvedOptions, "hourCycle", dataPropertyDesc);
+ verifyProperty(resolvedOptions, "hour12", dataPropertyDesc);
+
+ /* When hour12 and extension key are set, hour12 takes precedence */
+
+ resolvedOptions = new Intl.DateTimeFormat("fr-u-hc-h24", {
+ timeStyle,
+ hour12: true,
+ }).resolvedOptions();
+
+ assert(hour12Values.includes(resolvedOptions.hourCycle));
+ assert.sameValue(resolvedOptions.hour12, true);
+
+ verifyProperty(resolvedOptions, "hourCycle", dataPropertyDesc);
+ verifyProperty(resolvedOptions, "hour12", dataPropertyDesc);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/hourCycle.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/hourCycle.js
new file mode 100644
index 0000000000..07c3913191
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/hourCycle.js
@@ -0,0 +1,101 @@
+// Copyright 2017 Mozilla Corporation. All rights reserved.
+// This code is governed by the license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.DateTimeFormat.prototype.resolvedOptions
+description: >
+ Intl.DateTimeFormat.prototype.resolvedOptions properly
+ reflect hourCycle settings.
+info: |
+ 12.4.5 Intl.DateTimeFormat.prototype.resolvedOptions()
+
+includes: [propertyHelper.js]
+---*/
+
+/* Values passed via unicode extension key work */
+
+const hcValues = ['h11', 'h12', 'h23', 'h24'];
+const hour12Values = ['h11', 'h12'];
+
+const dataPropertyDesc = { writable: true, enumerable: true, configurable: true };
+
+for (const hcValue of hcValues) {
+ const resolvedOptions = new Intl.DateTimeFormat(`de-u-hc-${hcValue}`, {
+ hour: 'numeric'
+ }).resolvedOptions();
+
+ assert.sameValue(resolvedOptions.hourCycle, hcValue);
+ assert.sameValue(resolvedOptions.hour12, hour12Values.includes(hcValue));
+
+ verifyProperty(resolvedOptions, 'hourCycle', dataPropertyDesc);
+ verifyProperty(resolvedOptions, 'hour12', dataPropertyDesc);
+}
+
+/* Values passed via options work */
+
+for (const hcValue of hcValues) {
+ const resolvedOptions = new Intl.DateTimeFormat(`en-US`, {
+ hour: 'numeric',
+ hourCycle: hcValue
+ }).resolvedOptions();
+
+ assert.sameValue(resolvedOptions.hourCycle, hcValue);
+ assert.sameValue(resolvedOptions.hour12, hour12Values.includes(hcValue));
+
+ verifyProperty(resolvedOptions, 'hourCycle', dataPropertyDesc);
+ verifyProperty(resolvedOptions, 'hour12', dataPropertyDesc);
+}
+
+/* When both extension key and option is passed, option takes precedence */
+
+let resolvedOptions = new Intl.DateTimeFormat(`en-US-u-hc-h12`, {
+ hour: 'numeric',
+ hourCycle: 'h23'
+}).resolvedOptions();
+
+assert.sameValue(resolvedOptions.hourCycle, 'h23');
+assert.sameValue(resolvedOptions.hour12, false);
+
+verifyProperty(resolvedOptions, 'hourCycle', dataPropertyDesc);
+verifyProperty(resolvedOptions, 'hour12', dataPropertyDesc);
+
+/* When hour12 and hourCycle are set, hour12 takes precedence */
+
+resolvedOptions = new Intl.DateTimeFormat(`fr`, {
+ hour: 'numeric',
+ hour12: true,
+ hourCycle: 'h23'
+}).resolvedOptions();
+
+assert(hour12Values.includes(resolvedOptions.hourCycle));
+assert.sameValue(resolvedOptions.hour12, true);
+
+verifyProperty(resolvedOptions, 'hourCycle', dataPropertyDesc);
+verifyProperty(resolvedOptions, 'hour12', dataPropertyDesc);
+
+/* When hour12 and extension key are set, hour12 takes precedence */
+
+resolvedOptions = new Intl.DateTimeFormat(`fr-u-hc-h24`, {
+ hour: 'numeric',
+ hour12: true,
+}).resolvedOptions();
+
+assert(hour12Values.includes(resolvedOptions.hourCycle));
+assert.sameValue(resolvedOptions.hour12, true);
+
+verifyProperty(resolvedOptions, 'hourCycle', dataPropertyDesc);
+verifyProperty(resolvedOptions, 'hour12', dataPropertyDesc);
+
+/* When the hour is not in the pattern, hourCycle and hour12 are not defined. */
+
+resolvedOptions = new Intl.DateTimeFormat("fr", {
+ hourCycle: "h12",
+ hour12: false,
+}).resolvedOptions();
+
+assert.sameValue(resolvedOptions.hour, undefined,
+ "Precondition: hour should not be included by default");
+assert.sameValue(resolvedOptions.hourCycle, undefined);
+assert.sameValue(resolvedOptions.hour12, undefined);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/length.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/length.js
new file mode 100644
index 0000000000..5e2070baf0
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/length.js
@@ -0,0 +1,33 @@
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-intl.datetimeformat.prototype.resolvedoptions
+description: >
+ Intl.DateTimeFormat.prototype.resolvedOptions.length is 0.
+info: |
+ Intl.DateTimeFormat.prototype.resolvedOptions ()
+
+ 17 ECMAScript Standard Built-in Objects:
+
+ Every built-in function object, including constructors, has a length
+ property whose value is an integer. Unless otherwise specified, this
+ value is equal to the largest number of named arguments shown in the
+ subclause headings for the function description. Optional parameters
+ (which are indicated with brackets: [ ]) or rest parameters (which
+ are shown using the form «...name») are not included in the default
+ argument count.
+ Unless otherwise specified, the length property of a built-in function
+ object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+ [[Configurable]]: true }.
+
+includes: [propertyHelper.js]
+---*/
+
+assert.sameValue(Intl.DateTimeFormat.prototype.resolvedOptions.length, 0);
+
+verifyNotEnumerable(Intl.DateTimeFormat.prototype.resolvedOptions, "length");
+verifyNotWritable(Intl.DateTimeFormat.prototype.resolvedOptions, "length");
+verifyConfigurable(Intl.DateTimeFormat.prototype.resolvedOptions, "length");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/name.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/name.js
new file mode 100644
index 0000000000..808c268e74
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/name.js
@@ -0,0 +1,28 @@
+// Copyright (C) 2016 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.DateTimeFormat.prototype.resolvedOptions
+description: >
+ Intl.DateTimeFormat.prototype.resolvedOptions.name is "resolvedOptions".
+info: |
+ 12.4.4 Intl.DateTimeFormat.prototype.resolvedOptions ()
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, that is not
+ identified as an anonymous function has a name property whose value
+ is a String.
+
+ Unless otherwise specified, the name property of a built-in Function
+ object, if it exists, has the attributes { [[Writable]]: false,
+ [[Enumerable]]: false, [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+assert.sameValue(Intl.DateTimeFormat.prototype.resolvedOptions.name, "resolvedOptions");
+
+verifyNotEnumerable(Intl.DateTimeFormat.prototype.resolvedOptions, "name");
+verifyNotWritable(Intl.DateTimeFormat.prototype.resolvedOptions, "name");
+verifyConfigurable(Intl.DateTimeFormat.prototype.resolvedOptions, "name");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/order-dayPeriod.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/order-dayPeriod.js
new file mode 100644
index 0000000000..fa49b52b68
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/order-dayPeriod.js
@@ -0,0 +1,40 @@
+// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-dayPeriod is not released yet
+// Copyright 2019 Google Inc. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-intl.datetimeformat.prototype.resolvedoptions
+description: Verifies the property order for the object returned by resolvedOptions().
+includes: [arrayContains.js]
+features: [Intl.DateTimeFormat-dayPeriod]
+---*/
+
+const options = new Intl.DateTimeFormat([], {
+ "dayPeriod": "short",
+ "hour": "numeric",
+ "minute": "numeric",
+}).resolvedOptions();
+
+const expected = [
+ "locale",
+ "calendar",
+ "numberingSystem",
+ "timeZone",
+ "hourCycle",
+ "hour12",
+ "dayPeriod",
+ "hour",
+ "minute",
+];
+
+let actual = Object.getOwnPropertyNames(options);
+
+// Ensure all expected items are in actual and also allow other properties
+// implemented in new proposals.
+assert(arrayContains(actual, expected));
+for (var i = 1; i < expected.length; i++) {
+ // Ensure the order as expected but allow additional new property in between
+ assert(actual.indexOf(expected[i-1]) < actual.indexOf(expected[i]));
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/order-fractionalSecondDigits.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/order-fractionalSecondDigits.js
new file mode 100644
index 0000000000..a5160bb3c8
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/order-fractionalSecondDigits.js
@@ -0,0 +1,37 @@
+// Copyright 2019 Google Inc. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-intl.datetimeformat.prototype.resolvedoptions
+description: Verifies the property order for the object returned by resolvedOptions().
+includes: [arrayContains.js]
+features: [Intl.DateTimeFormat-fractionalSecondDigits]
+---*/
+
+const options = new Intl.DateTimeFormat([], {
+ "fractionalSecondDigits": 3,
+ "minute": "numeric",
+ "second": "numeric",
+}).resolvedOptions();
+
+const expected = [
+ "locale",
+ "calendar",
+ "numberingSystem",
+ "timeZone",
+ "minute",
+ "second",
+ "fractionalSecondDigits",
+];
+
+let actual = Object.getOwnPropertyNames(options);
+
+// Ensure all expected items are in actual and also allow other properties
+// implemented in new proposals.
+assert(arrayContains(actual, expected));
+for (var i = 1; i < expected.length; i++) {
+ // Ensure the order as expected but allow additional new property in between
+ assert(actual.indexOf(expected[i-1]) < actual.indexOf(expected[i]));
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/order-style.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/order-style.js
new file mode 100644
index 0000000000..338701c4de
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/order-style.js
@@ -0,0 +1,43 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-intl.datetimeformat.prototype.resolvedoptions
+description: Verifies the property order for the object returned by resolvedOptions().
+includes: [arrayContains.js]
+features: [Intl.DateTimeFormat-datetimestyle]
+---*/
+
+const options = new Intl.DateTimeFormat([], {
+ "hourCycle": "h24",
+ "weekday": "short",
+ "era": "short",
+ "year": "numeric",
+ "month": "numeric",
+ "day": "numeric",
+ "hour": "numeric",
+ "minute": "numeric",
+ "second": "numeric",
+ "timeZoneName": "short",
+}).resolvedOptions();
+
+const expected = [
+ "locale",
+ "calendar",
+ "numberingSystem",
+ "timeZone",
+ "hourCycle",
+ "hour12",
+];
+
+let actual = Object.getOwnPropertyNames(options);
+
+// Ensure all expected items are in actual and also allow other properties
+// implemented in new proposals.
+assert(arrayContains(actual, expected));
+for (var i = 1; i < expected.length; i++) {
+ // Ensure the order as expected but allow additional new property in between
+ assert(actual.indexOf(expected[i-1]) < actual.indexOf(expected[i]));
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/order.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/order.js
new file mode 100644
index 0000000000..8f50b76b2d
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/order.js
@@ -0,0 +1,51 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-intl.datetimeformat.prototype.resolvedoptions
+description: Verifies the property order for the object returned by resolvedOptions().
+includes: [arrayContains.js]
+---*/
+
+const options = new Intl.DateTimeFormat([], {
+ "hourCycle": "h24",
+ "weekday": "short",
+ "era": "short",
+ "year": "numeric",
+ "month": "numeric",
+ "day": "numeric",
+ "hour": "numeric",
+ "minute": "numeric",
+ "second": "numeric",
+ "timeZoneName": "short",
+}).resolvedOptions();
+
+const expected = [
+ "locale",
+ "calendar",
+ "numberingSystem",
+ "timeZone",
+ "hourCycle",
+ "hour12",
+ "weekday",
+ "era",
+ "year",
+ "month",
+ "day",
+ "hour",
+ "minute",
+ "second",
+ "timeZoneName",
+];
+
+let actual = Object.getOwnPropertyNames(options);
+
+// Ensure all expected items are in actual and also allow other properties
+// implemented in new proposals.
+assert(arrayContains(actual, expected));
+for (var i = 1; i < expected.length; i++) {
+ // Ensure the order as expected but allow additional new property in between
+ assert(actual.indexOf(expected[i-1]) < actual.indexOf(expected[i]));
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/prop-desc.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/prop-desc.js
new file mode 100644
index 0000000000..c4f9742f07
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/prop-desc.js
@@ -0,0 +1,31 @@
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-intl.datetimeformat.prototype.resolvedoptions
+description: >
+ "resolvedOptions" property of Intl.DateTimeFormat.prototype.
+info: |
+ Intl.DateTimeFormat.prototype.resolvedOptions ()
+
+ 7 Requirements for Standard Built-in ECMAScript Objects
+
+ Unless specified otherwise in this document, the objects, functions, and constructors
+ described in this standard are subject to the generic requirements and restrictions
+ specified for standard built-in ECMAScript objects in the ECMAScript 2018 Language
+ Specification, 9th edition, clause 17, or successor.
+
+ 17 ECMAScript Standard Built-in Objects:
+
+ Every other data property described in clauses 18 through 26 and in Annex B.2 has the
+ attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }
+ unless otherwise specified.
+
+includes: [propertyHelper.js]
+---*/
+
+verifyNotEnumerable(Intl.DateTimeFormat.prototype, "resolvedOptions");
+verifyWritable(Intl.DateTimeFormat.prototype, "resolvedOptions");
+verifyConfigurable(Intl.DateTimeFormat.prototype, "resolvedOptions");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/resolved-locale-with-hc-unicode.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/resolved-locale-with-hc-unicode.js
new file mode 100644
index 0000000000..5b0516ca27
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/resolved-locale-with-hc-unicode.js
@@ -0,0 +1,89 @@
+// Copyright 2018 André Bargull. All rights reserved.
+// This code is governed by the license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.DateTimeFormat.prototype.resolvedOptions
+description: >
+ The resolved locale doesn't include a hc Unicode extension value if the
+ hour12 or hourCycle option is also present.
+info: |
+ 12.1.1 InitializeDateTimeFormat(dateTimeFormat, locales, options)
+ ...
+ 6. Let hour12 be ? GetOption(options, "hour12", "boolean", undefined, undefined).
+ 7. Let hourCycle be ? GetOption(options, "hourCycle", "string", « "h11", "h12", "h23", "h24" », undefined).
+ 8. If hour12 is not undefined, then
+ a. Let hourCycle be null.
+ 9. Set opt.[[hc]] to hourCycle.
+ ...
+
+ 9.2.6 ResolveLocale(availableLocales, requestedLocales, options, relevantExtensionKeys, localeData)
+ ...
+ 8. For each element key of relevantExtensionKeys in List order, do
+ ...
+ i. If options has a field [[<key>]], then
+ i. Let optionsValue be options.[[<key>]].
+ ii. Assert: Type(optionsValue) is either String, Undefined, or Null.
+ iii. If keyLocaleData contains optionsValue, then
+ 1. If SameValue(optionsValue, value) is false, then
+ a. Let value be optionsValue.
+ b. Let supportedExtensionAddition be "".
+ ...
+---*/
+
+var defaultLocale = new Intl.DateTimeFormat().resolvedOptions().locale;
+var defaultLocaleWithHourCycle = defaultLocale + "-u-hc-h11";
+
+function assertLocale(locale, expectedLocale, options, message) {
+ var resolved = new Intl.DateTimeFormat(locale, {
+ hour: "2-digit",
+ hour12: options.hour12,
+ hourCycle: options.hourCycle,
+ }).resolvedOptions();
+ assert.sameValue(resolved.locale, expectedLocale, message + " (With hour option.)");
+
+ // Also test the case when no hour option is present at all.
+ // The resolved options don't include hour12 and hourCycle if the date-time
+ // formatter doesn't include an hour option. This restriction doesn't apply
+ // to the hc Unicode extension value.
+ resolved = new Intl.DateTimeFormat(locale, {
+ hour12: options.hour12,
+ hourCycle: options.hourCycle,
+ }).resolvedOptions();
+ assert.sameValue(resolved.locale, expectedLocale, message + " (Without hour option.)");
+}
+
+assertLocale(defaultLocaleWithHourCycle, defaultLocale, {
+ hour12: false,
+ hourCycle: "h23",
+}, "hour12 and hourCycle options and hc Unicode extension value are present.");
+
+assertLocale(defaultLocaleWithHourCycle, defaultLocale, {
+ hour12: false,
+}, "hour12 option and hc Unicode extension value are present.");
+
+assertLocale(defaultLocaleWithHourCycle, defaultLocale, {
+ hourCycle: "h23",
+}, "hourCycle option and hc Unicode extension value are present.");
+
+assertLocale(defaultLocaleWithHourCycle, defaultLocaleWithHourCycle, {
+}, "Only hc Unicode extension value is present.");
+
+// And make sure the hc Unicode extension doesn't get added if it's not present
+// in the requested locale.
+assertLocale(defaultLocale, defaultLocale, {
+ hour12: false,
+ hourCycle: "h23",
+}, "hour12 and hourCycle options are present, but no hc Unicode extension value.");
+
+assertLocale(defaultLocale, defaultLocale, {
+ hour12: false,
+}, "hourCycle option is present, but no hc Unicode extension value.");
+
+assertLocale(defaultLocale, defaultLocale, {
+ hourCycle: "h23",
+}, "hourCycle option is present, but no hc Unicode extension value.");
+
+assertLocale(defaultLocale, defaultLocale, {
+}, "No options are present and no hc Unicode extension value.");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/shell.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/shell.js
new file mode 100644
index 0000000000..857452379f
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/shell.js
@@ -0,0 +1,50 @@
+// GENERATED, DO NOT EDIT
+// file: arrayContains.js
+// Copyright (C) 2017 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: |
+ Verify that a subArray is contained within an array.
+defines: [arrayContains]
+---*/
+
+/**
+ * @param {Array} array
+ * @param {Array} subArray
+ */
+
+function arrayContains(array, subArray) {
+ var found;
+ for (var i = 0; i < subArray.length; i++) {
+ found = false;
+ for (var j = 0; j < array.length; j++) {
+ if (subArray[i] === array[j]) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ return false;
+ }
+ }
+ return true;
+}
+
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+---*/
+
+function isConstructor(f) {
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/shell.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/shell.js
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/this-value-datetimeformat-prototype.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/this-value-datetimeformat-prototype.js
new file mode 100644
index 0000000000..34db44141b
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/this-value-datetimeformat-prototype.js
@@ -0,0 +1,17 @@
+// Copyright 2012 Google Inc. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-properties-of-intl-datetimeformat-prototype-object
+description: >
+ Tests that Intl.DateTimeFormat.prototype is not an object that has
+ been initialized as an Intl.DateTimeFormat.
+author: Roozbeh Pournader
+---*/
+
+// test by calling a function that should fail as "this" is not an object
+// initialized as an Intl.DateTimeFormat
+assert.throws(TypeError, () => Intl.DateTimeFormat.prototype.format(0),
+ "Intl.DateTimeFormat's prototype is not an object that has been initialized as an Intl.DateTimeFormat");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/this-value-not-datetimeformat.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/this-value-not-datetimeformat.js
new file mode 100644
index 0000000000..4805ca2f69
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/this-value-not-datetimeformat.js
@@ -0,0 +1,28 @@
+// Copyright 2012 Mozilla Corporation. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es5id: 12.3_b
+description: >
+ Tests that Intl.DateTimeFormat.prototype functions throw a
+ TypeError if called on a non-object value or an object that hasn't
+ been initialized as a DateTimeFormat.
+author: Norbert Lindenberg
+---*/
+
+var functions = {
+ "format getter": Object.getOwnPropertyDescriptor(Intl.DateTimeFormat.prototype, "format").get,
+ resolvedOptions: Intl.DateTimeFormat.prototype.resolvedOptions
+};
+var invalidTargets = [undefined, null, true, 0, "DateTimeFormat", [], {}];
+
+Object.getOwnPropertyNames(functions).forEach(function (functionName) {
+ var f = functions[functionName];
+ invalidTargets.forEach(function (target) {
+ assert.throws(TypeError, function() {
+ f.call(target);
+ }, "Calling " + functionName + " on " + target + " was not rejected.");
+ });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/toStringTag/browser.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/toStringTag/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/toStringTag/browser.js
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/toStringTag/shell.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/toStringTag/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/toStringTag/shell.js
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/toStringTag/toString-changed-tag.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/toStringTag/toString-changed-tag.js
new file mode 100644
index 0000000000..69b853ad0a
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/toStringTag/toString-changed-tag.js
@@ -0,0 +1,30 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-intl.datetimeformat.prototype-@@tostringtag
+description: >
+ Object.prototype.toString utilizes Intl.DateTimeFormat.prototype[@@toStringTag].
+info: |
+ Object.prototype.toString ( )
+
+ [...]
+ 14. Else, let builtinTag be "Object".
+ 15. Let tag be ? Get(O, @@toStringTag).
+ 16. If Type(tag) is not String, set tag to builtinTag.
+ 17. Return the string-concatenation of "[object ", tag, and "]".
+
+ Intl.DateTimeFormat.prototype [ @@toStringTag ]
+
+ This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.
+features: [Symbol.toStringTag]
+---*/
+
+Object.defineProperty(Intl.DateTimeFormat.prototype, Symbol.toStringTag, {
+ value: "test262",
+});
+
+assert.sameValue(Object.prototype.toString.call(Intl.DateTimeFormat.prototype), "[object test262]");
+assert.sameValue(Object.prototype.toString.call(new Intl.DateTimeFormat()), "[object test262]");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/toStringTag/toString-removed-tag.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/toStringTag/toString-removed-tag.js
new file mode 100644
index 0000000000..170562a720
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/toStringTag/toString-removed-tag.js
@@ -0,0 +1,24 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-intl.datetimeformat.prototype-@@tostringtag
+description: >
+ Object.prototype.toString doesn't special-case neither Intl.DateTimeFormat instances nor its prototype.
+info: |
+ Object.prototype.toString ( )
+
+ [...]
+ 14. Else, let builtinTag be "Object".
+ 15. Let tag be ? Get(O, @@toStringTag).
+ 16. If Type(tag) is not String, set tag to builtinTag.
+ 17. Return the string-concatenation of "[object ", tag, and "]".
+features: [Symbol.toStringTag]
+---*/
+
+delete Intl.DateTimeFormat.prototype[Symbol.toStringTag];
+
+assert.sameValue(Object.prototype.toString.call(Intl.DateTimeFormat.prototype), "[object Object]");
+assert.sameValue(Object.prototype.toString.call(new Intl.DateTimeFormat()), "[object Object]");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/toStringTag/toString.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/toStringTag/toString.js
new file mode 100644
index 0000000000..f8e5d3db50
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/toStringTag/toString.js
@@ -0,0 +1,26 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-intl.datetimeformat.prototype-@@tostringtag
+description: >
+ Object.prototype.toString utilizes Intl.DateTimeFormat.prototype[@@toStringTag].
+info: |
+ Object.prototype.toString ( )
+
+ [...]
+ 14. Else, let builtinTag be "Object".
+ 15. Let tag be ? Get(O, @@toStringTag).
+ 16. If Type(tag) is not String, set tag to builtinTag.
+ 17. Return the string-concatenation of "[object ", tag, and "]".
+
+ Intl.DateTimeFormat.prototype [ @@toStringTag ]
+
+ The initial value of the @@toStringTag property is the String value "Intl.DateTimeFormat".
+features: [Symbol.toStringTag]
+---*/
+
+assert.sameValue(Object.prototype.toString.call(Intl.DateTimeFormat.prototype), "[object Intl.DateTimeFormat]");
+assert.sameValue(Object.prototype.toString.call(new Intl.DateTimeFormat()), "[object Intl.DateTimeFormat]");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/toStringTag/toStringTag.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/toStringTag/toStringTag.js
new file mode 100644
index 0000000000..b118adeac8
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/toStringTag/toStringTag.js
@@ -0,0 +1,25 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-intl.datetimeformat.prototype-@@tostringtag
+description: >
+ Property descriptor of Intl.DateTimeFormat.prototype[@@toStringTag].
+info: |
+ Intl.DateTimeFormat.prototype [ @@toStringTag ]
+
+ The initial value of the @@toStringTag property is the String value "Intl.DateTimeFormat".
+
+ This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.
+features: [Symbol.toStringTag]
+includes: [propertyHelper.js]
+---*/
+
+verifyProperty(Intl.DateTimeFormat.prototype, Symbol.toStringTag, {
+ value: "Intl.DateTimeFormat",
+ writable: false,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/required-date-time-formats.js b/js/src/tests/test262/intl402/DateTimeFormat/required-date-time-formats.js
new file mode 100644
index 0000000000..6a17fc5edb
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/required-date-time-formats.js
@@ -0,0 +1,48 @@
+// Copyright 2012 Mozilla Corporation. All rights reserved.
+// This code is governed by the license found in the LICENSE file.
+
+/*---
+es5id: 12.2.3_c
+description: >
+ Tests that Intl.DateTimeFormat provides the required date-time
+ format component subsets.
+author: Norbert Lindenberg
+includes: [testIntl.js]
+---*/
+
+var locales = ["de-DE", "en-US", "hi-IN", "id-ID", "ja-JP", "th-TH", "zh-Hans-CN", "zh-Hant-TW", "zxx"];
+var subsets = [
+ {weekday: "long", year: "numeric", month: "numeric", day: "numeric",
+ hour: "numeric", minute: "numeric", second: "numeric"},
+ {weekday: "long", year: "numeric", month: "numeric", day: "numeric"},
+ {year: "numeric", month: "numeric", day: "numeric"},
+ {year: "numeric", month: "numeric"},
+ {month: "numeric", day: "numeric"},
+ {hour: "numeric", minute: "numeric", second: "numeric"},
+ {hour: "numeric", minute: "numeric"}
+];
+
+locales.forEach(function (locale) {
+ subsets.forEach(function (subset) {
+ var format = new Intl.DateTimeFormat([locale], subset);
+ var actual = format.resolvedOptions();
+ getDateTimeComponents().forEach(function (component) {
+ if (actual.hasOwnProperty(component)) {
+ assert(subset.hasOwnProperty(component),
+ "Unrequested component " + component +
+ " added to requested subset " + JSON.stringify(subset) +
+ "; locale " + locale + ".");
+ assert.notSameValue(getDateTimeComponentValues(component).indexOf(actual[component]), -1,
+ "Invalid value " + actual[component] + " for date-time component " + component + "." +
+ " (Testing locale " + locale + "; subset " + JSON.stringify(subset) + ")");
+ } else {
+ assert.sameValue(subset.hasOwnProperty(component), false,
+ "Missing component " + component +
+ " from requested subset " + JSON.stringify(subset) +
+ "; locale " + locale + ".");
+ }
+ });
+ });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/shell.js b/js/src/tests/test262/intl402/DateTimeFormat/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/shell.js
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/subclassing.js b/js/src/tests/test262/intl402/DateTimeFormat/subclassing.js
new file mode 100644
index 0000000000..c7167676b8
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/subclassing.js
@@ -0,0 +1,30 @@
+// Copyright 2011-2012 Norbert Lindenberg. All rights reserved.
+// Copyright 2012 Mozilla Corporation. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es5id: 12.1.2
+description: Tests that Intl.DateTimeFormat can be subclassed.
+author: Norbert Lindenberg
+includes: [compareArray.js]
+---*/
+
+// get a date-time format and have it format an array of dates for comparison with the subclass
+var locales = ["tlh", "id", "en"];
+var a = [new Date(0), Date.now(), new Date(Date.parse("1989-11-09T17:57:00Z"))];
+var referenceDateTimeFormat = new Intl.DateTimeFormat(locales);
+var referenceFormatted = a.map(referenceDateTimeFormat.format);
+
+class MyDateTimeFormat extends Intl.DateTimeFormat {
+ constructor(locales, options) {
+ super(locales, options);
+ // could initialize MyDateTimeFormat properties
+ }
+ // could add methods to MyDateTimeFormat.prototype
+}
+
+var format = new MyDateTimeFormat(locales);
+var actual = a.map(format.format);
+assert.compareArray(actual, referenceFormatted);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/basic.js b/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/basic.js
new file mode 100644
index 0000000000..8b4e2884e7
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/basic.js
@@ -0,0 +1,25 @@
+// Copyright 2012 Google Inc. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es5id: 12.2.2_a
+description: >
+ Tests that Intl.DateTimeFormat has a supportedLocalesOf property,
+ and it works as planned.
+author: Roozbeh Pournader
+---*/
+
+var defaultLocale = new Intl.DateTimeFormat().resolvedOptions().locale;
+var notSupported = 'zxx'; // "no linguistic content"
+var requestedLocales = [defaultLocale, notSupported];
+
+var supportedLocales;
+
+assert(Intl.DateTimeFormat.hasOwnProperty('supportedLocalesOf'), "Intl.DateTimeFormat doesn't have a supportedLocalesOf property.");
+
+supportedLocales = Intl.DateTimeFormat.supportedLocalesOf(requestedLocales);
+assert.sameValue(supportedLocales.length, 1, 'The length of supported locales list is not 1.');
+
+assert.sameValue(supportedLocales[0], defaultLocale, 'The default locale is not returned in the supported list.');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/browser.js b/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/browser.js
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/builtin.js b/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/builtin.js
new file mode 100644
index 0000000000..5af3ea6504
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/builtin.js
@@ -0,0 +1,30 @@
+// Copyright 2012 Mozilla Corporation. All rights reserved.
+// This code is governed by the license found in the LICENSE file.
+
+/*---
+es5id: 12.2.2_L15
+description: >
+ Tests that Intl.DateTimeFormat.supportedLocalesOf meets the
+ requirements for built-in objects defined by the introduction of
+ chapter 17 of the ECMAScript Language Specification.
+author: Norbert Lindenberg
+includes: [isConstructor.js]
+features: [Reflect.construct]
+---*/
+
+assert.sameValue(Object.prototype.toString.call(Intl.DateTimeFormat.supportedLocalesOf), "[object Function]",
+ "The [[Class]] internal property of a built-in function must be " +
+ "\"Function\".");
+
+assert(Object.isExtensible(Intl.DateTimeFormat.supportedLocalesOf),
+ "Built-in objects must be extensible.");
+
+assert.sameValue(Object.getPrototypeOf(Intl.DateTimeFormat.supportedLocalesOf), Function.prototype);
+
+assert.sameValue(Intl.DateTimeFormat.supportedLocalesOf.hasOwnProperty("prototype"), false,
+ "Built-in functions that aren't constructors must not have a prototype property.");
+
+assert.sameValue(isConstructor(Intl.DateTimeFormat.supportedLocalesOf), false,
+ "Built-in functions don't implement [[Construct]] unless explicitly specified.");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/length.js b/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/length.js
new file mode 100644
index 0000000000..728265c107
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/length.js
@@ -0,0 +1,33 @@
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-intl.datetimeformat.supportedlocalesof
+description: >
+ Intl.DateTimeFormat.supportedLocalesOf.length is 1.
+info: |
+ Intl.DateTimeFormat.supportedLocalesOf ( locales [ , options ] )
+
+ 17 ECMAScript Standard Built-in Objects:
+
+ Every built-in function object, including constructors, has a length
+ property whose value is an integer. Unless otherwise specified, this
+ value is equal to the largest number of named arguments shown in the
+ subclause headings for the function description. Optional parameters
+ (which are indicated with brackets: [ ]) or rest parameters (which
+ are shown using the form «...name») are not included in the default
+ argument count.
+ Unless otherwise specified, the length property of a built-in function
+ object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+ [[Configurable]]: true }.
+
+includes: [propertyHelper.js]
+---*/
+
+assert.sameValue(Intl.DateTimeFormat.supportedLocalesOf.length, 1);
+
+verifyNotEnumerable(Intl.DateTimeFormat.supportedLocalesOf, "length");
+verifyNotWritable(Intl.DateTimeFormat.supportedLocalesOf, "length");
+verifyConfigurable(Intl.DateTimeFormat.supportedLocalesOf, "length");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/name.js b/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/name.js
new file mode 100644
index 0000000000..1575c0d168
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/name.js
@@ -0,0 +1,28 @@
+// Copyright (C) 2016 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.DateTimeFormat.supportedLocalesOf
+description: >
+ Intl.DateTimeFormat.supportedLocalesOf.name is "supportedLocalesOf".
+info: |
+ 12.3.2 Intl.DateTimeFormat.supportedLocalesOf (locales [ , options ])
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, that is not
+ identified as an anonymous function has a name property whose value
+ is a String.
+
+ Unless otherwise specified, the name property of a built-in Function
+ object, if it exists, has the attributes { [[Writable]]: false,
+ [[Enumerable]]: false, [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+assert.sameValue(Intl.DateTimeFormat.supportedLocalesOf.name, "supportedLocalesOf");
+
+verifyNotEnumerable(Intl.DateTimeFormat.supportedLocalesOf, "name");
+verifyNotWritable(Intl.DateTimeFormat.supportedLocalesOf, "name");
+verifyConfigurable(Intl.DateTimeFormat.supportedLocalesOf, "name");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/prop-desc.js b/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/prop-desc.js
new file mode 100644
index 0000000000..3a81c9f952
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/prop-desc.js
@@ -0,0 +1,31 @@
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-intl.datetimeformat.supportedlocalesof
+description: >
+ "supportedLocalesOf" property of Intl.DateTimeFormat.
+info: |
+ Intl.DateTimeFormat.supportedLocalesOf ( locales [ , options ] )
+
+ 7 Requirements for Standard Built-in ECMAScript Objects
+
+ Unless specified otherwise in this document, the objects, functions, and constructors
+ described in this standard are subject to the generic requirements and restrictions
+ specified for standard built-in ECMAScript objects in the ECMAScript 2018 Language
+ Specification, 9th edition, clause 17, or successor.
+
+ 17 ECMAScript Standard Built-in Objects:
+
+ Every other data property described in clauses 18 through 26 and in Annex B.2 has the
+ attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }
+ unless otherwise specified.
+
+includes: [propertyHelper.js]
+---*/
+
+verifyNotEnumerable(Intl.DateTimeFormat, "supportedLocalesOf");
+verifyWritable(Intl.DateTimeFormat, "supportedLocalesOf");
+verifyConfigurable(Intl.DateTimeFormat, "supportedLocalesOf");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/shell.js b/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/shell.js
new file mode 100644
index 0000000000..54371b7789
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/shell.js
@@ -0,0 +1,19 @@
+// GENERATED, DO NOT EDIT
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+---*/
+
+function isConstructor(f) {
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/taint-Object-prototype.js b/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/taint-Object-prototype.js
new file mode 100644
index 0000000000..47ed85a18c
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/taint-Object-prototype.js
@@ -0,0 +1,16 @@
+// Copyright 2013 Mozilla Corporation. All rights reserved.
+// This code is governed by the license found in the LICENSE file.
+
+/*---
+es5id: 12.2.2_b
+description: >
+ Tests that Intl.DateTimeFormat.supportedLocalesOf doesn't access
+ arguments that it's not given.
+author: Norbert Lindenberg
+includes: [testIntl.js]
+---*/
+
+taintDataProperty(Object.prototype, "1");
+new Intl.DateTimeFormat("und");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/taint-Object-prototype-date-time-components.js b/js/src/tests/test262/intl402/DateTimeFormat/taint-Object-prototype-date-time-components.js
new file mode 100644
index 0000000000..a05e77b80e
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/taint-Object-prototype-date-time-components.js
@@ -0,0 +1,18 @@
+// Copyright 2012 Mozilla Corporation. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es5id: 12.1.1_22
+description: >
+ Tests that the behavior of a Record is not affected by
+ adversarial changes to Object.prototype.
+author: Norbert Lindenberg
+includes: [testIntl.js]
+---*/
+
+taintProperties(["weekday", "era", "year", "month", "day", "hour", "minute", "second", "timeZone"]);
+
+var locale = new Intl.DateTimeFormat(undefined, {localeMatcher: "lookup"}).resolvedOptions().locale;
+assert(isCanonicalizedStructurallyValidLanguageTag(locale), "DateTimeFormat returns invalid locale " + locale + ".");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/taint-Object-prototype-dayPeriod.js b/js/src/tests/test262/intl402/DateTimeFormat/taint-Object-prototype-dayPeriod.js
new file mode 100644
index 0000000000..a0f21acc24
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/taint-Object-prototype-dayPeriod.js
@@ -0,0 +1,19 @@
+// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-dayPeriod is not released yet
+// Copyright 2019 Google Inc. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-initializedatetimeformat
+description: >
+ Tests that the behavior of a Record is not affected by
+ adversarial changes to Object.prototype.
+includes: [testIntl.js]
+features: [Intl.DateTimeFormat-dayPeriod]
+---*/
+
+taintProperties(["dayPeriod"]);
+
+var locale = new Intl.DateTimeFormat(undefined, {localeMatcher: "lookup"}).resolvedOptions().locale;
+assert(isCanonicalizedStructurallyValidLanguageTag(locale), "DateTimeFormat returns invalid locale " + locale + ".");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/taint-Object-prototype-fractionalSecondDigits.js b/js/src/tests/test262/intl402/DateTimeFormat/taint-Object-prototype-fractionalSecondDigits.js
new file mode 100644
index 0000000000..6b7836e1c8
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/taint-Object-prototype-fractionalSecondDigits.js
@@ -0,0 +1,18 @@
+// Copyright 2019 Google Inc. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-initializedatetimeformat
+description: >
+ Tests that the behavior of a Record is not affected by
+ adversarial changes to Object.prototype.
+includes: [testIntl.js]
+features: [Intl.DateTimeFormat-fractionalSecondDigits]
+---*/
+
+taintProperties(["fractionalSecondDigits"]);
+
+var locale = new Intl.DateTimeFormat(undefined, {localeMatcher: "lookup"}).resolvedOptions().locale;
+assert(isCanonicalizedStructurallyValidLanguageTag(locale), "DateTimeFormat returns invalid locale " + locale + ".");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/taint-Object-prototype.js b/js/src/tests/test262/intl402/DateTimeFormat/taint-Object-prototype.js
new file mode 100644
index 0000000000..5dd7b61535
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/taint-Object-prototype.js
@@ -0,0 +1,18 @@
+// Copyright 2012 Mozilla Corporation. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es5id: 12.1.1_5
+description: >
+ Tests that the behavior of a Record is not affected by
+ adversarial changes to Object.prototype.
+author: Norbert Lindenberg
+includes: [testIntl.js]
+---*/
+
+taintProperties(["localeMatcher"]);
+
+var locale = new Intl.DateTimeFormat(undefined, {localeMatcher: "lookup"}).resolvedOptions().locale;
+assert(isCanonicalizedStructurallyValidLanguageTag(locale), "DateTimeFormat returns invalid locale " + locale + ".");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/test-option-date-time-components.js b/js/src/tests/test262/intl402/DateTimeFormat/test-option-date-time-components.js
new file mode 100644
index 0000000000..a0e0a16dc7
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/test-option-date-time-components.js
@@ -0,0 +1,17 @@
+// Copyright 2012 Mozilla Corporation. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es5id: 12.1.1_23
+description: >
+ Tests that the options for the date and time components are
+ processed correctly.
+author: Norbert Lindenberg
+includes: [testIntl.js]
+---*/
+
+getDateTimeComponents().forEach(function (component) {
+ testOption(Intl.DateTimeFormat, component, "string", getDateTimeComponentValues(component), undefined, {isILD: true});
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/test-option-formatMatcher.js b/js/src/tests/test262/intl402/DateTimeFormat/test-option-formatMatcher.js
new file mode 100644
index 0000000000..41c25d6e99
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/test-option-formatMatcher.js
@@ -0,0 +1,13 @@
+// Copyright 2012 Mozilla Corporation. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es5id: 12.1.1_25
+description: Tests that the option formatMatcher is processed correctly.
+author: Norbert Lindenberg
+includes: [testIntl.js]
+---*/
+
+testOption(Intl.DateTimeFormat, "formatMatcher", "string", ["basic", "best fit"], "best fit", {noReturn: true});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/test-option-hour12.js b/js/src/tests/test262/intl402/DateTimeFormat/test-option-hour12.js
new file mode 100644
index 0000000000..c6a4124bf9
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/test-option-hour12.js
@@ -0,0 +1,16 @@
+// Copyright 2012 Mozilla Corporation. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es5id: 12.1.1_18
+description: Tests that the option hour12 is processed correctly.
+author: Norbert Lindenberg
+includes: [testIntl.js]
+---*/
+
+testOption(Intl.DateTimeFormat, "hour12", "boolean", undefined, undefined,
+ {extra: {any: {hour: "numeric", minute: "numeric"}}});
+testOption(Intl.DateTimeFormat, "hour12", "boolean", undefined, undefined,
+ {noReturn: true});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/test-option-localeMatcher.js b/js/src/tests/test262/intl402/DateTimeFormat/test-option-localeMatcher.js
new file mode 100644
index 0000000000..6adf184682
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/test-option-localeMatcher.js
@@ -0,0 +1,13 @@
+// Copyright 2012 Mozilla Corporation. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es5id: 12.1.1_6
+description: Tests that the option localeMatcher is processed correctly.
+author: Norbert Lindenberg
+includes: [testIntl.js]
+---*/
+
+testOption(Intl.DateTimeFormat, "localeMatcher", "string", ["lookup", "best fit"], "best fit", {noReturn: true});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/this-value-ignored.js b/js/src/tests/test262/intl402/DateTimeFormat/this-value-ignored.js
new file mode 100644
index 0000000000..e96110d1ca
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/this-value-ignored.js
@@ -0,0 +1,37 @@
+// Copyright 2012 Mozilla Corporation. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-intl-datetimeformat-constructor
+description: >
+ Tests that the this-value is ignored in DateTimeFormat, if the this-value
+ isn't a DateTimeFormat instance.
+author: Norbert Lindenberg
+includes: [testIntl.js]
+---*/
+
+testWithIntlConstructors(function (Constructor) {
+ if (Constructor === Intl.DateTimeFormat)
+ return;
+
+ var obj, newObj;
+
+ // variant 1: use constructor in a "new" expression
+ obj = new Constructor();
+ newObj = Intl.DateTimeFormat.call(obj);
+ assert.notSameValue(obj, newObj, "DateTimeFormat object created with \"new\" was not ignored as this-value.");
+
+ // variant 2: use constructor as a function
+ if (Constructor !== Intl.Collator &&
+ Constructor !== Intl.NumberFormat &&
+ Constructor !== Intl.DateTimeFormat)
+ {
+ // Newer Intl constructors are not callable as a function.
+ return;
+ }
+ obj = Constructor();
+ newObj = Intl.DateTimeFormat.call(obj);
+ assert.notSameValue(obj, newObj, "DateTimeFormat object created with constructor as function was not ignored as this-value.");
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/timezone-canonicalized.js b/js/src/tests/test262/intl402/DateTimeFormat/timezone-canonicalized.js
new file mode 100644
index 0000000000..e7e28cd0e6
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/timezone-canonicalized.js
@@ -0,0 +1,37 @@
+// Copyright 2012 Mozilla Corporation. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es5id: 6.4_c
+description: >
+ Tests that additional time zone names, if accepted, are handled
+ correctly.
+author: Norbert Lindenberg
+---*/
+
+// canonicalization specified in conformance clause
+var additionalTimeZoneNames = {
+ "Etc/GMT": "UTC",
+ "Greenwich": "UTC",
+ "PRC": "Asia/Shanghai",
+ "AmErIcA/LoS_aNgElEs": "America/Los_Angeles",
+ "etc/gmt+7": "Etc/GMT+7"
+};
+
+Object.getOwnPropertyNames(additionalTimeZoneNames).forEach(function (name) {
+ var format, error;
+ try {
+ format = new Intl.DateTimeFormat([], {timeZone: name});
+ } catch (e) {
+ error = e;
+ }
+ if (error === undefined) {
+ var actual = format.resolvedOptions().timeZone;
+ var expected = additionalTimeZoneNames[name];
+ assert.sameValue(actual, expected, "Time zone name " + name + " was accepted, but incorrectly canonicalized.");
+ } else {
+ assert(error instanceof RangeError, "Time zone name " + name + " was rejected with wrong error " + error.name + ".");
+ }
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/timezone-invalid.js b/js/src/tests/test262/intl402/DateTimeFormat/timezone-invalid.js
new file mode 100644
index 0000000000..f42ffd0201
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/timezone-invalid.js
@@ -0,0 +1,28 @@
+// Copyright 2012 Mozilla Corporation. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es5id: 6.4_b
+description: Tests that invalid time zone names are not accepted.
+author: Norbert Lindenberg
+---*/
+
+var invalidTimeZoneNames = [
+ "",
+ "MEZ", // localized abbreviation
+ "Pacific Time", // localized long form
+ "cnsha", // BCP 47 time zone code
+ "invalid", // as the name says
+ "Europe/İstanbul", // non-ASCII letter
+ "asıa/baku", // non-ASCII letter
+ "europe/brußels" // non-ASCII letter
+];
+
+invalidTimeZoneNames.forEach(function (name) {
+ // this must throw an exception for an invalid time zone name
+ assert.throws(RangeError, function() {
+ var format = new Intl.DateTimeFormat(["de-de"], {timeZone: name});
+ }, "Invalid time zone name " + name + " was not rejected.");
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/timezone-utc.js b/js/src/tests/test262/intl402/DateTimeFormat/timezone-utc.js
new file mode 100644
index 0000000000..f27d109b1a
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/timezone-utc.js
@@ -0,0 +1,21 @@
+// Copyright 2012 Mozilla Corporation. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es5id: 6.4_a
+description: Tests that valid time zone names are accepted.
+author: Norbert Lindenberg
+---*/
+
+var validTimeZoneNames = [
+ "UTC",
+ "utc" // time zone names are case-insensitive
+];
+
+validTimeZoneNames.forEach(function (name) {
+ // this must not throw an exception for a valid time zone name
+ var format = new Intl.DateTimeFormat(["de-de"], {timeZone: name});
+ assert.sameValue(format.resolvedOptions().timeZone, name.toUpperCase(), "Time zone name " + name + " was not correctly accepted.");
+});
+
+reportCompare(0, 0);