summaryrefslogtreecommitdiffstats
path: root/js/src/tests/test262/intl402/RelativeTimeFormat
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/tests/test262/intl402/RelativeTimeFormat')
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/browser.js0
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/constructor/browser.js0
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/browser.js0
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/locales-invalid.js20
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/locales-valid.js45
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/newtarget-undefined.js29
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-invalid.js18
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-localeMatcher-invalid.js31
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-numberingSystem-invalid.js46
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-numberingSystem-valid.js29
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-numeric-invalid.js33
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-numeric-valid.js27
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-order.js68
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-proto.js90
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-style-invalid.js34
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-style-valid.js28
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-throwing-getters.js119
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-toobject-prototype.js37
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-toobject.js28
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-undefined.js40
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/proto-from-ctor-realm.js59
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/shell.js0
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/subclassing.js42
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/constructor/length.js24
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/constructor/name.js23
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/constructor/prop-desc.js37
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/constructor/prototype.js19
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/constructor/shell.js0
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/basic.js23
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/branding.js34
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/browser.js0
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/length.js24
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/locales-invalid.js22
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/name.js23
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/options-localeMatcher-invalid.js36
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/options-null.js22
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/options-toobject.js43
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/options-undefined.js28
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/prop-desc.js31
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/result-type.js35
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/shell.js0
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/instance/browser.js0
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/instance/extensibility.js22
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/instance/prototype.js22
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/instance/shell.js0
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/browser.js0
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/constructor/browser.js0
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/constructor/prop-desc.js26
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/constructor/shell.js0
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/branding.js28
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/browser.js0
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/en-us-numeric-always.js39
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/en-us-numeric-auto.js87
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/en-us-style-short.js42
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/length.js23
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/name.js22
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/pl-pl-style-long.js71
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/pl-pl-style-narrow.js62
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/pl-pl-style-short.js62
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/prop-desc.js30
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/shell.js0
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/unit-invalid.js55
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/unit-plural.js42
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/value-non-finite.js38
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/value-symbol.js22
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/value-tonumber.js40
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/branding.js28
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/browser.js0
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/en-us-numeric-always.js107
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/en-us-numeric-auto.js156
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/en-us-style-short.js111
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/length.js23
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/name.js22
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/pl-pl-style-long.js141
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/pl-pl-style-narrow.js130
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/pl-pl-style-short.js130
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/prop-desc.js30
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/result-type.js84
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/shell.js0
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/unit-invalid.js55
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/unit-plural.js54
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/value-non-finite.js38
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/value-symbol.js22
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/value-tonumber.js52
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/prop-desc.js24
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/resolvedOptions/branding.js28
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/resolvedOptions/browser.js0
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/resolvedOptions/caching.js19
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/resolvedOptions/length.js23
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/resolvedOptions/name.js22
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/resolvedOptions/order.js29
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/resolvedOptions/prop-desc.js30
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/resolvedOptions/shell.js0
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/resolvedOptions/type.js42
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/shell.js0
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/toStringTag/browser.js0
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/toStringTag/shell.js0
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/toStringTag/toString.js18
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/prototype/toStringTag/toStringTag.js25
-rw-r--r--js/src/tests/test262/intl402/RelativeTimeFormat/shell.js0
100 files changed, 3423 insertions, 0 deletions
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/browser.js b/js/src/tests/test262/intl402/RelativeTimeFormat/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/browser.js
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/browser.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/browser.js
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/browser.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/browser.js
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/locales-invalid.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/locales-invalid.js
new file mode 100644
index 0000000000..dc5ea2b632
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/locales-invalid.js
@@ -0,0 +1,20 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat
+description: Checks error cases for the locales argument to the RelativeTimeFormat constructor.
+info: |
+ InitializeRelativeTimeFormat (relativeTimeFormat, locales, options)
+ 3. Let _requestedLocales_ be ? CanonicalizeLocaleList(_locales_).
+includes: [testIntl.js]
+features: [Intl.RelativeTimeFormat]
+---*/
+
+assert.sameValue(typeof Intl.RelativeTimeFormat, "function");
+
+for (const [locales, expectedError] of getInvalidLocaleArguments()) {
+ assert.throws(expectedError, function() { new Intl.RelativeTimeFormat(locales) });
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/locales-valid.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/locales-valid.js
new file mode 100644
index 0000000000..91a1721531
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/locales-valid.js
@@ -0,0 +1,45 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat
+description: Checks various cases for the locales argument to the RelativeTimeFormat constructor.
+info: |
+ InitializeRelativeTimeFormat (relativeTimeFormat, locales, options)
+ 3. Let _requestedLocales_ be ? CanonicalizeLocaleList(_locales_).
+features: [Intl.RelativeTimeFormat]
+---*/
+
+const defaultLocale = new Intl.RelativeTimeFormat().resolvedOptions().locale;
+
+const tests = [
+ [undefined, defaultLocale, "undefined"],
+ ["EN", "en", "Single value"],
+ [[], defaultLocale, "Empty array"],
+ [["en", "EN"], "en", "Duplicate value (canonical first)"],
+ [["EN", "en"], "en", "Duplicate value (canonical last)"],
+ [{ 0: "DE", length: 0 }, defaultLocale, "Object with zero length"],
+ [{ 0: "DE", length: 1 }, "de", "Object with length"],
+];
+
+const errorTests = [
+ [["en-GB-oed"], "Grandfathered"],
+ [["x-private"], "Private", ["lookup"]],
+];
+
+for (const [locales, expected, name, matchers = ["best fit", "lookup"]] of tests) {
+ for (const matcher of matchers) {
+ const rtf = new Intl.RelativeTimeFormat(locales, {localeMatcher: matcher});
+ assert.sameValue(rtf.resolvedOptions().locale, expected, name);
+ }
+}
+
+for (const [locales, name, matchers = ["best fit", "lookup"]] of errorTests) {
+ for (const matcher of matchers) {
+ assert.throws(RangeError, function() {
+ new Intl.RelativeTimeFormat(locales, {localeMatcher: matcher});
+ }, name);
+ }
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/newtarget-undefined.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/newtarget-undefined.js
new file mode 100644
index 0000000000..34e34faaed
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/newtarget-undefined.js
@@ -0,0 +1,29 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-intl.RelativeTimeFormat
+description: >
+ Verifies the NewTarget check for Intl.RelativeTimeFormat.
+info: |
+ Intl.RelativeTimeFormat ([ locales [ , options ]])
+
+ 1. If NewTarget is undefined, throw a TypeError exception.
+features: [Intl.RelativeTimeFormat]
+---*/
+
+assert.sameValue(typeof Intl.RelativeTimeFormat, "function");
+
+assert.throws(TypeError, function() {
+ Intl.RelativeTimeFormat();
+});
+
+assert.throws(TypeError, function() {
+ Intl.RelativeTimeFormat("en");
+});
+
+assert.throws(TypeError, function() {
+ Intl.RelativeTimeFormat("not-valid-tag");
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-invalid.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-invalid.js
new file mode 100644
index 0000000000..94db7ed97f
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-invalid.js
@@ -0,0 +1,18 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat
+description: Checks handling of a null options argument to the RelativeTimeFormat constructor.
+info: |
+ InitializeRelativeTimeFormat (relativeTimeFormat, locales, options)
+ 5. Else
+ a. Let options be ? ToObject(options).
+features: [Intl.RelativeTimeFormat]
+---*/
+
+assert.sameValue(typeof Intl.RelativeTimeFormat, "function");
+
+assert.throws(TypeError, function() { new Intl.RelativeTimeFormat([], null) })
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-localeMatcher-invalid.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-localeMatcher-invalid.js
new file mode 100644
index 0000000000..f567f29a04
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-localeMatcher-invalid.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-Intl.RelativeTimeFormat
+description: Checks handling of invalid value for the localeMatcher option to the RelativeTimeFormat constructor.
+info: |
+ InitializeRelativeTimeFormat (relativeTimeFormat, locales, options)
+ 7. Let matcher be ? GetOption(options, "localeMatcher", "string", «"lookup", "best fit"», "best fit").
+features: [Intl.RelativeTimeFormat]
+---*/
+
+const invalidOptions = [
+ null,
+ 1,
+ "",
+ "Lookup",
+ "LOOKUP",
+ "lookup\0",
+ "Best fit",
+ "BEST FIT",
+ "best\u00a0fit",
+];
+
+for (const invalidOption of invalidOptions) {
+ assert.throws(RangeError, function() {
+ new Intl.RelativeTimeFormat([], {"localeMatcher": invalidOption});
+ }, `${invalidOption} is an invalid localeMatcher option value`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-numberingSystem-invalid.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-numberingSystem-invalid.js
new file mode 100644
index 0000000000..4451d7be14
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-numberingSystem-invalid.js
@@ -0,0 +1,46 @@
+// Copyright 2018 André Bargull; Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat
+description: >
+ Checks error cases for the options argument to the RelativeTimeFormat constructor.
+info: |
+ InitializeRelativeTimeFormat (relativeTimeFormat, locales, options)
+
+ ...
+ 8. If numberingSystem is not undefined, then
+ a. If numberingSystem does not match the type sequence (from UTS 35 Unicode Locale Identifier, section 3.2), throw a RangeError exception.
+
+features: [Intl.RelativeTimeFormat]
+---*/
+
+assert.sameValue(typeof Intl.RelativeTimeFormat, "function");
+
+/*
+ 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.RelativeTimeFormat('en', {numberingSystem});
+ }, `new Intl.RelativeTimeFormat("en", {numberingSystem: "${numberingSystem}"}) throws RangeError`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-numberingSystem-valid.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-numberingSystem-valid.js
new file mode 100644
index 0000000000..aa9d5038f1
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-numberingSystem-valid.js
@@ -0,0 +1,29 @@
+// Copyright 2018 André Bargull; Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat
+description: Checks valid cases for the options argument to the RelativeTimeFormat constructor.
+features: [Intl.RelativeTimeFormat]
+---*/
+
+assert.sameValue(typeof Intl.RelativeTimeFormat, "function");
+
+const validNumberingSystemOptions = [
+ "abc",
+ "abcd",
+ "abcde",
+ "abcdef",
+ "abcdefg",
+ "abcdefgh",
+ "12345678",
+ "1234abcd",
+ "1234abcd-abc123",
+];
+
+for (const numberingSystem of validNumberingSystemOptions) {
+ const rtf = new Intl.RelativeTimeFormat("en", {numberingSystem});
+ assert.sameValue(rtf.resolvedOptions().numberingSystem, "latn");
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-numeric-invalid.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-numeric-invalid.js
new file mode 100644
index 0000000000..3b02910050
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-numeric-invalid.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-Intl.RelativeTimeFormat
+description: Checks handling of invalid value for the numeric option to the RelativeTimeFormat constructor.
+info: |
+ InitializeRelativeTimeFormat (relativeTimeFormat, locales, options)
+ 16. Let numeric be ? GetOption(options, "numeric", "string", «"always", "auto"», "always").
+features: [Intl.RelativeTimeFormat]
+---*/
+
+assert.sameValue(typeof Intl.RelativeTimeFormat, "function");
+
+const invalidOptions = [
+ null,
+ 1,
+ "",
+ "Always",
+ "ALWAYS",
+ "always\0",
+ "Auto",
+ "AUTO",
+ "auto\0",
+];
+
+for (const invalidOption of invalidOptions) {
+ assert.throws(RangeError, function() {
+ new Intl.RelativeTimeFormat([], {"numeric": invalidOption});
+ }, `${invalidOption} is an invalid numeric option value`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-numeric-valid.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-numeric-valid.js
new file mode 100644
index 0000000000..d831b94128
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-numeric-valid.js
@@ -0,0 +1,27 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat
+description: Checks handling of valid values for the numeric option to the RelativeTimeFormat constructor.
+info: |
+ InitializeRelativeTimeFormat (relativeTimeFormat, locales, options)
+ 16. Let numeric be ? GetOption(options, "numeric", "string", «"always", "auto"», "always").
+ 17. Set relativeTimeFormat.[[Numeric]] to numeric.
+features: [Intl.RelativeTimeFormat]
+---*/
+
+const validOptions = [
+ [undefined, "always"],
+ ["always", "always"],
+ ["auto", "auto"],
+ [{ toString() { return "auto"; } }, "auto"],
+];
+
+for (const [validOption, expected] of validOptions) {
+ const tf = new Intl.RelativeTimeFormat([], {"numeric": validOption});
+ const resolvedOptions = tf.resolvedOptions();
+ assert.sameValue(resolvedOptions.numeric, expected);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-order.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-order.js
new file mode 100644
index 0000000000..e8684f2121
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-order.js
@@ -0,0 +1,68 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat
+description: Checks the order of operations on the options argument to the RelativeTimeFormat constructor.
+info: |
+ InitializeRelativeTimeFormat (relativeTimeFormat, locales, options)
+ 7. Let matcher be ? GetOption(options, "localeMatcher", "string", «"lookup", "best fit"», "best fit").
+ 14. Let s be ? GetOption(options, "style", "string", «"long", "short", "narrow"», "long").
+ 16. Let numeric be ? GetOption(options, "numeric", "string", «"always", "auto"», "always").
+includes: [compareArray.js]
+features: [Intl.RelativeTimeFormat]
+---*/
+
+const callOrder = [];
+
+new Intl.RelativeTimeFormat([], {
+ get localeMatcher() {
+ callOrder.push("localeMatcher");
+ return {
+ toString() {
+ callOrder.push("localeMatcher toString");
+ return "best fit";
+ }
+ };
+ },
+ get style() {
+ callOrder.push("style");
+ return {
+ toString() {
+ callOrder.push("style toString");
+ return "long";
+ }
+ };
+ },
+ get numberingSystem() {
+ callOrder.push("numberingSystem");
+ return {
+ toString() {
+ callOrder.push("numberingSystem toString");
+ return "abc";
+ }
+ };
+ },
+ get numeric() {
+ callOrder.push("numeric");
+ return {
+ toString() {
+ callOrder.push("numeric toString");
+ return "always";
+ }
+ };
+ },
+});
+
+assert.compareArray(callOrder, [
+ "localeMatcher",
+ "localeMatcher toString",
+ "numberingSystem",
+ "numberingSystem toString",
+ "style",
+ "style toString",
+ "numeric",
+ "numeric toString",
+]);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-proto.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-proto.js
new file mode 100644
index 0000000000..c47805f02b
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-proto.js
@@ -0,0 +1,90 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat
+description: |
+ Checks that the RelativeTimeFormat constructor does not cause the
+ NumberFormat and PluralRules constructors to get properties off
+ Object.prototype through the options objects it creates.
+info: |
+ InitializeRelativeTimeFormat (relativeTimeFormat, locales, options)
+ 20. Let nfOptions be ObjectCreate(null).
+ 25. Let prOptions be ObjectCreate(null).
+features: [Intl.RelativeTimeFormat]
+---*/
+
+Object.defineProperties(Object.prototype, {
+ // NumberFormat & PluralRules
+ "localeMatcher": {
+ "get": function() {
+ throw new Test262Error("Should not call getter on Object.prototype: localeMatcher");
+ },
+ },
+
+ "minimumIntegerDigits": {
+ "get": function() {
+ throw new Test262Error("Should not call getter on Object.prototype: minimumIntegerDigits");
+ },
+ },
+
+ "minimumFractionDigits": {
+ "get": function() {
+ throw new Test262Error("Should not call getter on Object.prototype: minimumFractionDigits");
+ },
+ },
+
+ "maximumFractionDigits": {
+ "get": function() {
+ throw new Test262Error("Should not call getter on Object.prototype: maximumFractionDigits");
+ },
+ },
+
+ "minimumSignificantDigits": {
+ "get": function() {
+ throw new Test262Error("Should not call getter on Object.prototype: minimumSignificantDigits");
+ },
+ },
+
+ "maximumSignificantDigits": {
+ "get": function() {
+ throw new Test262Error("Should not call getter on Object.prototype: maximumSignificantDigits");
+ },
+ },
+
+ // NumberFormat
+ "style": {
+ "get": function() {
+ throw new Test262Error("Should not call getter on Object.prototype: style");
+ },
+ },
+
+ "currency": {
+ "get": function() {
+ throw new Test262Error("Should not call getter on Object.prototype: currency");
+ },
+ },
+
+ "currencyDisplay": {
+ "get": function() {
+ throw new Test262Error("Should not call getter on Object.prototype: currencyDisplay");
+ },
+ },
+
+ "useGrouping": {
+ "get": function() {
+ throw new Test262Error("Should not call getter on Object.prototype: useGrouping");
+ },
+ },
+
+ // PluralRules
+ "type": {
+ "get": function() {
+ throw new Test262Error("Should not call getter on Object.prototype: type");
+ },
+ },
+});
+
+new Intl.RelativeTimeFormat();
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-style-invalid.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-style-invalid.js
new file mode 100644
index 0000000000..7b397bed71
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-style-invalid.js
@@ -0,0 +1,34 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat
+description: Checks handling of invalid value for the style option to the RelativeTimeFormat constructor.
+info: |
+ InitializeRelativeTimeFormat (relativeTimeFormat, locales, options)
+ 14. Let s be ? GetOption(options, "style", "string", «"long", "short", "narrow"», "long").
+features: [Intl.RelativeTimeFormat]
+---*/
+
+const invalidOptions = [
+ null,
+ 1,
+ "",
+ "Long",
+ "LONG",
+ "long\0",
+ "Short",
+ "SHORT",
+ "short\0",
+ "Narrow",
+ "NARROW",
+ "narrow\0",
+];
+
+for (const invalidOption of invalidOptions) {
+ assert.throws(RangeError, function() {
+ new Intl.RelativeTimeFormat([], {"style": invalidOption});
+ }, `${invalidOption} is an invalid style option value`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-style-valid.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-style-valid.js
new file mode 100644
index 0000000000..1e53694ae7
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-style-valid.js
@@ -0,0 +1,28 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat
+description: Checks handling of valid values for the style option to the RelativeTimeFormat constructor.
+info: |
+ InitializeRelativeTimeFormat (relativeTimeFormat, locales, options)
+ 14. Let s be ? GetOption(options, "style", "string", «"long", "short", "narrow"», "long").
+ 15. Set relativeTimeFormat.[[Style]] to s.
+features: [Intl.RelativeTimeFormat]
+---*/
+
+const validOptions = [
+ [undefined, "long"],
+ ["long", "long"],
+ ["short", "short"],
+ ["narrow", "narrow"],
+ [{ toString() { return "narrow"; } }, "narrow"],
+];
+
+for (const [validOption, expected] of validOptions) {
+ const tf = new Intl.RelativeTimeFormat([], {"style": validOption});
+ const resolvedOptions = tf.resolvedOptions();
+ assert.sameValue(resolvedOptions.style, expected);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-throwing-getters.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-throwing-getters.js
new file mode 100644
index 0000000000..f06e962f64
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-throwing-getters.js
@@ -0,0 +1,119 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-InitializeRelativeTimeFormat
+description: Checks the propagation of exceptions from the options for the RelativeTimeFormat constructor.
+info: |
+ InitializeRelativeTimeFormat
+
+ 5. Let matcher be ? GetOption(options, "localeMatcher", "string", «"lookup", "best fit"», "best fit").
+ ...
+ 7. Let numberingSystem be ? GetOption(options, "numberingSystem", "string", undefined, undefined).
+ ...
+ 16. Let s be ? GetOption(options, "style", "string", «"long", "short", "narrow"», "long").
+ ...
+ 18. Let numeric be ? GetOption(options, "numeric", "string", «"always", "auto"», "always").
+
+ GetOption ( options, property, type, values, fallback )
+
+ 1. Let value be ? Get(options, property).
+ 2. If value is not undefined, then
+ a. Assert: type is "boolean" or "string".
+ b. If type is "boolean", then
+ i. Let value be ToBoolean(value).
+ c. If type is "string", then
+ i. Let value be ? ToString(value).
+ d. If values is not undefined, then
+ i. If values does not contain an element equal to value, throw a RangeError exception.
+ e. Return value.
+ 3. Else, return fallback.
+features: [Intl.RelativeTimeFormat]
+includes: [compareArray.js]
+---*/
+
+function CustomError() {}
+
+const o1 = {
+ get localeMatcher() {
+ throw new CustomError();
+ },
+ get numberingSystem() {
+ throw "should not get the numberingSystem option before localeMatcher";
+ },
+ get style() {
+ throw "should not get the style option before localeMatcher";
+ },
+ get numeric() {
+ throw "should not get the numeric option before localeMatcher";
+ }
+};
+
+const o2captures = [];
+const o2 = {
+ get localeMatcher() {
+ o2captures.push('localeMatcher');
+ },
+ get numberingSystem() {
+ throw new CustomError();
+ },
+ get style() {
+ throw "should not get the style option before numberingSystem";
+ },
+ get numeric() {
+ throw "should not get the numeric option before numberingSystem";
+ }
+};
+
+const o3captures = [];
+const o3 = {
+ get localeMatcher() {
+ o3captures.push('localeMatcher');
+ },
+ get numberingSystem() {
+ o3captures.push('numberingSystem');
+ },
+ get style() {
+ throw new CustomError();
+ },
+ get numeric() {
+ throw "should not get the numeric option before style";
+ }
+};
+
+const o4captures = [];
+const o4 = {
+ get localeMatcher() {
+ o4captures.push('localeMatcher');
+ },
+ get numberingSystem() {
+ o4captures.push('numberingSystem');
+ },
+ get style() {
+ o4captures.push('style');
+ },
+ get numeric() {
+ throw new CustomError();
+ }
+};
+
+assert.throws(CustomError, () => {
+ new Intl.RelativeTimeFormat("en", o1);
+}, `Exception from localeMatcher getter should be propagated`);
+
+assert.throws(CustomError, () => {
+ new Intl.RelativeTimeFormat("en", o2);
+}, `Exception from numberingSystem getter should be propagated`);
+assert.compareArray(o2captures, ['localeMatcher']);
+
+assert.throws(CustomError, () => {
+ new Intl.RelativeTimeFormat("en", o3);
+}, `Exception from style getter should be propagated`);
+assert.compareArray(o3captures, ['localeMatcher', 'numberingSystem']);
+
+assert.throws(CustomError, () => {
+ new Intl.RelativeTimeFormat("en", o4);
+}, `Exception from numeric getter should be propagated`);
+assert.compareArray(o4captures, ['localeMatcher', 'numberingSystem', 'style']);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-toobject-prototype.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-toobject-prototype.js
new file mode 100644
index 0000000000..2c352b2dd0
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-toobject-prototype.js
@@ -0,0 +1,37 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat
+description: Checks handling of non-object option arguments to the RelativeTimeFormat constructor.
+info: |
+ InitializeRelativeTimeFormat (relativeTimeFormat, locales, options)
+features: [Intl.RelativeTimeFormat]
+---*/
+
+Object.defineProperties(Object.prototype, {
+ "style": {
+ value: "short",
+ },
+ "numeric": {
+ value: "auto",
+ },
+})
+
+const optionsArguments = [
+ true,
+ "test",
+ 7,
+ Symbol(),
+];
+
+for (const options of optionsArguments) {
+ const rtf = new Intl.RelativeTimeFormat([], options);
+ const resolvedOptions = rtf.resolvedOptions();
+ assert.sameValue(resolvedOptions.style, "short",
+ `options argument ${String(options)} should yield the correct value for "style"`);
+ assert.sameValue(resolvedOptions.numeric, "auto",
+ `options argument ${String(options)} should yield the correct value for "numeric"`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-toobject.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-toobject.js
new file mode 100644
index 0000000000..872308d078
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-toobject.js
@@ -0,0 +1,28 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat
+description: Checks handling of non-object option arguments to the RelativeTimeFormat constructor.
+info: |
+ InitializeRelativeTimeFormat (relativeTimeFormat, locales, options)
+features: [Intl.RelativeTimeFormat]
+---*/
+
+const optionsArguments = [
+ true,
+ "test",
+ 7,
+ Symbol(),
+];
+
+for (const options of optionsArguments) {
+ const rtf = new Intl.RelativeTimeFormat([], options);
+ const resolvedOptions = rtf.resolvedOptions();
+ assert.sameValue(resolvedOptions.style, "long",
+ `options argument ${String(options)} should yield the correct value for "style"`);
+ assert.sameValue(resolvedOptions.numeric, "always",
+ `options argument ${String(options)} should yield the correct value for "numeric"`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-undefined.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-undefined.js
new file mode 100644
index 0000000000..1953dd1cdc
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/options-undefined.js
@@ -0,0 +1,40 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat
+description: Checks handling of non-object option arguments to the RelativeTimeFormat constructor.
+info: |
+ InitializeRelativeTimeFormat (relativeTimeFormat, locales, options)
+features: [Intl.RelativeTimeFormat]
+---*/
+
+Object.defineProperties(Object.prototype, {
+ style: {
+ get() {
+ throw new Error("Should not call style getter");
+ }
+ },
+ numeric: {
+ get() {
+ throw new Error("Should not call numeric getter");
+ }
+ },
+})
+
+const optionsArguments = [
+ [],
+ [[]],
+ [[], undefined],
+];
+
+for (const args of optionsArguments) {
+ const rtf = new Intl.RelativeTimeFormat(...args);
+ const resolvedOptions = rtf.resolvedOptions();
+ assert.sameValue(resolvedOptions.style, "long",
+ `Calling with ${args.length} empty arguments should yield the fallback value for "style"`);
+ assert.sameValue(resolvedOptions.numeric, "always",
+ `Calling with ${args.length} empty arguments should yield the fallback value for "numeric"`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/proto-from-ctor-realm.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/proto-from-ctor-realm.js
new file mode 100644
index 0000000000..5f71812c17
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/proto-from-ctor-realm.js
@@ -0,0 +1,59 @@
+// Copyright (C) 2019 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat
+description: Default [[Prototype]] value derived from realm of the NewTarget.
+info: |
+ Intl.RelativeTimeFormat ([ locales [ , options ]])
+
+ 1. If NewTarget is undefined, throw a TypeError exception.
+ 2. Let relativeTimeFormat be ? OrdinaryCreateFromConstructor(NewTarget, "%RelativeTimeFormatPrototype%", « ... »).
+ 3. Return ? InitializeRelativeTimeFormat(relativeTimeFormat, locales, options).
+
+ 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: [Intl.RelativeTimeFormat, cross-realm, Reflect, Symbol]
+---*/
+
+var other = $262.createRealm().global;
+var newTarget = new other.Function();
+var rtf;
+
+newTarget.prototype = undefined;
+rtf = Reflect.construct(Intl.RelativeTimeFormat, [], newTarget);
+assert.sameValue(Object.getPrototypeOf(rtf), other.Intl.RelativeTimeFormat.prototype, 'newTarget.prototype is undefined');
+
+newTarget.prototype = null;
+rtf = Reflect.construct(Intl.RelativeTimeFormat, [], newTarget);
+assert.sameValue(Object.getPrototypeOf(rtf), other.Intl.RelativeTimeFormat.prototype, 'newTarget.prototype is null');
+
+newTarget.prototype = true;
+rtf = Reflect.construct(Intl.RelativeTimeFormat, [], newTarget);
+assert.sameValue(Object.getPrototypeOf(rtf), other.Intl.RelativeTimeFormat.prototype, 'newTarget.prototype is a Boolean');
+
+newTarget.prototype = '';
+rtf = Reflect.construct(Intl.RelativeTimeFormat, [], newTarget);
+assert.sameValue(Object.getPrototypeOf(rtf), other.Intl.RelativeTimeFormat.prototype, 'newTarget.prototype is a String');
+
+newTarget.prototype = Symbol();
+rtf = Reflect.construct(Intl.RelativeTimeFormat, [], newTarget);
+assert.sameValue(Object.getPrototypeOf(rtf), other.Intl.RelativeTimeFormat.prototype, 'newTarget.prototype is a Symbol');
+
+newTarget.prototype = -1;
+rtf = Reflect.construct(Intl.RelativeTimeFormat, [], newTarget);
+assert.sameValue(Object.getPrototypeOf(rtf), other.Intl.RelativeTimeFormat.prototype, 'newTarget.prototype is a Number');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/shell.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/shell.js
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/subclassing.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/subclassing.js
new file mode 100644
index 0000000000..02b7b9fd2a
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/constructor/subclassing.js
@@ -0,0 +1,42 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat
+description: Checks that RelativeTimeFormat can be subclassed.
+info: |
+ Intl.RelativeTimeFormat ( [ locales [ , options ] ] )
+
+ 2. Let relativeTimeFormat be ! OrdinaryCreateFromConstructor(NewTarget, "%RelativeTimeFormatPrototype%", « [[InitializedRelativeTimeFormat]] »).
+
+features: [Intl.RelativeTimeFormat]
+---*/
+
+class CustomRelativeTimeFormat extends Intl.RelativeTimeFormat {
+ constructor(locales, options) {
+ super(locales, options);
+ this.isCustom = true;
+ }
+}
+
+const locale = "de";
+const value = 7;
+const unit = "day";
+
+const real_rtf = new Intl.RelativeTimeFormat(locale);
+assert.sameValue(real_rtf.isCustom, undefined, "Custom property");
+
+const custom_rtf = new CustomRelativeTimeFormat(locale);
+assert.sameValue(custom_rtf.isCustom, true, "Custom property");
+
+assert.sameValue(custom_rtf.format(value, unit),
+ real_rtf.format(value, unit),
+ "Direct call");
+
+assert.sameValue(Intl.RelativeTimeFormat.prototype.format.call(custom_rtf, value, unit),
+ Intl.RelativeTimeFormat.prototype.format.call(real_rtf, value, unit),
+ "Indirect call");
+
+assert.sameValue(Object.getPrototypeOf(custom_rtf), CustomRelativeTimeFormat.prototype, "Prototype");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/length.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/length.js
new file mode 100644
index 0000000000..752e277bc5
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/length.js
@@ -0,0 +1,24 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat
+description: >
+ Checks the "length" property of the RelativeTimeFormat constructor.
+info: |
+ 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 2019 Language Specification, 10th edition, clause 17, or successor.
+ The RelativeTimeFormat constructor is a standard built-in property of the Intl object.
+ 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]
+features: [Intl.RelativeTimeFormat]
+---*/
+
+verifyProperty(Intl.RelativeTimeFormat, "length", {
+ value: 0,
+ writable: false,
+ enumerable: false,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/name.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/name.js
new file mode 100644
index 0000000000..4dc57bf36f
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/name.js
@@ -0,0 +1,23 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat
+description: >
+ Checks the "name" property of the RelativeTimeFormat constructor.
+info: |
+ 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 2019 Language Specification, 10th edition, clause 17, or successor.
+ 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, this value is the name that is given to the function in this specification.
+ 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]
+features: [Intl.RelativeTimeFormat]
+---*/
+
+verifyProperty(Intl.RelativeTimeFormat, "name", {
+ value: "RelativeTimeFormat",
+ writable: false,
+ enumerable: false,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/prop-desc.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/prop-desc.js
new file mode 100644
index 0000000000..af3bcf0aef
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/prop-desc.js
@@ -0,0 +1,37 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat
+description: >
+ "RelativeTimeFormat" property of Intl.
+info: |
+ Intl.RelativeTimeFormat (...)
+
+ 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]
+features: [Intl.RelativeTimeFormat]
+---*/
+
+assert.sameValue(typeof Intl.RelativeTimeFormat, "function");
+
+verifyProperty(Intl, "RelativeTimeFormat", {
+ value: Intl.RelativeTimeFormat,
+ writable: true,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/prototype.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/prototype.js
new file mode 100644
index 0000000000..665269f330
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/prototype.js
@@ -0,0 +1,19 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat
+description: The prototype of the Intl.RelativeTimeFormat constructor is %FunctionPrototype%.
+info: |
+ 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 2019 Language Specification, 10th edition, clause 17, or successor.
+ Unless otherwise specified every built-in function object has the %FunctionPrototype% object as the initial value of its [[Prototype]] internal slot.
+features: [Intl.RelativeTimeFormat]
+---*/
+
+assert.sameValue(
+ Object.getPrototypeOf(Intl.RelativeTimeFormat),
+ Function.prototype,
+ "Object.getPrototypeOf(Intl.RelativeTimeFormat) equals the value of Function.prototype"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/shell.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/shell.js
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/basic.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/basic.js
new file mode 100644
index 0000000000..7cd949a718
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/basic.js
@@ -0,0 +1,23 @@
+// Copyright 2018 Google Inc., Igalia S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.supportedLocalesOf
+description: >
+ Tests that Intl.RelativeTimeFormat has a supportedLocalesOf property,
+ and it works as planned.
+features: [Intl.RelativeTimeFormat]
+---*/
+
+assert.sameValue(typeof Intl.RelativeTimeFormat.supportedLocalesOf, "function",
+ "supportedLocalesOf should be supported.");
+
+const defaultLocale = new Intl.RelativeTimeFormat().resolvedOptions().locale;
+const notSupported = 'zxx'; // "no linguistic content"
+const requestedLocales = [defaultLocale, notSupported];
+
+const supportedLocales = Intl.RelativeTimeFormat.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/RelativeTimeFormat/constructor/supportedLocalesOf/branding.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/branding.js
new file mode 100644
index 0000000000..fa89f86ba0
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/branding.js
@@ -0,0 +1,34 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.supportedLocalesOf
+description: >
+ Verifies there's no branding check for Intl.RelativeTimeFormat.supportedLocalesOf().
+info: |
+ Intl.RelativeTimeFormat.supportedLocalesOf ( locales [, options ])
+features: [Intl.RelativeTimeFormat]
+---*/
+
+const supportedLocalesOf = Intl.RelativeTimeFormat.supportedLocalesOf;
+
+assert.sameValue(typeof supportedLocalesOf, "function");
+
+const thisValues = [
+ undefined,
+ null,
+ true,
+ "",
+ Symbol(),
+ 1,
+ {},
+ Intl.RelativeTimeFormat,
+ Intl.RelativeTimeFormat.prototype,
+];
+
+for (const thisValue of thisValues) {
+ const result = supportedLocalesOf.call(thisValue);
+ assert.sameValue(Array.isArray(result), true);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/browser.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/browser.js
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/length.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/length.js
new file mode 100644
index 0000000000..2775259dc6
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/length.js
@@ -0,0 +1,24 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.supportedLocalesOf
+description: >
+ Checks the "length" property of Intl.RelativeTimeFormat.supportedLocalesOf().
+info: |
+ The value of the length property of the supportedLocalesOf method is 1.
+ 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 2019 Language Specification, 10th edition, clause 17, or successor.
+ Every built-in function object, including constructors, has a length property whose value is an integer.
+ Unless otherwise specified, the length property of a built-in function object has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.
+includes: [propertyHelper.js]
+features: [Intl.RelativeTimeFormat]
+---*/
+
+verifyProperty(Intl.RelativeTimeFormat.supportedLocalesOf, "length", {
+ value: 1,
+ writable: false,
+ enumerable: false,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/locales-invalid.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/locales-invalid.js
new file mode 100644
index 0000000000..57cfa4a3ee
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/locales-invalid.js
@@ -0,0 +1,22 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.supportedLocalesOf
+description: Checks error cases for the locales argument to the supportedLocalesOf function.
+info: |
+ Intl.RelativeTimeFormat.supportedLocalesOf ( locales [, options ])
+
+ 2. Let requestedLocales be CanonicalizeLocaleList(locales).
+includes: [testIntl.js]
+features: [Intl.RelativeTimeFormat]
+---*/
+
+assert.sameValue(typeof Intl.RelativeTimeFormat.supportedLocalesOf, "function",
+ "Should support Intl.RelativeTimeFormat.supportedLocalesOf.");
+
+for (const [locales, expectedError] of getInvalidLocaleArguments()) {
+ assert.throws(expectedError, () => Intl.RelativeTimeFormat.supportedLocalesOf(locales));
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/name.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/name.js
new file mode 100644
index 0000000000..34c59814fd
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/name.js
@@ -0,0 +1,23 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.supportedLocalesOf
+description: >
+ Checks the "name" property of Intl.RelativeTimeFormat.supportedLocalesOf().
+info: |
+ 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 2019 Language Specification, 10th edition, clause 17, or successor.
+ 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, this value is the name that is given to the function in this specification.
+ 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]
+features: [Intl.RelativeTimeFormat]
+---*/
+
+verifyProperty(Intl.RelativeTimeFormat.supportedLocalesOf, "name", {
+ value: "supportedLocalesOf",
+ writable: false,
+ enumerable: false,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/options-localeMatcher-invalid.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/options-localeMatcher-invalid.js
new file mode 100644
index 0000000000..854f9ca3d7
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/options-localeMatcher-invalid.js
@@ -0,0 +1,36 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.supportedLocalesOf
+description: Checks handling of invalid values for the localeMatcher option to the supportedLocalesOf function.
+info: |
+ SupportedLocales ( availableLocales, requestedLocales, options )
+
+ 1. If options is not undefined, then
+ b. Let matcher be ? GetOption(options, "localeMatcher", "string", «"lookup", "best fit"», "best fit").
+features: [Intl.RelativeTimeFormat]
+---*/
+
+assert.sameValue(typeof Intl.RelativeTimeFormat.supportedLocalesOf, "function",
+ "Should support Intl.RelativeTimeFormat.supportedLocalesOf.");
+
+const invalidOptions = [
+ null,
+ 1,
+ "",
+ "Lookup",
+ "LOOKUP",
+ "lookup\0",
+ "Best fit",
+ "BEST FIT",
+ "best\u00a0fit",
+];
+
+for (const invalidOption of invalidOptions) {
+ assert.throws(RangeError, function() {
+ Intl.RelativeTimeFormat.supportedLocalesOf([], {"localeMatcher": invalidOption});
+ }, `${invalidOption} is an invalid localeMatcher option value`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/options-null.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/options-null.js
new file mode 100644
index 0000000000..be15359c46
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/options-null.js
@@ -0,0 +1,22 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.supportedLocalesOf
+description: Checks handling of a null options argument to the supportedLocalesOf function.
+info: |
+ SupportedLocales ( availableLocales, requestedLocales, options )
+
+ 1. If options is not undefined, then
+ a. Let options be ? ToObject(options).
+features: [Intl.RelativeTimeFormat]
+---*/
+
+assert.sameValue(typeof Intl.RelativeTimeFormat.supportedLocalesOf, "function",
+ "Should support Intl.RelativeTimeFormat.supportedLocalesOf.");
+
+assert.throws(TypeError, function() {
+ Intl.RelativeTimeFormat.supportedLocalesOf([], null);
+}, "Should throw when passing null as the options argument");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/options-toobject.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/options-toobject.js
new file mode 100644
index 0000000000..036883f5ca
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/options-toobject.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.RelativeTimeFormat.supportedLocalesOf
+description: Checks handling of non-object options arguments to the supportedLocalesOf function.
+info: |
+ SupportedLocales ( availableLocales, requestedLocales, options )
+
+ 1. If options is not undefined, then
+ a. Let options be ? ToObject(options).
+features: [Intl.RelativeTimeFormat]
+---*/
+
+assert.sameValue(typeof Intl.RelativeTimeFormat.supportedLocalesOf, "function",
+ "Should support Intl.RelativeTimeFormat.supportedLocalesOf.");
+
+let called;
+Object.defineProperties(Object.prototype, {
+ "localeMatcher": {
+ get() {
+ ++called;
+ return "best fit";
+ }
+ }
+});
+
+const optionsArguments = [
+ true,
+ "test",
+ 7,
+ Symbol(),
+];
+
+for (const options of optionsArguments) {
+ called = 0;
+ const result = Intl.RelativeTimeFormat.supportedLocalesOf([], options);
+ assert.sameValue(Array.isArray(result), true, `Expected array from ${String(options)}`);
+ assert.sameValue(called, 1, `Expected one call from ${String(options)}`);
+}
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/options-undefined.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/options-undefined.js
new file mode 100644
index 0000000000..9a0832ec14
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/options-undefined.js
@@ -0,0 +1,28 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.supportedLocalesOf
+description: Checks handling of an undefined options argument to the supportedLocalesOf function.
+info: |
+ SupportedLocales ( availableLocales, requestedLocales, options )
+
+ 1. If options is not undefined, then
+ b. Let matcher be ? GetOption(options, "localeMatcher", "string", «"lookup", "best fit"», "best fit").
+features: [Intl.RelativeTimeFormat]
+---*/
+
+assert.sameValue(typeof Intl.RelativeTimeFormat.supportedLocalesOf, "function",
+ "Should support Intl.RelativeTimeFormat.supportedLocalesOf.");
+
+Object.defineProperties(Object.prototype, {
+ "localeMatcher": {
+ get() { throw new Error("Should not call localeMatcher getter"); }
+ }
+});
+
+assert.sameValue(Array.isArray(Intl.RelativeTimeFormat.supportedLocalesOf()), true, "No arguments");
+assert.sameValue(Array.isArray(Intl.RelativeTimeFormat.supportedLocalesOf([])), true, "One argument");
+assert.sameValue(Array.isArray(Intl.RelativeTimeFormat.supportedLocalesOf([], undefined)), true, "Two arguments");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/prop-desc.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/prop-desc.js
new file mode 100644
index 0000000000..ea80acf8a3
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/prop-desc.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-Intl.RelativeTimeFormat.supportedLocalesOf
+description: >
+ Checks the "supportedLocalesOf" property of the RelativeTimeFormat prototype object.
+info: |
+ Intl.RelativeTimeFormat.supportedLocalesOf ( locales [, options ])
+
+ 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 2019 Language Specification, 10th edition, clause 17, or successor.
+
+ 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]
+features: [Intl.RelativeTimeFormat]
+---*/
+
+assert.sameValue(
+ typeof Intl.RelativeTimeFormat.supportedLocalesOf,
+ "function",
+ "typeof Intl.RelativeTimeFormat.supportedLocalesOf is function"
+);
+
+verifyProperty(Intl.RelativeTimeFormat, "supportedLocalesOf", {
+ writable: true,
+ enumerable: false,
+ configurable: true,
+});
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/result-type.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/result-type.js
new file mode 100644
index 0000000000..8801c662c2
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/result-type.js
@@ -0,0 +1,35 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.supportedLocalesOf
+description: Verifies the type of the return value of Intl.RelativeTimeFormat.supportedLocalesOf().
+info: |
+ Intl.RelativeTimeFormat.supportedLocalesOf ( locales [, options ])
+includes: [propertyHelper.js]
+features: [Intl.RelativeTimeFormat]
+---*/
+
+const result = Intl.RelativeTimeFormat.supportedLocalesOf("en");
+assert.sameValue(Array.isArray(result), true,
+ "Array.isArray() should return true");
+assert.sameValue(Object.getPrototypeOf(result), Array.prototype,
+ "The prototype should be Array.prototype");
+assert.sameValue(Object.isExtensible(result), true,
+ "Object.isExtensible() should return true");
+
+assert.notSameValue(result.length, 0);
+for (let i = 0; i < result.length; ++i) {
+ verifyProperty(result, String(i), {
+ "writable": true,
+ "enumerable": true,
+ "configurable": true,
+ });
+}
+
+verifyProperty(result, "length", {
+ "enumerable": false,
+ "configurable": false,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/shell.js b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/shell.js
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/instance/browser.js b/js/src/tests/test262/intl402/RelativeTimeFormat/instance/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/instance/browser.js
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/instance/extensibility.js b/js/src/tests/test262/intl402/RelativeTimeFormat/instance/extensibility.js
new file mode 100644
index 0000000000..67ad4b9b83
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/instance/extensibility.js
@@ -0,0 +1,22 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat
+description: >
+ Intl.RelativeTimeFormat instance object extensibility
+info: |
+ 17 ECMAScript Standard Built-in Objects:
+
+ Unless specified otherwise, the [[Extensible]] internal slot
+ of a built-in object initially has the value true.
+features: [Intl.RelativeTimeFormat]
+---*/
+
+assert.sameValue(
+ Object.isExtensible(new Intl.RelativeTimeFormat()),
+ true,
+ "Object.isExtensible(new Intl.RelativeTimeFormat()) returns true"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/instance/prototype.js b/js/src/tests/test262/intl402/RelativeTimeFormat/instance/prototype.js
new file mode 100644
index 0000000000..f874db89f6
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/instance/prototype.js
@@ -0,0 +1,22 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat
+description: >
+ Intl.RelativeTimeFormat instance object is created from %RelativeTimeFormatPrototype%.
+info: |
+ Intl.RelativeTimeFormat ([ locales [ , options ]])
+
+ 2. Let relativeTimeFormat be ! OrdinaryCreateFromConstructor(NewTarget, "%RelativeTimeFormatPrototype%").
+features: [Intl.RelativeTimeFormat]
+---*/
+
+const value = new Intl.RelativeTimeFormat();
+assert.sameValue(
+ Object.getPrototypeOf(value),
+ Intl.RelativeTimeFormat.prototype,
+ "Object.getPrototypeOf(value) equals the value of Intl.RelativeTimeFormat.prototype"
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/instance/shell.js b/js/src/tests/test262/intl402/RelativeTimeFormat/instance/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/instance/shell.js
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/browser.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/browser.js
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/constructor/browser.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/constructor/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/constructor/browser.js
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/constructor/prop-desc.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/constructor/prop-desc.js
new file mode 100644
index 0000000000..b441c56413
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/constructor/prop-desc.js
@@ -0,0 +1,26 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.prototype.constructor
+description: Checks the "constructor" property of the RelativeTimeFormat prototype object.
+info: |
+ Intl.RelativeTimeFormat.prototype.constructor
+
+ The initial value of Intl.RelativeTimeFormat.prototype.constructor is %RelativeTimeFormat%.
+
+ 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 2019 Language Specification, 10th edition, clause 17, or successor.
+
+ 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]
+features: [Intl.RelativeTimeFormat]
+---*/
+
+verifyProperty(Intl.RelativeTimeFormat.prototype, "constructor", {
+ value: Intl.RelativeTimeFormat,
+ writable: true,
+ enumerable: false,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/constructor/shell.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/constructor/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/constructor/shell.js
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/branding.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/branding.js
new file mode 100644
index 0000000000..fa7f890ad7
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/branding.js
@@ -0,0 +1,28 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.prototype.format
+description: Verifies the branding check for the "format" function of the RelativeTimeFormat prototype object.
+info: |
+ Intl.RelativeTimeFormat.prototype.format( value, unit )
+
+ 2. If Type(relativeTimeFormat) is not Object or relativeTimeFormat does not have an [[InitializedRelativeTimeFormat]] internal slot whose value is true, throw a TypeError exception.
+features: [Intl.RelativeTimeFormat]
+---*/
+
+const format = Intl.RelativeTimeFormat.prototype.format;
+
+assert.sameValue(typeof format, "function");
+
+assert.throws(TypeError, () => format.call(undefined), "undefined");
+assert.throws(TypeError, () => format.call(null), "null");
+assert.throws(TypeError, () => format.call(true), "true");
+assert.throws(TypeError, () => format.call(""), "empty string");
+assert.throws(TypeError, () => format.call(Symbol()), "symbol");
+assert.throws(TypeError, () => format.call(1), "1");
+assert.throws(TypeError, () => format.call({}), "plain object");
+assert.throws(TypeError, () => format.call(Intl.RelativeTimeFormat), "Intl.RelativeTimeFormat");
+assert.throws(TypeError, () => format.call(Intl.RelativeTimeFormat.prototype), "Intl.RelativeTimeFormat.prototype");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/browser.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/browser.js
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/en-us-numeric-always.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/en-us-numeric-always.js
new file mode 100644
index 0000000000..2a567d6d01
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/en-us-numeric-always.js
@@ -0,0 +1,39 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.prototype.format
+description: Checks the behavior of Intl.RelativeTimeFormat.prototype.format() in English.
+features: [Intl.RelativeTimeFormat]
+locale: [en-US]
+---*/
+
+const units = [
+ "second",
+ "minute",
+ "hour",
+ "day",
+ "week",
+ "month",
+ "quarter",
+ "year",
+];
+
+const rtf = new Intl.RelativeTimeFormat("en-US");
+
+assert.sameValue(typeof rtf.format, "function", "format should be supported");
+
+for (const unit of units) {
+ assert.sameValue(rtf.format(1000, unit), `in 1,000 ${unit}s`);
+ assert.sameValue(rtf.format(10, unit), `in 10 ${unit}s`);
+ assert.sameValue(rtf.format(2, unit), `in 2 ${unit}s`);
+ assert.sameValue(rtf.format(1, unit), `in 1 ${unit}`);
+ assert.sameValue(rtf.format(0, unit), `in 0 ${unit}s`);
+ assert.sameValue(rtf.format(-0, unit), `0 ${unit}s ago`);
+ assert.sameValue(rtf.format(-1, unit), `1 ${unit} ago`);
+ assert.sameValue(rtf.format(-2, unit), `2 ${unit}s ago`);
+ assert.sameValue(rtf.format(-10, unit), `10 ${unit}s ago`);
+ assert.sameValue(rtf.format(-1000, unit), `1,000 ${unit}s ago`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/en-us-numeric-auto.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/en-us-numeric-auto.js
new file mode 100644
index 0000000000..ef84a32934
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/en-us-numeric-auto.js
@@ -0,0 +1,87 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.prototype.format
+description: Checks the behavior of Intl.RelativeTimeFormat.prototype.format() in English.
+features: [Intl.RelativeTimeFormat]
+locale: [en-US]
+---*/
+
+const units = [
+ "second",
+ "minute",
+ "hour",
+ "day",
+ "week",
+ "month",
+ "quarter",
+ "year",
+];
+
+const rtf = new Intl.RelativeTimeFormat("en-US", { "numeric": "auto" });
+
+assert.sameValue(typeof rtf.format, "function", "format should be supported");
+
+// https://www.unicode.org/cldr/charts/33/summary/en.html#1530
+const exceptions = {
+ "year": {
+ "-1": "last year",
+ "0": "this year",
+ "1": "next year",
+ },
+ "quarter": {
+ "-1": "last quarter",
+ "0": "this quarter",
+ "1": "next quarter",
+ },
+ "month": {
+ "-1": "last month",
+ "0": "this month",
+ "1": "next month",
+ },
+ "week": {
+ "-1": "last week",
+ "0": "this week",
+ "1": "next week",
+ },
+ "day": {
+ "-1": "yesterday",
+ "0": "today",
+ "1": "tomorrow",
+ },
+ "hour": {
+ "-1": "1 hour ago",
+ '0': 'this hour',
+ "1": "in 1 hour",
+ },
+ "minute": {
+ "-1": "1 minute ago",
+ '0': 'this minute',
+ "1": "in 1 minute",
+ },
+ "second": {
+ "-1": "1 second ago",
+ "0": "now",
+ "1": "in 1 second",
+ },
+};
+
+for (const unit of units) {
+ const expected = unit in exceptions
+ ? [exceptions[unit]["1"], exceptions[unit]["0"], exceptions[unit]["0"], exceptions[unit]["-1"]]
+ : [`in 1 ${unit}`, `in 0 ${unit}s`, `0 ${unit}s ago`, `1 ${unit} ago`];
+
+ assert.sameValue(rtf.format(1000, unit), `in 1,000 ${unit}s`);
+ assert.sameValue(rtf.format(10, unit), `in 10 ${unit}s`);
+ assert.sameValue(rtf.format(2, unit), `in 2 ${unit}s`);
+ assert.sameValue(rtf.format(1, unit), expected[0]);
+ assert.sameValue(rtf.format(0, unit), expected[1]);
+ assert.sameValue(rtf.format(-0, unit), expected[2]);
+ assert.sameValue(rtf.format(-1, unit), expected[3]);
+ assert.sameValue(rtf.format(-2, unit), `2 ${unit}s ago`);
+ assert.sameValue(rtf.format(-10, unit), `10 ${unit}s ago`);
+ assert.sameValue(rtf.format(-1000, unit), `1,000 ${unit}s ago`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/en-us-style-short.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/en-us-style-short.js
new file mode 100644
index 0000000000..869ce5036a
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/en-us-style-short.js
@@ -0,0 +1,42 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.prototype.format
+description: Checks the behavior of Intl.RelativeTimeFormat.prototype.format() in English.
+features: [Intl.RelativeTimeFormat]
+locale: [en-US]
+---*/
+
+const units = {
+ "second": ["sec."],
+ "minute": ["min."],
+ "hour": ["hr."],
+ "day": ["day", "days"],
+ "week": ["wk."],
+ "month": ["mo."],
+ "quarter": ["qtr.", "qtrs."],
+ "year": ["yr."],
+};
+
+const rtf = new Intl.RelativeTimeFormat("en-US", {
+ "style": "short",
+});
+
+assert.sameValue(typeof rtf.format, "function", "format should be supported");
+
+for (const [unitArgument, unitStrings] of Object.entries(units)) {
+ const [singular, plural = singular] = unitStrings;
+ assert.sameValue(rtf.format(1000, unitArgument), `in 1,000 ${plural}`);
+ assert.sameValue(rtf.format(10, unitArgument), `in 10 ${plural}`);
+ assert.sameValue(rtf.format(2, unitArgument), `in 2 ${plural}`);
+ assert.sameValue(rtf.format(1, unitArgument), `in 1 ${singular}`);
+ assert.sameValue(rtf.format(0, unitArgument), `in 0 ${plural}`);
+ assert.sameValue(rtf.format(-0, unitArgument), `0 ${plural} ago`);
+ assert.sameValue(rtf.format(-1, unitArgument), `1 ${singular} ago`);
+ assert.sameValue(rtf.format(-2, unitArgument), `2 ${plural} ago`);
+ assert.sameValue(rtf.format(-10, unitArgument), `10 ${plural} ago`);
+ assert.sameValue(rtf.format(-1000, unitArgument), `1,000 ${plural} ago`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/length.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/length.js
new file mode 100644
index 0000000000..e2f791593b
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/length.js
@@ -0,0 +1,23 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.prototype.format
+description: Checks the "length" property of Intl.RelativeTimeFormat.prototype.format().
+info: |
+ 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 2019 Language Specification, 10th edition, clause 17, or successor.
+ The RelativeTimeFormat constructor is a standard built-in property of the Intl object.
+ 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]
+features: [Intl.RelativeTimeFormat]
+---*/
+
+verifyProperty(Intl.RelativeTimeFormat.prototype.format, "length", {
+ value: 2,
+ writable: false,
+ enumerable: false,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/name.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/name.js
new file mode 100644
index 0000000000..d71d98d964
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/name.js
@@ -0,0 +1,22 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.prototype.format
+description: Checks the "name" property of Intl.RelativeTimeFormat.prototype.format().
+info: |
+ 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 2019 Language Specification, 10th edition, clause 17, or successor.
+ 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, this value is the name that is given to the function in this specification.
+ 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]
+features: [Intl.RelativeTimeFormat]
+---*/
+
+verifyProperty(Intl.RelativeTimeFormat.prototype.format, "name", {
+ value: "format",
+ writable: false,
+ enumerable: false,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/pl-pl-style-long.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/pl-pl-style-long.js
new file mode 100644
index 0000000000..596e1b914c
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/pl-pl-style-long.js
@@ -0,0 +1,71 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.prototype.format
+description: Checks the behavior of Intl.RelativeTimeFormat.prototype.format() in Polish.
+features: [Intl.RelativeTimeFormat]
+locale: [pl-PL]
+---*/
+
+function regular(s) {
+ return {
+ "many": s,
+ "few": s + "y",
+ "one": s + "ę",
+ }
+}
+
+// https://www.unicode.org/cldr/charts/33/summary/pl.html#1419
+const units = {
+ "second": regular("sekund"),
+ "minute": regular("minut"),
+ "hour": regular("godzin"),
+ "day": {
+ "many": "dni",
+ "few": "dni",
+ "one": "dzień",
+ },
+ "week": {
+ "many": "tygodni",
+ "few": "tygodnie",
+ "one": "tydzień",
+ },
+ "month": {
+ 1000: "miesięcy",
+ "many": "miesięcy",
+ "few": "miesiące",
+ "one": "miesiąc",
+ },
+ "quarter": {
+ "many": "kwartałów",
+ "few": "kwartały",
+ "one": "kwartał",
+ },
+ "year": {
+ "many": "lat",
+ "few": "lata",
+ "one": "rok",
+ },
+};
+
+const rtf = new Intl.RelativeTimeFormat("pl-PL", {
+ "style": "long",
+});
+
+assert.sameValue(typeof rtf.format, "function", "format should be supported");
+
+for (const [unitArgument, expected] of Object.entries(units)) {
+ assert.sameValue(rtf.format(1000, unitArgument), `za 1000 ${expected.many}`);
+ assert.sameValue(rtf.format(10, unitArgument), `za 10 ${expected.many}`);
+ assert.sameValue(rtf.format(2, unitArgument), `za 2 ${expected.few}`);
+ assert.sameValue(rtf.format(1, unitArgument), `za 1 ${expected.one}`);
+ assert.sameValue(rtf.format(0, unitArgument), `za 0 ${expected.many}`);
+ assert.sameValue(rtf.format(-0, unitArgument), `0 ${expected.many} temu`);
+ assert.sameValue(rtf.format(-1, unitArgument), `1 ${expected.one} temu`);
+ assert.sameValue(rtf.format(-2, unitArgument), `2 ${expected.few} temu`);
+ assert.sameValue(rtf.format(-10, unitArgument), `10 ${expected.many} temu`);
+ assert.sameValue(rtf.format(-1000, unitArgument), `1000 ${expected.many} temu`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/pl-pl-style-narrow.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/pl-pl-style-narrow.js
new file mode 100644
index 0000000000..12d32ce1aa
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/pl-pl-style-narrow.js
@@ -0,0 +1,62 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.prototype.format
+description: Checks the behavior of Intl.RelativeTimeFormat.prototype.format() in Polish.
+features: [Intl.RelativeTimeFormat]
+locale: [pl-PL]
+---*/
+
+function always(s) {
+ return {
+ "many": s,
+ "few": s,
+ "one": s,
+ }
+}
+
+// https://www.unicode.org/cldr/charts/33/summary/pl.html#1419
+const units = {
+ "second": always("s"),
+ "minute": always("min"),
+ "hour": always("g."),
+ "day": {
+ "many": "dni",
+ "few": "dni",
+ "one": "dzień",
+ },
+ "week": {
+ "many": "tyg.",
+ "few": "tyg.",
+ "one": "tydz.",
+ },
+ "month": always("mies."),
+ "quarter": always("kw."),
+ "year": {
+ "many": "lat",
+ "few": "lata",
+ "one": "rok",
+ },
+};
+
+const rtf = new Intl.RelativeTimeFormat("pl-PL", {
+ "style": "narrow",
+});
+
+assert.sameValue(typeof rtf.format, "function", "format should be supported");
+
+for (const [unitArgument, expected] of Object.entries(units)) {
+ assert.sameValue(rtf.format(1000, unitArgument), `za 1000 ${expected.many}`);
+ assert.sameValue(rtf.format(10, unitArgument), `za 10 ${expected.many}`);
+ assert.sameValue(rtf.format(2, unitArgument), `za 2 ${expected.few}`);
+ assert.sameValue(rtf.format(1, unitArgument), `za 1 ${expected.one}`);
+ assert.sameValue(rtf.format(0, unitArgument), `za 0 ${expected.many}`);
+ assert.sameValue(rtf.format(-0, unitArgument), `0 ${expected.many} temu`);
+ assert.sameValue(rtf.format(-1, unitArgument), `1 ${expected.one} temu`);
+ assert.sameValue(rtf.format(-2, unitArgument), `2 ${expected.few} temu`);
+ assert.sameValue(rtf.format(-10, unitArgument), `10 ${expected.many} temu`);
+ assert.sameValue(rtf.format(-1000, unitArgument), `1000 ${expected.many} temu`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/pl-pl-style-short.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/pl-pl-style-short.js
new file mode 100644
index 0000000000..27a4a972d8
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/pl-pl-style-short.js
@@ -0,0 +1,62 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.prototype.format
+description: Checks the behavior of Intl.RelativeTimeFormat.prototype.format() in Polish.
+features: [Intl.RelativeTimeFormat]
+locale: [pl-PL]
+---*/
+
+function always(s) {
+ return {
+ "many": s,
+ "few": s,
+ "one": s,
+ }
+}
+
+// https://www.unicode.org/cldr/charts/33/summary/pl.html#1419
+const units = {
+ "second": always("sek."),
+ "minute": always("min"),
+ "hour": always("godz."),
+ "day": {
+ "many": "dni",
+ "few": "dni",
+ "one": "dzień",
+ },
+ "week": {
+ "many": "tyg.",
+ "few": "tyg.",
+ "one": "tydz.",
+ },
+ "month": always("mies."),
+ "quarter": always("kw."),
+ "year": {
+ "many": "lat",
+ "few": "lata",
+ "one": "rok",
+ },
+};
+
+const rtf = new Intl.RelativeTimeFormat("pl-PL", {
+ "style": "short",
+});
+
+assert.sameValue(typeof rtf.format, "function", "format should be supported");
+
+for (const [unitArgument, expected] of Object.entries(units)) {
+ assert.sameValue(rtf.format(1000, unitArgument), `za 1000 ${expected.many}`);
+ assert.sameValue(rtf.format(10, unitArgument), `za 10 ${expected.many}`);
+ assert.sameValue(rtf.format(2, unitArgument), `za 2 ${expected.few}`);
+ assert.sameValue(rtf.format(1, unitArgument), `za 1 ${expected.one}`);
+ assert.sameValue(rtf.format(0, unitArgument), `za 0 ${expected.many}`);
+ assert.sameValue(rtf.format(-0, unitArgument), `0 ${expected.many} temu`);
+ assert.sameValue(rtf.format(-1, unitArgument), `1 ${expected.one} temu`);
+ assert.sameValue(rtf.format(-2, unitArgument), `2 ${expected.few} temu`);
+ assert.sameValue(rtf.format(-10, unitArgument), `10 ${expected.many} temu`);
+ assert.sameValue(rtf.format(-1000, unitArgument), `1000 ${expected.many} temu`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/prop-desc.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/prop-desc.js
new file mode 100644
index 0000000000..0b4b9f8572
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/prop-desc.js
@@ -0,0 +1,30 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.prototype.format
+description: Checks the "format" property of the RelativeTimeFormat prototype object.
+info: |
+ Intl.RelativeTimeFormat.prototype.format ()
+
+ 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 2019 Language Specification, 10th edition, clause 17, or successor.
+
+ 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]
+features: [Intl.RelativeTimeFormat]
+---*/
+
+assert.sameValue(
+ typeof Intl.RelativeTimeFormat.prototype.format,
+ "function",
+ "typeof Intl.RelativeTimeFormat.prototype.format is function"
+);
+
+verifyProperty(Intl.RelativeTimeFormat.prototype, "format", {
+ writable: true,
+ enumerable: false,
+ configurable: true,
+});
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/shell.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/shell.js
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/unit-invalid.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/unit-invalid.js
new file mode 100644
index 0000000000..186ff57ec9
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/unit-invalid.js
@@ -0,0 +1,55 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.prototype.format
+description: Checks the handling of invalid unit arguments to Intl.RelativeTimeFormat.prototype.format().
+info: |
+ SingularRelativeTimeUnit ( unit )
+
+ 10. If unit is not one of "second", "minute", "hour", "day", "week", "month", "quarter", "year", throw a RangeError exception.
+
+features: [Intl.RelativeTimeFormat]
+---*/
+
+const rtf = new Intl.RelativeTimeFormat("en-US");
+
+assert.sameValue(typeof rtf.format, "function");
+
+const values = [
+ undefined,
+ null,
+ true,
+ 1,
+ 0.1,
+ NaN,
+ {},
+ "",
+ "SECOND",
+ "MINUTE",
+ "HOUR",
+ "DAY",
+ "WEEK",
+ "MONTH",
+ "QUARTER",
+ "YEAR",
+ "decade",
+ "decades",
+ "century",
+ "centuries",
+ "millisecond",
+ "milliseconds",
+ "microsecond",
+ "microseconds",
+ "nanosecond",
+ "nanoseconds",
+];
+
+for (const value of values) {
+ assert.throws(RangeError, () => rtf.format(0, value), String(value));
+}
+
+const symbol = Symbol();
+assert.throws(TypeError, () => rtf.format(0, symbol), "symbol");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/unit-plural.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/unit-plural.js
new file mode 100644
index 0000000000..faf8e37ecc
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/unit-plural.js
@@ -0,0 +1,42 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.prototype.format
+description: Checks the handling of plural unit arguments to Intl.RelativeTimeFormat.prototype.format().
+info: |
+ SingularRelativeTimeUnit ( unit )
+
+ 2. If unit is "seconds", return "second".
+ 3. If unit is "minutes", return "minute".
+ 4. If unit is "hours", return "hour".
+ 5. If unit is "days", return "day".
+ 6. If unit is "weeks", return "week".
+ 7. If unit is "months", return "month".
+ 8. If unit is "quarters", return "quarter".
+ 9. If unit is "years", return "year".
+
+features: [Intl.RelativeTimeFormat]
+---*/
+
+const rtf = new Intl.RelativeTimeFormat("en-US");
+
+assert.sameValue(typeof rtf.format, "function", "format should be supported");
+
+const units = [
+ "second",
+ "minute",
+ "hour",
+ "day",
+ "week",
+ "month",
+ "quarter",
+ "year",
+];
+
+for (const unit of units) {
+ assert.sameValue(rtf.format(3, unit + "s"), rtf.format(3, unit),
+ `Should support unit ${unit}s as a synonym for ${unit}`)
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/value-non-finite.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/value-non-finite.js
new file mode 100644
index 0000000000..77827e4c68
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/value-non-finite.js
@@ -0,0 +1,38 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.prototype.format
+description: Checks the handling of invalid value arguments to Intl.RelativeTimeFormat.prototype.format().
+info: |
+ Intl.RelativeTimeFormat.prototype.format( value, unit )
+
+ 3. Let value be ? ToNumber(value).
+
+ PartitionRelativeTimePattern ( relativeTimeFormat, value, unit )
+
+ 4. If isFinite(value) is false, then throw a RangeError exception.
+
+features: [Intl.RelativeTimeFormat]
+---*/
+
+const rtf = new Intl.RelativeTimeFormat("en-US");
+
+assert.sameValue(typeof rtf.format, "function", "format should be supported");
+
+const values = [
+ [undefined, "undefined"],
+ [NaN, "NaN"],
+ [Infinity, "Infinity"],
+ [-Infinity, "-Infinity"],
+ ["string", '"string"'],
+ [{}, "empty object"],
+ [{ toString() { return NaN; }, valueOf: undefined }, "object with toString"],
+ [{ valueOf() { return NaN; }, toString: undefined }, "object with valueOf"],
+];
+
+for (const [value, name] of values) {
+ assert.throws(RangeError, () => rtf.format(value, "second"), name);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/value-symbol.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/value-symbol.js
new file mode 100644
index 0000000000..83b1617f29
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/value-symbol.js
@@ -0,0 +1,22 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.prototype.format
+description: Checks the handling of invalid value arguments to Intl.RelativeTimeFormat.prototype.format().
+info: |
+ Intl.RelativeTimeFormat.prototype.format( value, unit )
+
+ 3. Let value be ? ToNumber(value).
+
+features: [Intl.RelativeTimeFormat]
+---*/
+
+const rtf = new Intl.RelativeTimeFormat("en-US");
+
+assert.sameValue(typeof rtf.format, "function", "format should be supported");
+
+const symbol = Symbol();
+assert.throws(TypeError, () => rtf.format(symbol, "second"));
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/value-tonumber.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/value-tonumber.js
new file mode 100644
index 0000000000..2ca5ae6100
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/format/value-tonumber.js
@@ -0,0 +1,40 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.prototype.format
+description: Checks the handling of non-number value arguments to Intl.RelativeTimeFormat.prototype.format().
+info: |
+ Intl.RelativeTimeFormat.prototype.format( value, unit )
+
+ 3. Let value be ? ToNumber(value).
+
+features: [Intl.RelativeTimeFormat]
+---*/
+
+const rtf = new Intl.RelativeTimeFormat("en-US");
+
+assert.sameValue(typeof rtf.format, "function", "format should be supported");
+
+const values = [
+ [null, 0],
+
+ [true, 1],
+ [false, 0],
+
+ ["5", 5],
+ ["-5", -5],
+ ["0", 0],
+ ["-0", -0],
+ [" 6 ", 6],
+
+ [{ toString() { return 7; } }, 7, "object with toString"],
+ [{ valueOf() { return 7; } }, 7, "object with valueOf"],
+];
+
+for (const [input, number, name = String(input)] of values) {
+ assert.sameValue(rtf.format(input, "second"), rtf.format(number, "second"),
+ `Should treat ${name} as ${number}`)
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/branding.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/branding.js
new file mode 100644
index 0000000000..fa5f00ad62
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/branding.js
@@ -0,0 +1,28 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.prototype.formatToParts
+description: Verifies the branding check for the "formatToParts" function of the RelativeTimeFormat prototype object.
+info: |
+ Intl.RelativeTimeFormat.prototype.formatToParts( value, unit )
+
+ 2. If Type(relativeTimeFormat) is not Object or relativeTimeFormat does not have an [[InitializedRelativeTimeFormat]] internal slot whose value is true, throw a TypeError exception.
+features: [Intl.RelativeTimeFormat]
+---*/
+
+const formatToParts = Intl.RelativeTimeFormat.prototype.formatToParts;
+
+assert.sameValue(typeof formatToParts, "function");
+
+assert.throws(TypeError, () => formatToParts.call(undefined), "undefined");
+assert.throws(TypeError, () => formatToParts.call(null), "null");
+assert.throws(TypeError, () => formatToParts.call(true), "true");
+assert.throws(TypeError, () => formatToParts.call(""), "empty string");
+assert.throws(TypeError, () => formatToParts.call(Symbol()), "symbol");
+assert.throws(TypeError, () => formatToParts.call(1), "1");
+assert.throws(TypeError, () => formatToParts.call({}), "plain object");
+assert.throws(TypeError, () => formatToParts.call(Intl.RelativeTimeFormat), "Intl.RelativeTimeFormat");
+assert.throws(TypeError, () => formatToParts.call(Intl.RelativeTimeFormat.prototype), "Intl.RelativeTimeFormat.prototype");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/browser.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/browser.js
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/en-us-numeric-always.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/en-us-numeric-always.js
new file mode 100644
index 0000000000..b10ee9a701
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/en-us-numeric-always.js
@@ -0,0 +1,107 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.prototype.formatToParts
+description: Checks the behavior of Intl.RelativeTimeFormat.prototype.formatToParts() in English.
+features: [Intl.RelativeTimeFormat]
+locale: [en-US]
+---*/
+
+function verifyFormatParts(actual, expected, message) {
+ assert.sameValue(actual.length, expected.length, `${message}: length`);
+
+ for (let i = 0; i < actual.length; ++i) {
+ assert.sameValue(actual[i].type, expected[i].type, `${message}: parts[${i}].type`);
+ assert.sameValue(actual[i].value, expected[i].value, `${message}: parts[${i}].value`);
+ assert.sameValue(actual[i].unit, expected[i].unit, `${message}: parts[${i}].unit`);
+ }
+}
+
+const units = [
+ "second",
+ "minute",
+ "hour",
+ "day",
+ "week",
+ "month",
+ "quarter",
+ "year",
+];
+
+const rtf = new Intl.RelativeTimeFormat("en-US");
+
+assert.sameValue(typeof rtf.formatToParts, "function", "formatToParts should be supported");
+
+for (const unit of units) {
+ verifyFormatParts(rtf.formatToParts(1000, unit), [
+ { "type": "literal", "value": "in " },
+ { "type": "integer", "value": "1", "unit": unit },
+ { "type": "group", "value": ",", "unit": unit },
+ { "type": "integer", "value": "000", "unit": unit },
+ { "type": "literal", "value": ` ${unit}s` },
+ ], `formatToParts(1000, ${unit})`);
+
+ verifyFormatParts(rtf.formatToParts(10, unit), [
+ { "type": "literal", "value": "in " },
+ { "type": "integer", "value": "10", "unit": unit },
+ { "type": "literal", "value": ` ${unit}s` },
+ ], `formatToParts(10, ${unit})`);
+
+ verifyFormatParts(rtf.formatToParts(2, unit), [
+ { "type": "literal", "value": "in " },
+ { "type": "integer", "value": "2", "unit": unit },
+ { "type": "literal", "value": ` ${unit}s` },
+ ], `formatToParts(2, ${unit})`);
+
+ verifyFormatParts(rtf.formatToParts(1, unit), [
+ { "type": "literal", "value": "in " },
+ { "type": "integer", "value": "1", "unit": unit },
+ { "type": "literal", "value": ` ${unit}` },
+ ], `formatToParts(1, ${unit})`);
+
+ verifyFormatParts(rtf.formatToParts(0, unit), [
+ { "type": "literal", "value": "in " },
+ { "type": "integer", "value": "0", "unit": unit },
+ { "type": "literal", "value": ` ${unit}s` },
+ ], `formatToParts(0, ${unit})`);
+
+ verifyFormatParts(rtf.formatToParts(-0, unit), [
+ { "type": "integer", "value": "0", "unit": unit },
+ { "type": "literal", "value": ` ${unit}s ago` },
+ ], `formatToParts(-0, ${unit})`);
+
+ verifyFormatParts(rtf.formatToParts(-1, unit), [
+ { "type": "integer", "value": "1", "unit": unit },
+ { "type": "literal", "value": ` ${unit} ago` },
+ ], `formatToParts(-1, ${unit})`);
+
+ verifyFormatParts(rtf.formatToParts(-2, unit), [
+ { "type": "integer", "value": "2", "unit": unit },
+ { "type": "literal", "value": ` ${unit}s ago` },
+ ], `formatToParts(-2, ${unit})`);
+
+ verifyFormatParts(rtf.formatToParts(-10, unit), [
+ { "type": "integer", "value": "10", "unit": unit },
+ { "type": "literal", "value": ` ${unit}s ago` },
+ ], `formatToParts(-10, ${unit})`);
+
+ verifyFormatParts(rtf.formatToParts(-1000, unit), [
+ { "type": "integer", "value": "1", "unit": unit },
+ { "type": "group", "value": ",", "unit": unit },
+ { "type": "integer", "value": "000", "unit": unit },
+ { "type": "literal", "value": ` ${unit}s ago` },
+ ], `formatToParts(-1000, ${unit})`);
+
+ verifyFormatParts(rtf.formatToParts(123456.78, unit), [
+ { "type": "literal", "value": "in " },
+ { "type": "integer", "value": "123", "unit": unit },
+ { "type": "group", "value": ",", "unit": unit },
+ { "type": "integer", "value": "456", "unit": unit },
+ { "type": "decimal", "value": ".", "unit": unit },
+ { "type": "fraction", "value": "78", "unit": unit },
+ { "type": "literal", "value": ` ${unit}s` },
+ ], `formatToParts(123456.78, ${unit})`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/en-us-numeric-auto.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/en-us-numeric-auto.js
new file mode 100644
index 0000000000..fdf9ab6487
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/en-us-numeric-auto.js
@@ -0,0 +1,156 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.prototype.formatToParts
+description: Checks the behavior of Intl.RelativeTimeFormat.prototype.formatToParts() in English.
+features: [Intl.RelativeTimeFormat]
+locale: [en-US]
+---*/
+
+function verifyFormatParts(actual, expected, message) {
+ assert.sameValue(actual.length, expected.length, `${message}: length`);
+
+ for (let i = 0; i < actual.length; ++i) {
+ assert.sameValue(actual[i].type, expected[i].type, `${message}: parts[${i}].type`);
+ assert.sameValue(actual[i].value, expected[i].value, `${message}: parts[${i}].value`);
+ assert.sameValue(actual[i].unit, expected[i].unit, `${message}: parts[${i}].unit`);
+ }
+}
+
+function expected(key, unit, default_) {
+ // https://www.unicode.org/cldr/charts/33/summary/en.html#1530
+ const exceptions = {
+ "year": {
+ "-1": "last year",
+ "0": "this year",
+ "1": "next year",
+ },
+ "quarter": {
+ "-1": "last quarter",
+ "0": "this quarter",
+ "1": "next quarter",
+ },
+ "month": {
+ "-1": "last month",
+ "0": "this month",
+ "1": "next month",
+ },
+ "week": {
+ "-1": "last week",
+ "0": "this week",
+ "1": "next week",
+ },
+ "day": {
+ "-1": "yesterday",
+ "0": "today",
+ "1": "tomorrow",
+ },
+ "hour": {
+ "0": "this hour",
+ },
+ "minute": {
+ "0": "this minute",
+ },
+ "second": {
+ "0": "now",
+ },
+ };
+
+ const exception = exceptions[unit] || {};
+ if (key in exception) {
+ return [
+ { "type": "literal", "value": exception[key] },
+ ]
+ }
+
+ return default_;
+}
+
+const units = [
+ "second",
+ "minute",
+ "hour",
+ "day",
+ "week",
+ "month",
+ "quarter",
+ "year",
+];
+
+const rtf = new Intl.RelativeTimeFormat("en-US", { "numeric": "auto" });
+
+assert.sameValue(typeof rtf.formatToParts, "function", "formatToParts should be supported");
+
+for (const unit of units) {
+ verifyFormatParts(rtf.formatToParts(1000, unit), [
+ { "type": "literal", "value": "in " },
+ { "type": "integer", "value": "1", "unit": unit },
+ { "type": "group", "value": ",", "unit": unit },
+ { "type": "integer", "value": "000", "unit": unit },
+ { "type": "literal", "value": ` ${unit}s` },
+ ], `formatToParts(1000, ${unit})`);
+
+ verifyFormatParts(rtf.formatToParts(10, unit), [
+ { "type": "literal", "value": "in " },
+ { "type": "integer", "value": "10", "unit": unit },
+ { "type": "literal", "value": ` ${unit}s` },
+ ], `formatToParts(10, ${unit})`);
+
+ verifyFormatParts(rtf.formatToParts(2, unit), [
+ { "type": "literal", "value": "in " },
+ { "type": "integer", "value": "2", "unit": unit },
+ { "type": "literal", "value": ` ${unit}s` },
+ ], `formatToParts(2, ${unit})`);
+
+ verifyFormatParts(rtf.formatToParts(1, unit), expected("1", unit, [
+ { "type": "literal", "value": "in " },
+ { "type": "integer", "value": "1", "unit": unit },
+ { "type": "literal", "value": ` ${unit}` },
+ ]), `formatToParts(1, ${unit})`);
+
+ verifyFormatParts(rtf.formatToParts(0, unit), expected("0", unit, [
+ { "type": "literal", "value": "in " },
+ { "type": "integer", "value": "0", "unit": unit },
+ { "type": "literal", "value": ` ${unit}s` },
+ ]), `formatToParts(0, ${unit})`);
+
+ verifyFormatParts(rtf.formatToParts(-0, unit), expected("0", unit, [
+ { "type": "integer", "value": "0", "unit": unit },
+ { "type": "literal", "value": ` ${unit}s ago` },
+ ]), `formatToParts(-0, ${unit})`);
+
+ verifyFormatParts(rtf.formatToParts(-1, unit), expected("-1", unit, [
+ { "type": "integer", "value": "1", "unit": unit },
+ { "type": "literal", "value": ` ${unit} ago` },
+ ]), `formatToParts(-1, ${unit})`);
+
+ verifyFormatParts(rtf.formatToParts(-2, unit), [
+ { "type": "integer", "value": "2", "unit": unit },
+ { "type": "literal", "value": ` ${unit}s ago` },
+ ], `formatToParts(-2, ${unit})`);
+
+ verifyFormatParts(rtf.formatToParts(-10, unit), [
+ { "type": "integer", "value": "10", "unit": unit },
+ { "type": "literal", "value": ` ${unit}s ago` },
+ ], `formatToParts(-10, ${unit})`);
+
+ verifyFormatParts(rtf.formatToParts(-1000, unit), [
+ { "type": "integer", "value": "1", "unit": unit },
+ { "type": "group", "value": ",", "unit": unit },
+ { "type": "integer", "value": "000", "unit": unit },
+ { "type": "literal", "value": ` ${unit}s ago` },
+ ], `formatToParts(-1000, ${unit})`);
+
+ verifyFormatParts(rtf.formatToParts(123456.78, unit), [
+ { "type": "literal", "value": "in " },
+ { "type": "integer", "value": "123", "unit": unit },
+ { "type": "group", "value": ",", "unit": unit },
+ { "type": "integer", "value": "456", "unit": unit },
+ { "type": "decimal", "value": ".", "unit": unit },
+ { "type": "fraction", "value": "78", "unit": unit },
+ { "type": "literal", "value": ` ${unit}s` },
+ ], `formatToParts(123456.78, ${unit})`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/en-us-style-short.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/en-us-style-short.js
new file mode 100644
index 0000000000..812a66d8c2
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/en-us-style-short.js
@@ -0,0 +1,111 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.prototype.formatToParts
+description: Checks the behavior of Intl.RelativeTimeFormat.prototype.formatToParts() in English.
+features: [Intl.RelativeTimeFormat]
+locale: [en-US]
+---*/
+
+function verifyFormatParts(actual, expected, message) {
+ assert.sameValue(actual.length, expected.length, `${message}: length`);
+
+ for (let i = 0; i < actual.length; ++i) {
+ assert.sameValue(actual[i].type, expected[i].type, `${message}: parts[${i}].type`);
+ assert.sameValue(actual[i].value, expected[i].value, `${message}: parts[${i}].value`);
+ assert.sameValue(actual[i].unit, expected[i].unit, `${message}: parts[${i}].unit`);
+ }
+}
+
+const units = {
+ "second": ["sec."],
+ "minute": ["min."],
+ "hour": ["hr."],
+ "day": ["day", "days"],
+ "week": ["wk."],
+ "month": ["mo."],
+ "quarter": ["qtr.", "qtrs."],
+ "year": ["yr."],
+};
+
+const rtf = new Intl.RelativeTimeFormat("en-US", {
+ "style": "short",
+});
+
+assert.sameValue(typeof rtf.formatToParts, "function", "formatToParts should be supported");
+
+for (const [unitArgument, unitStrings] of Object.entries(units)) {
+ const [singular, plural = singular] = unitStrings;
+
+ verifyFormatParts(rtf.formatToParts(1000, unitArgument), [
+ { "type": "literal", "value": "in " },
+ { "type": "integer", "value": "1", "unit": unitArgument },
+ { "type": "group", "value": ",", "unit": unitArgument },
+ { "type": "integer", "value": "000", "unit": unitArgument },
+ { "type": "literal", "value": ` ${plural}` },
+ ], `formatToParts(1000, ${unitArgument})`);
+
+ verifyFormatParts(rtf.formatToParts(10, unitArgument), [
+ { "type": "literal", "value": "in " },
+ { "type": "integer", "value": "10", "unit": unitArgument },
+ { "type": "literal", "value": ` ${plural}` },
+ ], `formatToParts(10, ${unitArgument})`);
+
+ verifyFormatParts(rtf.formatToParts(2, unitArgument), [
+ { "type": "literal", "value": "in " },
+ { "type": "integer", "value": "2", "unit": unitArgument },
+ { "type": "literal", "value": ` ${plural}` },
+ ], `formatToParts(2, ${unitArgument})`);
+
+ verifyFormatParts(rtf.formatToParts(1, unitArgument), [
+ { "type": "literal", "value": "in " },
+ { "type": "integer", "value": "1", "unit": unitArgument },
+ { "type": "literal", "value": ` ${singular}` },
+ ], `formatToParts(1, ${unitArgument})`);
+
+ verifyFormatParts(rtf.formatToParts(0, unitArgument), [
+ { "type": "literal", "value": "in " },
+ { "type": "integer", "value": "0", "unit": unitArgument },
+ { "type": "literal", "value": ` ${plural}` },
+ ], `formatToParts(0, ${unitArgument})`);
+
+ verifyFormatParts(rtf.formatToParts(-0, unitArgument), [
+ { "type": "integer", "value": "0", "unit": unitArgument },
+ { "type": "literal", "value": ` ${plural} ago` },
+ ], `formatToParts(-0, ${unitArgument})`);
+
+ verifyFormatParts(rtf.formatToParts(-1, unitArgument), [
+ { "type": "integer", "value": "1", "unit": unitArgument },
+ { "type": "literal", "value": ` ${singular} ago` },
+ ], `formatToParts(-1, ${unitArgument})`);
+
+ verifyFormatParts(rtf.formatToParts(-2, unitArgument), [
+ { "type": "integer", "value": "2", "unit": unitArgument },
+ { "type": "literal", "value": ` ${plural} ago` },
+ ], `formatToParts(-2, ${unitArgument})`);
+
+ verifyFormatParts(rtf.formatToParts(-10, unitArgument), [
+ { "type": "integer", "value": "10", "unit": unitArgument },
+ { "type": "literal", "value": ` ${plural} ago` },
+ ], `formatToParts(-10, ${unitArgument})`);
+
+ verifyFormatParts(rtf.formatToParts(-1000, unitArgument), [
+ { "type": "integer", "value": "1", "unit": unitArgument },
+ { "type": "group", "value": ",", "unit": unitArgument },
+ { "type": "integer", "value": "000", "unit": unitArgument },
+ { "type": "literal", "value": ` ${plural} ago` },
+ ], `formatToParts(-1000, ${unitArgument})`);
+
+ verifyFormatParts(rtf.formatToParts(123456.78, unitArgument), [
+ { "type": "literal", "value": "in " },
+ { "type": "integer", "value": "123", "unit": unitArgument },
+ { "type": "group", "value": ",", "unit": unitArgument },
+ { "type": "integer", "value": "456", "unit": unitArgument },
+ { "type": "decimal", "value": ".", "unit": unitArgument },
+ { "type": "fraction", "value": "78", "unit": unitArgument },
+ { "type": "literal", "value": ` ${plural}` },
+ ], `formatToParts(123456.78, ${unitArgument})`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/length.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/length.js
new file mode 100644
index 0000000000..c6badcd71a
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/length.js
@@ -0,0 +1,23 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.prototype.formatToParts
+description: Checks the "length" property of Intl.RelativeTimeFormat.prototype.formatToParts().
+info: |
+ 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 2019 Language Specification, 10th edition, clause 17, or successor.
+ The RelativeTimeFormat constructor is a standard built-in property of the Intl object.
+ 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]
+features: [Intl.RelativeTimeFormat]
+---*/
+
+verifyProperty(Intl.RelativeTimeFormat.prototype.formatToParts, "length", {
+ value: 2,
+ writable: false,
+ enumerable: false,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/name.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/name.js
new file mode 100644
index 0000000000..df10bfe3a7
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/name.js
@@ -0,0 +1,22 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.prototype.formatToParts
+description: Checks the "name" property of Intl.RelativeTimeFormat.prototype.formatToParts().
+info: |
+ 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 2019 Language Specification, 10th edition, clause 17, or successor.
+ 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, this value is the name that is given to the function in this specification.
+ 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]
+features: [Intl.RelativeTimeFormat]
+---*/
+
+verifyProperty(Intl.RelativeTimeFormat.prototype.formatToParts, "name", {
+ value: "formatToParts",
+ writable: false,
+ enumerable: false,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/pl-pl-style-long.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/pl-pl-style-long.js
new file mode 100644
index 0000000000..0a10fe68e6
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/pl-pl-style-long.js
@@ -0,0 +1,141 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.prototype.format
+description: Checks the behavior of Intl.RelativeTimeFormat.prototype.format() in Polish.
+features: [Intl.RelativeTimeFormat]
+locale: [pl-PL]
+---*/
+
+function verifyFormatParts(actual, expected, message) {
+ assert.sameValue(actual.length, expected.length, `${message}: length`);
+
+ for (let i = 0; i < actual.length; ++i) {
+ assert.sameValue(actual[i].type, expected[i].type, `${message}: parts[${i}].type`);
+ assert.sameValue(actual[i].value, expected[i].value, `${message}: parts[${i}].value`);
+ assert.sameValue(actual[i].unit, expected[i].unit, `${message}: parts[${i}].unit`);
+ }
+}
+
+function regular(s) {
+ return {
+ "many": s,
+ "few": s + "y",
+ "one": s + "ę",
+ "other": s + "y",
+ }
+}
+
+// https://www.unicode.org/cldr/charts/33/summary/pl.html#1419
+const units = {
+ "second": regular("sekund"),
+ "minute": regular("minut"),
+ "hour": regular("godzin"),
+ "day": {
+ "many": "dni",
+ "few": "dni",
+ "one": "dzień",
+ "other": "dnia",
+ },
+ "week": {
+ "many": "tygodni",
+ "few": "tygodnie",
+ "one": "tydzień",
+ "other": "tygodnia",
+ },
+ "month": {
+ 1000: "miesięcy",
+ "many": "miesięcy",
+ "few": "miesiące",
+ "one": "miesiąc",
+ "other": "miesiąca",
+ },
+ "quarter": {
+ "many": "kwartałów",
+ "few": "kwartały",
+ "one": "kwartał",
+ "other": "kwartału",
+ },
+ "year": {
+ "many": "lat",
+ "few": "lata",
+ "one": "rok",
+ "other": "roku",
+ },
+};
+
+const rtf = new Intl.RelativeTimeFormat("pl-PL", {
+ "style": "long",
+});
+
+assert.sameValue(typeof rtf.formatToParts, "function", "formatToParts should be supported");
+
+for (const [unitArgument, expected] of Object.entries(units)) {
+ verifyFormatParts(rtf.formatToParts(1000, unitArgument), [
+ { "type": "literal", "value": "za " },
+ { "type": "integer", "value": "1000", "unit": unitArgument },
+ { "type": "literal", "value": ` ${expected.many}` },
+ ], `formatToParts(1000, ${unitArgument})`);
+
+ verifyFormatParts(rtf.formatToParts(10, unitArgument), [
+ { "type": "literal", "value": "za " },
+ { "type": "integer", "value": "10", "unit": unitArgument },
+ { "type": "literal", "value": ` ${expected.many}` },
+ ], `formatToParts(10, ${unitArgument})`);
+
+ verifyFormatParts(rtf.formatToParts(2, unitArgument), [
+ { "type": "literal", "value": "za " },
+ { "type": "integer", "value": "2", "unit": unitArgument },
+ { "type": "literal", "value": ` ${expected.few}` },
+ ], `formatToParts(2, ${unitArgument})`);
+
+ verifyFormatParts(rtf.formatToParts(1, unitArgument), [
+ { "type": "literal", "value": "za " },
+ { "type": "integer", "value": "1", "unit": unitArgument },
+ { "type": "literal", "value": ` ${expected.one}` },
+ ], `formatToParts(1, ${unitArgument})`);
+
+ verifyFormatParts(rtf.formatToParts(0, unitArgument), [
+ { "type": "literal", "value": "za " },
+ { "type": "integer", "value": "0", "unit": unitArgument },
+ { "type": "literal", "value": ` ${expected.many}` },
+ ], `formatToParts(0, ${unitArgument})`);
+
+ verifyFormatParts(rtf.formatToParts(-0, unitArgument), [
+ { "type": "integer", "value": "0", "unit": unitArgument },
+ { "type": "literal", "value": ` ${expected.many} temu` },
+ ], `formatToParts(-0, ${unitArgument})`);
+
+ verifyFormatParts(rtf.formatToParts(-1, unitArgument), [
+ { "type": "integer", "value": "1", "unit": unitArgument },
+ { "type": "literal", "value": ` ${expected.one} temu` },
+ ], `formatToParts(-1, ${unitArgument})`);
+
+ verifyFormatParts(rtf.formatToParts(-2, unitArgument), [
+ { "type": "integer", "value": "2", "unit": unitArgument },
+ { "type": "literal", "value": ` ${expected.few} temu` },
+ ], `formatToParts(-2, ${unitArgument})`);
+
+ verifyFormatParts(rtf.formatToParts(-10, unitArgument), [
+ { "type": "integer", "value": "10", "unit": unitArgument },
+ { "type": "literal", "value": ` ${expected.many} temu` },
+ ], `formatToParts(-10, ${unitArgument})`);
+
+ verifyFormatParts(rtf.formatToParts(-1000, unitArgument), [
+ { "type": "integer", "value": "1000", "unit": unitArgument },
+ { "type": "literal", "value": ` ${expected.many} temu` },
+ ], `formatToParts(-1000, ${unitArgument})`);
+
+ verifyFormatParts(rtf.formatToParts(123456.78, unitArgument), [
+ { "type": "literal", "value": "za " },
+ { "type": "integer", "value": "123", "unit": unitArgument },
+ { "type": "group", "value": "\u00a0", "unit": unitArgument },
+ { "type": "integer", "value": "456", "unit": unitArgument },
+ { "type": "decimal", "value": ",", "unit": unitArgument },
+ { "type": "fraction", "value": "78", "unit": unitArgument },
+ { "type": "literal", "value": ` ${expected.other}` },
+ ], `formatToParts(123456.78, ${unitArgument})`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/pl-pl-style-narrow.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/pl-pl-style-narrow.js
new file mode 100644
index 0000000000..f8af023ca2
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/pl-pl-style-narrow.js
@@ -0,0 +1,130 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.prototype.format
+description: Checks the behavior of Intl.RelativeTimeFormat.prototype.format() in Polish.
+features: [Intl.RelativeTimeFormat]
+locale: [pl-PL]
+---*/
+
+function verifyFormatParts(actual, expected, message) {
+ assert.sameValue(actual.length, expected.length, `${message}: length`);
+
+ for (let i = 0; i < actual.length; ++i) {
+ assert.sameValue(actual[i].type, expected[i].type, `${message}: parts[${i}].type`);
+ assert.sameValue(actual[i].value, expected[i].value, `${message}: parts[${i}].value`);
+ assert.sameValue(actual[i].unit, expected[i].unit, `${message}: parts[${i}].unit`);
+ }
+}
+
+function always(s) {
+ return {
+ "many": s,
+ "few": s,
+ "one": s,
+ "other": s,
+ }
+}
+
+// https://www.unicode.org/cldr/charts/33/summary/pl.html#1419
+const units = {
+ "second": always("s"),
+ "minute": always("min"),
+ "hour": always("g."),
+ "day": {
+ "many": "dni",
+ "few": "dni",
+ "one": "dzień",
+ "other": "dnia",
+ },
+ "week": {
+ "many": "tyg.",
+ "few": "tyg.",
+ "one": "tydz.",
+ "other": "tyg.",
+ },
+ "month": always("mies."),
+ "quarter": always("kw."),
+ "year": {
+ "many": "lat",
+ "few": "lata",
+ "one": "rok",
+ "other": "roku",
+ },
+};
+
+const rtf = new Intl.RelativeTimeFormat("pl-PL", {
+ "style": "narrow",
+});
+
+assert.sameValue(typeof rtf.formatToParts, "function", "formatToParts should be supported");
+
+for (const [unitArgument, expected] of Object.entries(units)) {
+ verifyFormatParts(rtf.formatToParts(1000, unitArgument), [
+ { "type": "literal", "value": "za " },
+ { "type": "integer", "value": "1000", "unit": unitArgument },
+ { "type": "literal", "value": ` ${expected.many}` },
+ ], `formatToParts(1000, ${unitArgument})`);
+
+ verifyFormatParts(rtf.formatToParts(10, unitArgument), [
+ { "type": "literal", "value": "za " },
+ { "type": "integer", "value": "10", "unit": unitArgument },
+ { "type": "literal", "value": ` ${expected.many}` },
+ ], `formatToParts(10, ${unitArgument})`);
+
+ verifyFormatParts(rtf.formatToParts(2, unitArgument), [
+ { "type": "literal", "value": "za " },
+ { "type": "integer", "value": "2", "unit": unitArgument },
+ { "type": "literal", "value": ` ${expected.few}` },
+ ], `formatToParts(2, ${unitArgument})`);
+
+ verifyFormatParts(rtf.formatToParts(1, unitArgument), [
+ { "type": "literal", "value": "za " },
+ { "type": "integer", "value": "1", "unit": unitArgument },
+ { "type": "literal", "value": ` ${expected.one}` },
+ ], `formatToParts(1, ${unitArgument})`);
+
+ verifyFormatParts(rtf.formatToParts(0, unitArgument), [
+ { "type": "literal", "value": "za " },
+ { "type": "integer", "value": "0", "unit": unitArgument },
+ { "type": "literal", "value": ` ${expected.many}` },
+ ], `formatToParts(0, ${unitArgument})`);
+
+ verifyFormatParts(rtf.formatToParts(-0, unitArgument), [
+ { "type": "integer", "value": "0", "unit": unitArgument },
+ { "type": "literal", "value": ` ${expected.many} temu` },
+ ], `formatToParts(-0, ${unitArgument})`);
+
+ verifyFormatParts(rtf.formatToParts(-1, unitArgument), [
+ { "type": "integer", "value": "1", "unit": unitArgument },
+ { "type": "literal", "value": ` ${expected.one} temu` },
+ ], `formatToParts(-1, ${unitArgument})`);
+
+ verifyFormatParts(rtf.formatToParts(-2, unitArgument), [
+ { "type": "integer", "value": "2", "unit": unitArgument },
+ { "type": "literal", "value": ` ${expected.few} temu` },
+ ], `formatToParts(-2, ${unitArgument})`);
+
+ verifyFormatParts(rtf.formatToParts(-10, unitArgument), [
+ { "type": "integer", "value": "10", "unit": unitArgument },
+ { "type": "literal", "value": ` ${expected.many} temu` },
+ ], `formatToParts(-10, ${unitArgument})`);
+
+ verifyFormatParts(rtf.formatToParts(-1000, unitArgument), [
+ { "type": "integer", "value": "1000", "unit": unitArgument },
+ { "type": "literal", "value": ` ${expected.many} temu` },
+ ], `formatToParts(-1000, ${unitArgument})`);
+
+ verifyFormatParts(rtf.formatToParts(123456.78, unitArgument), [
+ { "type": "literal", "value": "za " },
+ { "type": "integer", "value": "123", "unit": unitArgument },
+ { "type": "group", "value": "\u00a0", "unit": unitArgument },
+ { "type": "integer", "value": "456", "unit": unitArgument },
+ { "type": "decimal", "value": ",", "unit": unitArgument },
+ { "type": "fraction", "value": "78", "unit": unitArgument },
+ { "type": "literal", "value": ` ${expected.other}` },
+ ], `formatToParts(123456.78, ${unitArgument})`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/pl-pl-style-short.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/pl-pl-style-short.js
new file mode 100644
index 0000000000..97734b1365
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/pl-pl-style-short.js
@@ -0,0 +1,130 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.prototype.format
+description: Checks the behavior of Intl.RelativeTimeFormat.prototype.format() in Polish.
+features: [Intl.RelativeTimeFormat]
+locale: [pl-PL]
+---*/
+
+function verifyFormatParts(actual, expected, message) {
+ assert.sameValue(actual.length, expected.length, `${message}: length`);
+
+ for (let i = 0; i < actual.length; ++i) {
+ assert.sameValue(actual[i].type, expected[i].type, `${message}: parts[${i}].type`);
+ assert.sameValue(actual[i].value, expected[i].value, `${message}: parts[${i}].value`);
+ assert.sameValue(actual[i].unit, expected[i].unit, `${message}: parts[${i}].unit`);
+ }
+}
+
+function always(s) {
+ return {
+ "many": s,
+ "few": s,
+ "one": s,
+ "other": s,
+ }
+}
+
+// https://www.unicode.org/cldr/charts/33/summary/pl.html#1419
+const units = {
+ "second": always("sek."),
+ "minute": always("min"),
+ "hour": always("godz."),
+ "day": {
+ "many": "dni",
+ "few": "dni",
+ "one": "dzień",
+ "other": "dnia",
+ },
+ "week": {
+ "many": "tyg.",
+ "few": "tyg.",
+ "one": "tydz.",
+ "other": "tyg.",
+ },
+ "month": always("mies."),
+ "quarter": always("kw."),
+ "year": {
+ "many": "lat",
+ "few": "lata",
+ "one": "rok",
+ "other": "roku",
+ },
+};
+
+const rtf = new Intl.RelativeTimeFormat("pl-PL", {
+ "style": "short",
+});
+
+assert.sameValue(typeof rtf.formatToParts, "function", "formatToParts should be supported");
+
+for (const [unitArgument, expected] of Object.entries(units)) {
+ verifyFormatParts(rtf.formatToParts(1000, unitArgument), [
+ { "type": "literal", "value": "za " },
+ { "type": "integer", "value": "1000", "unit": unitArgument },
+ { "type": "literal", "value": ` ${expected.many}` },
+ ], `formatToParts(1000, ${unitArgument})`);
+
+ verifyFormatParts(rtf.formatToParts(10, unitArgument), [
+ { "type": "literal", "value": "za " },
+ { "type": "integer", "value": "10", "unit": unitArgument },
+ { "type": "literal", "value": ` ${expected.many}` },
+ ], `formatToParts(10, ${unitArgument})`);
+
+ verifyFormatParts(rtf.formatToParts(2, unitArgument), [
+ { "type": "literal", "value": "za " },
+ { "type": "integer", "value": "2", "unit": unitArgument },
+ { "type": "literal", "value": ` ${expected.few}` },
+ ], `formatToParts(2, ${unitArgument})`);
+
+ verifyFormatParts(rtf.formatToParts(1, unitArgument), [
+ { "type": "literal", "value": "za " },
+ { "type": "integer", "value": "1", "unit": unitArgument },
+ { "type": "literal", "value": ` ${expected.one}` },
+ ], `formatToParts(1, ${unitArgument})`);
+
+ verifyFormatParts(rtf.formatToParts(0, unitArgument), [
+ { "type": "literal", "value": "za " },
+ { "type": "integer", "value": "0", "unit": unitArgument },
+ { "type": "literal", "value": ` ${expected.many}` },
+ ], `formatToParts(0, ${unitArgument})`);
+
+ verifyFormatParts(rtf.formatToParts(-0, unitArgument), [
+ { "type": "integer", "value": "0", "unit": unitArgument },
+ { "type": "literal", "value": ` ${expected.many} temu` },
+ ], `formatToParts(-0, ${unitArgument})`);
+
+ verifyFormatParts(rtf.formatToParts(-1, unitArgument), [
+ { "type": "integer", "value": "1", "unit": unitArgument },
+ { "type": "literal", "value": ` ${expected.one} temu` },
+ ], `formatToParts(-1, ${unitArgument})`);
+
+ verifyFormatParts(rtf.formatToParts(-2, unitArgument), [
+ { "type": "integer", "value": "2", "unit": unitArgument },
+ { "type": "literal", "value": ` ${expected.few} temu` },
+ ], `formatToParts(-2, ${unitArgument})`);
+
+ verifyFormatParts(rtf.formatToParts(-10, unitArgument), [
+ { "type": "integer", "value": "10", "unit": unitArgument },
+ { "type": "literal", "value": ` ${expected.many} temu` },
+ ], `formatToParts(-10, ${unitArgument})`);
+
+ verifyFormatParts(rtf.formatToParts(-1000, unitArgument), [
+ { "type": "integer", "value": "1000", "unit": unitArgument },
+ { "type": "literal", "value": ` ${expected.many} temu` },
+ ], `formatToParts(-1000, ${unitArgument})`);
+
+ verifyFormatParts(rtf.formatToParts(123456.78, unitArgument), [
+ { "type": "literal", "value": "za " },
+ { "type": "integer", "value": "123", "unit": unitArgument },
+ { "type": "group", "value": "\u00a0", "unit": unitArgument },
+ { "type": "integer", "value": "456", "unit": unitArgument },
+ { "type": "decimal", "value": ",", "unit": unitArgument },
+ { "type": "fraction", "value": "78", "unit": unitArgument },
+ { "type": "literal", "value": ` ${expected.other}` },
+ ], `formatToParts(123456.78, ${unitArgument})`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/prop-desc.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/prop-desc.js
new file mode 100644
index 0000000000..257c9ea533
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/prop-desc.js
@@ -0,0 +1,30 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.prototype.formatToParts
+description: Checks the "formatToParts" property of the RelativeTimeFormat prototype object.
+info: |
+ Intl.RelativeTimeFormat.prototype.formatToParts ()
+
+ 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 2019 Language Specification, 10th edition, clause 17, or successor.
+
+ 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]
+features: [Intl.RelativeTimeFormat]
+---*/
+
+assert.sameValue(
+ typeof Intl.RelativeTimeFormat.prototype.formatToParts,
+ "function",
+ "typeof Intl.RelativeTimeFormat.prototype.formatToParts is function"
+);
+
+verifyProperty(Intl.RelativeTimeFormat.prototype, "formatToParts", {
+ writable: true,
+ enumerable: false,
+ configurable: true,
+});
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/result-type.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/result-type.js
new file mode 100644
index 0000000000..127642a5ef
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/result-type.js
@@ -0,0 +1,84 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.prototype.formatToParts
+description: Checks the handling of plural unit arguments to Intl.RelativeTimeFormat.prototype.formatToParts().
+info: |
+ FormatRelativeTimeToParts ( relativeTimeFormat, value, unit )
+
+ 3. Let n be 0.
+ 4. For each part in parts, do:
+ a. Let O be ObjectCreate(%ObjectPrototype%).
+ b. Perform ! CreateDataPropertyOrThrow(O, "type", part.[[Type]]).
+ c. Perform ! CreateDataPropertyOrThrow(O, "value", part.[[Value]]).
+ d. If part has a [[Unit]] field,
+ i. Perform ! CreateDataPropertyOrThrow(O, "unit", part.[[Unit]]).
+ e. Perform ! CreateDataPropertyOrThrow(result, ! ToString(n), O).
+ f. Increment n by 1.
+
+features: [Intl.RelativeTimeFormat]
+includes: [propertyHelper.js]
+---*/
+
+const rtf = new Intl.RelativeTimeFormat("en-US");
+
+assert.sameValue(typeof rtf.formatToParts, "function", "formatToParts should be supported");
+
+const parts = rtf.formatToParts(3, "second");
+
+assert.sameValue(Object.getPrototypeOf(parts), Array.prototype, "parts: prototype");
+assert.sameValue(Array.isArray(parts), true, "parts: isArray");
+assert.sameValue(parts.length, 3, "parts: length");
+
+assert.sameValue(Object.getPrototypeOf(parts[0]), Object.prototype, "parts[0]: prototype");
+verifyProperty(parts[0], "type", {
+ value: "literal",
+ writable: true,
+ enumerable: true,
+ configurable: true,
+});
+verifyProperty(parts[0], "value", {
+ value: "in ",
+ writable: true,
+ enumerable: true,
+ configurable: true,
+});
+
+
+assert.sameValue(Object.getPrototypeOf(parts[1]), Object.prototype, "parts[1]: prototype");
+verifyProperty(parts[1], "type", {
+ value: "integer",
+ writable: true,
+ enumerable: true,
+ configurable: true,
+});
+verifyProperty(parts[1], "value", {
+ value: "3",
+ writable: true,
+ enumerable: true,
+ configurable: true,
+});
+verifyProperty(parts[1], "unit", {
+ value: "second",
+ writable: true,
+ enumerable: true,
+ configurable: true,
+});
+
+
+assert.sameValue(Object.getPrototypeOf(parts[2]), Object.prototype, "parts[2]: prototype");
+verifyProperty(parts[2], "type", {
+ value: "literal",
+ writable: true,
+ enumerable: true,
+ configurable: true,
+});
+verifyProperty(parts[2], "value", {
+ value: " seconds",
+ writable: true,
+ enumerable: true,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/shell.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/shell.js
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/unit-invalid.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/unit-invalid.js
new file mode 100644
index 0000000000..94e4355e09
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/unit-invalid.js
@@ -0,0 +1,55 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.prototype.formatToParts
+description: Checks the handling of invalid unit arguments to Intl.RelativeTimeFormat.prototype.formatToParts().
+info: |
+ SingularRelativeTimeUnit ( unit )
+
+ 10. If unit is not one of "second", "minute", "hour", "day", "week", "month", "quarter", "year", throw a RangeError exception.
+
+features: [Intl.RelativeTimeFormat]
+---*/
+
+const rtf = new Intl.RelativeTimeFormat("en-US");
+
+assert.sameValue(typeof rtf.formatToParts, "function");
+
+const values = [
+ undefined,
+ null,
+ true,
+ 1,
+ 0.1,
+ NaN,
+ {},
+ "",
+ "SECOND",
+ "MINUTE",
+ "HOUR",
+ "DAY",
+ "WEEK",
+ "MONTH",
+ "QUARTER",
+ "YEAR",
+ "decade",
+ "decades",
+ "century",
+ "centuries",
+ "millisecond",
+ "milliseconds",
+ "microsecond",
+ "microseconds",
+ "nanosecond",
+ "nanoseconds",
+];
+
+for (const value of values) {
+ assert.throws(RangeError, () => rtf.formatToParts(0, value), String(value));
+}
+
+const symbol = Symbol();
+assert.throws(TypeError, () => rtf.formatToParts(0, symbol), "symbol");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/unit-plural.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/unit-plural.js
new file mode 100644
index 0000000000..210ce7c8b4
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/unit-plural.js
@@ -0,0 +1,54 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.prototype.formatToParts
+description: Checks the handling of plural unit arguments to Intl.RelativeTimeFormat.prototype.formatToParts().
+info: |
+ SingularRelativeTimeUnit ( unit )
+
+ 2. If unit is "seconds", return "second".
+ 3. If unit is "minutes", return "minute".
+ 4. If unit is "hours", return "hour".
+ 5. If unit is "days", return "day".
+ 6. If unit is "weeks", return "week".
+ 7. If unit is "months", return "month".
+ 8. If unit is "quarters", return "quarter".
+ 9. If unit is "years", return "year".
+
+features: [Intl.RelativeTimeFormat]
+---*/
+
+const rtf = new Intl.RelativeTimeFormat("en-US");
+
+assert.sameValue(typeof rtf.formatToParts, "function", "formatToParts should be supported");
+
+const units = [
+ "second",
+ "minute",
+ "hour",
+ "day",
+ "week",
+ "month",
+ "quarter",
+ "year",
+];
+
+for (const unit of units) {
+ const plural = rtf.formatToParts(3, unit + "s");
+ const singular = rtf.formatToParts(3, unit);
+
+ assert.sameValue(plural.length, singular.length,
+ `Should support unit ${unit}s as a synonym for ${unit}: length`);
+
+ for (let i = 0; i < plural.length; ++i) {
+ assert.sameValue(plural[i].type, singular[i].type,
+ `Should support unit ${unit}s as a synonym for ${unit}: [${i}].type`);
+ assert.sameValue(plural[i].value, singular[i].value,
+ `Should support unit ${unit}s as a synonym for ${unit}: [${i}].value`);
+ assert.sameValue(plural[i].unit, singular[i].unit,
+ `Should support unit ${unit}s as a synonym for ${unit}: [${i}].unit`);
+ }
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/value-non-finite.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/value-non-finite.js
new file mode 100644
index 0000000000..f0c888d165
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/value-non-finite.js
@@ -0,0 +1,38 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.prototype.formatToParts
+description: Checks the handling of invalid value arguments to Intl.RelativeTimeFormat.prototype.formatToParts().
+info: |
+ Intl.RelativeTimeFormat.prototype.formatToParts( value, unit )
+
+ 3. Let value be ? ToNumber(value).
+
+ PartitionRelativeTimePattern ( relativeTimeFormat, value, unit )
+
+ 4. If isFinite(value) is false, then throw a RangeError exception.
+
+features: [Intl.RelativeTimeFormat]
+---*/
+
+const rtf = new Intl.RelativeTimeFormat("en-US");
+
+assert.sameValue(typeof rtf.formatToParts, "function", "formatToParts should be supported");
+
+const values = [
+ [undefined, "undefined"],
+ [NaN, "NaN"],
+ [Infinity, "Infinity"],
+ [-Infinity, "-Infinity"],
+ ["string", '"string"'],
+ [{}, "empty object"],
+ [{ toString() { return NaN; }, valueOf: undefined }, "object with toString"],
+ [{ valueOf() { return NaN; }, toString: undefined }, "object with valueOf"],
+];
+
+for (const [value, name] of values) {
+ assert.throws(RangeError, () => rtf.formatToParts(value, "second"), name);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/value-symbol.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/value-symbol.js
new file mode 100644
index 0000000000..6592cf3fa1
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/value-symbol.js
@@ -0,0 +1,22 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.prototype.formatToParts
+description: Checks the handling of invalid value arguments to Intl.RelativeTimeFormat.prototype.formatToParts().
+info: |
+ Intl.RelativeTimeFormat.prototype.formatToParts( value, unit )
+
+ 3. Let value be ? ToNumber(value).
+
+features: [Intl.RelativeTimeFormat]
+---*/
+
+const rtf = new Intl.RelativeTimeFormat("en-US");
+
+assert.sameValue(typeof rtf.formatToParts, "function", "formatToParts should be supported");
+
+const symbol = Symbol();
+assert.throws(TypeError, () => rtf.formatToParts(symbol, "second"));
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/value-tonumber.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/value-tonumber.js
new file mode 100644
index 0000000000..7fc4c733a0
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/formatToParts/value-tonumber.js
@@ -0,0 +1,52 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.prototype.format
+description: Checks the handling of non-number value arguments to Intl.RelativeTimeFormat.prototype.format().
+info: |
+ Intl.RelativeTimeFormat.prototype.format( value, unit )
+
+ 3. Let value be ? ToNumber(value).
+
+features: [Intl.RelativeTimeFormat]
+---*/
+
+const rtf = new Intl.RelativeTimeFormat("en-US");
+
+assert.sameValue(typeof rtf.format, "function", "format should be supported");
+
+const values = [
+ [null, 0],
+
+ [true, 1],
+ [false, 0],
+
+ ["5", 5],
+ ["-5", -5],
+ ["0", 0],
+ ["-0", -0],
+ [" 6 ", 6],
+
+ [{ toString() { return 7; } }, 7, "object with toString"],
+ [{ valueOf() { return 7; } }, 7, "object with valueOf"],
+];
+
+for (const [input, number, name = String(input)] of values) {
+ const actual = rtf.formatToParts(input, "second");
+ const expected = rtf.formatToParts(number, "second");
+
+ assert.sameValue(actual.length, expected.length,
+ `Should treat ${name} as ${number}: length`);
+
+ for (let i = 0; i < actual.length; ++i) {
+ assert.sameValue(actual[i].type, expected[i].type,
+ `Should treat ${name} as ${number}: [${i}].type`);
+ assert.sameValue(actual[i].value, expected[i].value,
+ `Should treat ${name} as ${number}: [${i}].value`);
+ assert.sameValue(actual[i].unit, expected[i].unit,
+ `Should treat ${name} as ${number}: [${i}].unit`);
+ }
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/prop-desc.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/prop-desc.js
new file mode 100644
index 0000000000..c9aa6913c2
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/prop-desc.js
@@ -0,0 +1,24 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.prototype
+description: >
+ Checks the "prototype" property of the RelativeTimeFormat constructor.
+info: |
+ Intl.RelativeTimeFormat.prototype
+
+ The value of Intl.RelativeTimeFormat.prototype is %RelativeTimeFormatPrototype%.
+
+ This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.
+includes: [propertyHelper.js]
+features: [Intl.RelativeTimeFormat]
+---*/
+
+verifyProperty(Intl.RelativeTimeFormat, "prototype", {
+ writable: false,
+ enumerable: false,
+ configurable: false,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/resolvedOptions/branding.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/resolvedOptions/branding.js
new file mode 100644
index 0000000000..ba3ab34bee
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/resolvedOptions/branding.js
@@ -0,0 +1,28 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.prototype.resolvedOptions
+description: Verifies the branding check for the "resolvedOptions" function of the RelativeTimeFormat prototype object.
+info: |
+ Intl.RelativeTimeFormat.prototype.resolvedOptions ()
+
+ 2. If Type(relativeTimeFormat) is not Object or relativeTimeFormat does not have an [[InitializedRelativeTimeFormat]] internal slot whose value is true, throw a TypeError exception.
+features: [Intl.RelativeTimeFormat]
+---*/
+
+const resolvedOptions = Intl.RelativeTimeFormat.prototype.resolvedOptions;
+
+assert.sameValue(typeof resolvedOptions, "function");
+
+assert.throws(TypeError, () => resolvedOptions.call(undefined), "undefined");
+assert.throws(TypeError, () => resolvedOptions.call(null), "null");
+assert.throws(TypeError, () => resolvedOptions.call(true), "true");
+assert.throws(TypeError, () => resolvedOptions.call(""), "empty string");
+assert.throws(TypeError, () => resolvedOptions.call(Symbol()), "symbol");
+assert.throws(TypeError, () => resolvedOptions.call(1), "1");
+assert.throws(TypeError, () => resolvedOptions.call({}), "plain object");
+assert.throws(TypeError, () => resolvedOptions.call(Intl.RelativeTimeFormat), "Intl.RelativeTimeFormat");
+assert.throws(TypeError, () => resolvedOptions.call(Intl.RelativeTimeFormat.prototype), "Intl.RelativeTimeFormat.prototype");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/resolvedOptions/browser.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/resolvedOptions/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/resolvedOptions/browser.js
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/resolvedOptions/caching.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/resolvedOptions/caching.js
new file mode 100644
index 0000000000..c00142c482
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/resolvedOptions/caching.js
@@ -0,0 +1,19 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.prototype.resolvedOptions
+description: Verifies that the return value of Intl.RelativeTimeFormat.prototype.resolvedOptions() is not cached.
+info: |
+ Intl.RelativeTimeFormat.prototype.resolvedOptions ()
+
+ 4. Let options be ! ObjectCreate(%ObjectPrototype%).
+features: [Intl.RelativeTimeFormat]
+---*/
+
+const rtf = new Intl.RelativeTimeFormat("en-us");
+const options1 = rtf.resolvedOptions();
+const options2 = rtf.resolvedOptions();
+assert.notSameValue(options1, options2, "Should create a new object each time.");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/resolvedOptions/length.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/resolvedOptions/length.js
new file mode 100644
index 0000000000..8c49fd2e98
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/resolvedOptions/length.js
@@ -0,0 +1,23 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.prototype.resolvedOptions
+description: Checks the "length" property of Intl.RelativeTimeFormat.prototype.resolvedOptions().
+info: |
+ 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 2019 Language Specification, 10th edition, clause 17, or successor.
+ The RelativeTimeFormat constructor is a standard built-in property of the Intl object.
+ 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]
+features: [Intl.RelativeTimeFormat]
+---*/
+
+verifyProperty(Intl.RelativeTimeFormat.prototype.resolvedOptions, "length", {
+ value: 0,
+ writable: false,
+ enumerable: false,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/resolvedOptions/name.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/resolvedOptions/name.js
new file mode 100644
index 0000000000..2305662ed6
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/resolvedOptions/name.js
@@ -0,0 +1,22 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.prototype.resolvedOptions
+description: Checks the "name" property of Intl.RelativeTimeFormat.prototype.resolvedOptions().
+info: |
+ 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 2019 Language Specification, 10th edition, clause 17, or successor.
+ 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, this value is the name that is given to the function in this specification.
+ 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]
+features: [Intl.RelativeTimeFormat]
+---*/
+
+verifyProperty(Intl.RelativeTimeFormat.prototype.resolvedOptions, "name", {
+ value: "resolvedOptions",
+ writable: false,
+ enumerable: false,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/resolvedOptions/order.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/resolvedOptions/order.js
new file mode 100644
index 0000000000..c0017b721c
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/resolvedOptions/order.js
@@ -0,0 +1,29 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-intl.relativetimeformat.prototype.resolvedoptions
+description: Verifies the property order for the object returned by resolvedOptions().
+features: [Intl.RelativeTimeFormat]
+---*/
+
+const options = new Intl.RelativeTimeFormat().resolvedOptions();
+
+const expected = [
+ "locale",
+ "style",
+ "numeric",
+ "numberingSystem",
+];
+
+const actual = Object.getOwnPropertyNames(options);
+
+// Ensure all expected items are in actual and also allow other properties
+// implemented in new proposals.
+assert(actual.indexOf("locale") > -1, "\"locale\" is present");
+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]), `"${expected[i-1]}" precedes "${expected[i]}"`);
+}
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/resolvedOptions/prop-desc.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/resolvedOptions/prop-desc.js
new file mode 100644
index 0000000000..cdb51d7ddd
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/resolvedOptions/prop-desc.js
@@ -0,0 +1,30 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.prototype.resolvedOptions
+description: Checks the "resolvedOptions" property of the RelativeTimeFormat prototype object.
+info: |
+ Intl.RelativeTimeFormat.prototype.resolvedOptions ()
+
+ 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 2019 Language Specification, 10th edition, clause 17, or successor.
+
+ 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]
+features: [Intl.RelativeTimeFormat]
+---*/
+
+assert.sameValue(
+ typeof Intl.RelativeTimeFormat.prototype.resolvedOptions,
+ "function",
+ "typeof Intl.RelativeTimeFormat.prototype.resolvedOptions is function"
+);
+
+verifyProperty(Intl.RelativeTimeFormat.prototype, "resolvedOptions", {
+ writable: true,
+ enumerable: false,
+ configurable: true,
+});
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/resolvedOptions/shell.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/resolvedOptions/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/resolvedOptions/shell.js
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/resolvedOptions/type.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/resolvedOptions/type.js
new file mode 100644
index 0000000000..4ad150eb48
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/resolvedOptions/type.js
@@ -0,0 +1,42 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.RelativeTimeFormat.prototype.resolvedOptions
+description: Checks the properties of the result of Intl.RelativeTimeFormat.prototype.resolvedOptions().
+info: |
+ Intl.RelativeTimeFormat.prototype.resolvedOptions ()
+
+ 4. Let options be ! ObjectCreate(%ObjectPrototype%).
+ 5. For each row of Table 1, except the header row, do
+ d. Perform ! CreateDataPropertyOrThrow(options, p, v).
+includes: [propertyHelper.js]
+features: [Intl.RelativeTimeFormat]
+---*/
+
+const rtf = new Intl.RelativeTimeFormat("en-us", { "style": "short", "numeric": "auto" });
+const options = rtf.resolvedOptions();
+assert.sameValue(Object.getPrototypeOf(options), Object.prototype, "Prototype");
+
+verifyProperty(options, "locale", {
+ value: "en-US",
+ writable: true,
+ enumerable: true,
+ configurable: true,
+});
+
+verifyProperty(options, "style", {
+ value: "short",
+ writable: true,
+ enumerable: true,
+ configurable: true,
+});
+
+verifyProperty(options, "numeric", {
+ value: "auto",
+ writable: true,
+ enumerable: true,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/shell.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/shell.js
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/toStringTag/browser.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/toStringTag/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/toStringTag/browser.js
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/toStringTag/shell.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/toStringTag/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/toStringTag/shell.js
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/toStringTag/toString.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/toStringTag/toString.js
new file mode 100644
index 0000000000..100584e18c
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/toStringTag/toString.js
@@ -0,0 +1,18 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-intl.RelativeTimeFormat.prototype-@@tostringtag
+description: >
+ Checks Object.prototype.toString with Intl.RelativeTimeFormat objects.
+info: |
+ Intl.RelativeTimeFormat.prototype[ @@toStringTag ]
+
+ The initial value of the @@toStringTag property is the string value "Intl.RelativeTimeFormat".
+features: [Intl.RelativeTimeFormat]
+---*/
+
+assert.sameValue(Object.prototype.toString.call(Intl.RelativeTimeFormat.prototype), "[object Intl.RelativeTimeFormat]");
+assert.sameValue(Object.prototype.toString.call(new Intl.RelativeTimeFormat("en")), "[object Intl.RelativeTimeFormat]");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/toStringTag/toStringTag.js b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/toStringTag/toStringTag.js
new file mode 100644
index 0000000000..80398ba2d2
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/prototype/toStringTag/toStringTag.js
@@ -0,0 +1,25 @@
+// Copyright 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-intl.RelativeTimeFormat.prototype-@@tostringtag
+description: >
+ Checks the @@toStringTag property of the RelativeTimeFormat prototype object.
+info: |
+ Intl.RelativeTimeFormat.prototype[ @@toStringTag ]
+
+ The initial value of the @@toStringTag property is the string value "Intl.RelativeTimeFormat".
+
+ This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.
+includes: [propertyHelper.js]
+features: [Intl.RelativeTimeFormat, Symbol.toStringTag]
+---*/
+
+verifyProperty(Intl.RelativeTimeFormat.prototype, Symbol.toStringTag, {
+ value: "Intl.RelativeTimeFormat",
+ writable: false,
+ enumerable: false,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/intl402/RelativeTimeFormat/shell.js b/js/src/tests/test262/intl402/RelativeTimeFormat/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/intl402/RelativeTimeFormat/shell.js